您的位置:

java实现神经网络bp算法,bp神经网络算法详解

本文目录一览:

如何用70行Java代码实现深度神经网络算法

import java.util.Random;public class BpDeep{

    public double[][] layer;//神经网络各层节点

    public double[][] layerErr;//神经网络各节点误差

    public double[][][] layer_weight;//各层节点权重

    public double[][][] layer_weight_delta;//各层节点权重动量

    public double mobp;//动量系数

    public double rate;//学习系数

    public BpDeep(int[] layernum, double rate, double mobp){

        this.mobp = mobp;

        this.rate = rate;

        layer = new double[layernum.length][];

        layerErr = new double[layernum.length][];

        layer_weight = new double[layernum.length][][];

        layer_weight_delta = new double[layernum.length][][];

        Random random = new Random();

        for(int l=0;llayernum.length;l++){

            layer[l]=new double[layernum[l]];

            layerErr[l]=new double[layernum[l]];

            if(l+1layernum.length){

                layer_weight[l]=new double[layernum[l]+1][layernum[l+1]];

                layer_weight_delta[l]=new double[layernum[l]+1][layernum[l+1]];

                for(int j=0;jlayernum[l]+1;j++)

                    for(int i=0;ilayernum[l+1];i++)

                        layer_weight[l][j][i]=random.nextDouble();//随机初始化权重

            }   

        }

    }

    //逐层向前计算输出

    public double[] computeOut(double[] in){

        for(int l=1;llayer.length;l++){

            for(int j=0;jlayer[l].length;j++){

                double z=layer_weight[l-1][layer[l-1].length][j];

                for(int i=0;ilayer[l-1].length;i++){

                    layer[l-1][i]=l==1?in[i]:layer[l-1][i];

                    z+=layer_weight[l-1][i][j]*layer[l-1][i];

                }

                layer[l][j]=1/(1+Math.exp(-z));

            }

        }

        return layer[layer.length-1];

    }

    //逐层反向计算误差并修改权重

    public void updateWeight(double[] tar){

        int l=layer.length-1;

        for(int j=0;jlayerErr[l].length;j++)

            layerErr[l][j]=layer[l][j]*(1-layer[l][j])*(tar[j]-layer[l][j]);

        while(l--0){

            for(int j=0;jlayerErr[l].length;j++){

                double z = 0.0;

                for(int i=0;ilayerErr[l+1].length;i++){

                    z=z+l0?layerErr[l+1][i]*layer_weight[l][j][i]:0;

                    layer_weight_delta[l][j][i]= mobp*layer_weight_delta[l][j][i]+rate*layerErr[l+1][i]*layer[l][j];//隐含层动量调整

                    layer_weight[l][j][i]+=layer_weight_delta[l][j][i];//隐含层权重调整

                    if(j==layerErr[l].length-1){

                        layer_weight_delta[l][j+1][i]= mobp*layer_weight_delta[l][j+1][i]+rate*layerErr[l+1][i];//截距动量调整

                        layer_weight[l][j+1][i]+=layer_weight_delta[l][j+1][i];//截距权重调整

                    }

                }

                layerErr[l][j]=z*layer[l][j]*(1-layer[l][j]);//记录误差

            }

        }

    }

    public void train(double[] in, double[] tar){

        double[] out = computeOut(in);

        updateWeight(tar);

    }

}

急求BP神经网络算法,用java实现!!!

见附件,一个基本的用java编写的BP网络代码。

BP(Back Propagation)神经网络是86年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input)、隐层(hidden layer)和输出层(output layer)。

BP神经网络的训练集需要大样本吗?一般样本个数为多少?

BP神经网络的训练集需要大样本吗?一般样本个数为多少?

BP神经网络样本数有什么影响

学习神经网络这段时间,有一个疑问,BP神经网络中训练的次数指的网络的迭代次数,如果有a个样本,每个样本训练次数n,则网络一共迭代an次,在na 情况下 , 网络在不停的调整权值,减小误差,跟样本数似乎关系不大。而且,a大了的话训练时间必然会变长。

换一种说法,将你的数据集看成一个固定值, 那么样本集与测试集 也可以按照某种规格确定下来如7:3 所以如何看待 样本集的多少与训练结果呢? 或者说怎么使你的网络更加稳定,更加符合你的所需 。

我尝试从之前的一个例子中看下区别

如何用70行Java代码实现深度神经网络算法

作者其实是实现了一个BP神经网络 ,不多说,看最后的例子

一个运用神经网络的例子

最后我们找个简单例子来看看神经网络神奇的效果。为了方便观察数据分布,我们选用一个二维坐标的数据,下面共有4个数据,方块代表数据的类型为1,三角代表数据的类型为0,可以看到属于方块类型的数据有(1,2)和(2,1),属于三角类型的数据有(1,1),(2,2),现在问题是需要在平面上将4个数据分成1和0两类,并以此来预测新的数据的类型。

图片描述

我们可以运用逻辑回归算法来解决上面的分类问题,但是逻辑回归得到一个线性的直线做为分界线,可以看到上面的红线无论怎么摆放,总是有一个样本被错误地划分到不同类型中,所以对于上面的数据,仅仅一条直线不能很正确地划分他们的分类,如果我们运用神经网络算法,可以得到下图的分类效果,相当于多条直线求并集来划分空间,这样准确性更高。

图片描述

简单粗暴,用作者的代码运行后 训练5000次 。根据训练结果来预测一条新数据的分类(3,1)

预测值 (3,1)的结果跟(1,2)(2,1)属于一类 属于正方形

这时如果我们去掉 2个样本,则样本输入变成如下

