初学神经网络,利用Java实现简单的BP,现记录下来。
1、BP.java文件,具体功能见代码注释
/**
* 简单BP网络的Java实现
* 3层网络
* 激活函数sigmoid
* 注意:
* 1、输入层的神经元个数和训练集的列数一致,训练集的每一行为一个特征向量。
* 2、输出层神经元的个数和标签的列数一致,标签的每一列相当于一个特征向量训练的结果
* @author yuliyan
*/
public class BP extends Matrix{
public double[][] x;//训练集
public double[][] y;//标签
public double[][] v;//输入层到隐藏层的权值
public double[][] w;//隐藏层到输出层的权值
public double lr;//学习率
public BP(double[][] x,double[][] y,int input,int hidden,int output,double lr) {
this.x= x;
this.y=y;
this.v= weigth(input, hidden);
this.w= weigth(hidden, output);
this.lr=lr;
}
/**
* 初始化权值
* @param row
* @param col
* @return
*/
public static double[][] weigth(int row,int col){
double[][] result = new double[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
result[i][j] = Math.random()*2-1;
}
}
return result;
}
/**
* 训练一次
*/
public void train(){
//隐藏层输出
double[][] L1 = sigmoid(matrixmultiple(x, v));//4*5
//输出层输出
double[][] L2 = sigmoid(matrixmultiple(L1, w));//4*3
//隐藏层到输出层权值调整
double[][] delta_2 = matrix_mu(matrixsub(y,L2),dsigmoid(L2));//(y-L2)*dsigmoid(L2) 4*3
w= matrixadd(w, matrixmultiple(matrixmultiple(T(L1), delta_2), lr));
//输入层到隐藏层权值调整
double[][] delta_1 = matrix_mu(matrixmultiple(delta_2,T(w)),dsigmoid(L1));
v = matrixadd(v, matrixmultiple(matrixmultiple(T(x), delta_1), lr));
}
/**
* 多次迭代训练
* @param range 迭代次数
*/
public void train(int range){
for(int i=0;i<range;i++){
train();
if(i%100==0){
//隐藏层输出
double[][] L1 = sigmoid(matrixmultiple(x, v));
//输出层输出
double[][] L2 = sigmoid( matrixmultiple(L1, w));
double temp = 0;
for(int j=0;j<y.length;j++){
for(int k=0;k<y[0].length;k++)
temp+=Math.abs(y[j][k]-L2[j][k]);
}
//输出误差
System.out.println("error:"+temp/(y.length*y[0].length