//设置样本数据,对应上面的4个二维坐标数据

double[][] data = new double[][]{{1,2},{2,2}};

//设置目标数据,对应4个坐标数据的分类

double[][] target = new double[][]{{1,0},{0,1}};

1

2

3

4

1

2

3

4

则(3,1)结果变成了三角形,

如果你选前两个点 你会发现直接一条中间线就可以区分 这时候的你的结果跟之前4个点时有区别 so 你得增加样本 直到这些样本按照你所想要的方式分类 ,所以样本的多少 重要性体现在,样本得能反映所有的特征值(也就是输入值) ,样本多少或者特征(本例子指点的位置特征)决定的你的网络的训练结果,!!!这是 我们反推出来的结果 。这里距离深度学习好像近了一步。

另外,这个70行代码的神经网络没有保存你训练的网络 ,所以你每次运行都是重新训练的网络。其实,在你训练过后 权值已经确定了下来,我们确定网络也就是根据权值,so只要把训练后的权值保存下来,将需要分类的数据按照这种权值带入网络,即可得到输出值,也就是一旦网络确定, 权值也就确定,一个输入对应一个固定的输出,不会再次改变!个人见解。

最后附上作者的源码,作者的文章见开头链接

下面的实现程序BpDeep.java可以直接拿去使用,

import java.util.Random;

public class BpDeep{

public double[][] layer;//神经网络各层节点

public double[][] layerErr;//神经网络各节点误差

public double[][][] layer_weight;//各层节点权重

public double[][][] layer_weight_delta;//各层节点权重动量

public double mobp;//动量系数

public double rate;//学习系数

public BpDeep(int[] layernum, double rate, double mobp){

this.mobp = mobp;

this.rate = rate;

layer = new double[layernum.length][];

layerErr = new double[layernum.length][];

layer_weight = new double[layernum.length][][];

layer_weight_delta = new double[layernum.length][][];

Random random = new Random();

for(int l=0;llayernum.length;l++){

layer[l]=new double[layernum[l]];

layerErr[l]=new double[layernum[l]];

if(l+1layernum.length){

layer_weight[l]=new double[layernum[l]+1][layernum[l+1]];

layer_weight_delta[l]=new double[layernum[l]+1][layernum[l+1]];

for(int j=0;jlayernum[l]+1;j++)

for(int i=0;ilayernum[l+1];i++)

layer_weight[l][j][i]=random.nextDouble();//随机初始化权重

}

}

}

//逐层向前计算输出

public double[] computeOut(double[] in){

for(int l=1;llayer.length;l++){

for(int j=0;jlayer[l].length;j++){

double z=layer_weight[l-1][layer[l-1].length][j];

for(int i=0;ilayer[l-1].length;i++){

layer[l-1][i]=l==1?in[i]:layer[l-1][i];

z+=layer_weight[l-1][i][j]*layer[l-1][i];

}

layer[l][j]=1/(1+Math.exp(-z));

}

}

return layer[layer.length-1];

}

//逐层反向计算误差并修改权重

public void updateWeight(double[] tar){

int l=layer.length-1;

for(int j=0;jlayerErr[l].length;j++)

layerErr[l][j]=layer[l][j]*(1-layer[l][j])*(tar[j]-layer[l][j]);

while(l--0){

for(int j=0;jlayerErr[l].length;j++){

double z = 0.0;

for(int i=0;ilayerErr[l+1].length;i++){

z=z+l0?layerErr[l+1][i]*layer_weight[l][j][i]:0;

layer_weight_delta[l][j][i]= mobp*layer_weight_delta[l][j][i]+rate*layerErr[l+1][i]*layer[l][j];//隐含层动量调整

layer_weight[l][j][i]+=layer_weight_delta[l][j][i];//隐含层权重调整

if(j==layerErr[l].length-1){

layer_weight_delta[l][j+1][i]= mobp*layer_weight_delta[l][j+1][i]+rate*layerErr[l+1][i];//截距动量调整

layer_weight[l][j+1][i]+=layer_weight_delta[l][j+1][i];//截距权重调整

}

}

layerErr[l][j]=z*layer[l][j]*(1-layer[l][j]);//记录误差

}

}

}

public void train(double[] in, double[] tar){

double[] out = computeOut(in);

updateWeight(tar);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

下面是这个测试程序BpDeepTest.java的源码:

import java.util.Arrays;

public class BpDeepTest{

public static void main(String[] args){

//初始化神经网络的基本配置

//第一个参数是一个整型数组,表示神经网络的层数和每层节点数,比如{3,10,10,10,10,2}表示输入层是3个节点,输出层是2个节点,中间有4层隐含层,每层10个节点

//第二个参数是学习步长,第三个参数是动量系数

BpDeep bp = new BpDeep(new int[]{2,10,2}, 0.15, 0.8);

//设置样本数据,对应上面的4个二维坐标数据

double[][] data = new double[][]{{1,2},{2,2},{1,1},{2,1}};

//设置目标数据,对应4个坐标数据的分类

double[][] target = new double[][]{{1,0},{0,1},{0,1},{1,0}};

//迭代训练5000次

for(int n=0;n5000;n++)

for(int i=0;idata.length;i++)

bp.train(data[i], target[i]);

//根据训练结果来检验样本数据

for(int j=0;jdata.length;j++){

double[] result = bp.computeOut(data[j]);

System.out.println(Arrays.toString(data[j])+":"+Arrays.toString(result));

}

//根据训练结果来预测一条新数据的分类

double[] x = new double[]{3,1};

double[] result = bp.computeOut(x);

System.out.println(Arrays.toString(x)+":"+Arrays.toString(result));

}

}