您的位置:首页 > 理论基础 > 计算机网络

简单BP神经网络的Java实现

2017-03-24 10:56 316 查看
初学神经网络,利用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<
4000
;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));
}
}
}
/**
* 根据训练结果输出预测值
* @param test 测试集
* @param test_y 测试结果
*/
public void predict(double[][] test,double[][] test_y){
double[][] L1 = sigmoid(matrixmultiple(test, v));
//输出层输出
double[][] L2 = sigmoid( matrixmultiple(L1, w));
System.out.println("预测值:");
for(int j=0;j<L2.length;j++){
for(int k=0;k<L2[0].length;k++)
System.out.print(L2[j][k]+" ");
System.out.println();
}
System.out.println("实际值:");
for(int j=0;j<L2.length;j++){
for(int k=0;k<L2[0].length;k++)
System.out.print(test_y[j][k] +" ");
System.out.println();
}
}

public static void main(String[] args) {
double[][] x = {
{1,0,0,0,0,0},
{1,0,0,0,0,1},
{1,0,0,0,1,0},
{1,0,0,1,0,0},
{1,0,1,0,0,0},
{1,1,0,0,0,0},
{1,0,0,0,1,1},
{1,0,0,1,1,0},
{1,0,1,1,0,0},
{1,1,1,0,0,0},
{1,0,0,1,1,1},
{1,0,1,1,1,0},
{1,1,1,1,0,0},
{1,0,1,1,1,1},
{1,1,1,1,1,0}
};
double[][] y = {
{0,0,0,1},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{1,0,0,0},
{1,0,0,0},
{1,0,0,0},
{0,0,1,1},
{0,0,1,1},
};
int input = 6;
int hidden = 50;
int output = 4;
double[][] test = {
{1,1,0,0,0,0},
{1,0,0,0,0,1},
{1,1,1,0,0,0},
{1,1,1,1,1,0}
};
double[][] test_y = {
{0,0,1,0},
{0,0,1,0},
{0,1,0,0},
{0,0,1,1}
};
double lr = 0.11;
//初始化初值
BP bp = new BP(x, y, input, hidden, output, lr);
//训练20000次
bp.train(20000);
//输出预测
bp.predict(test,test_y);
}
}
2、矩阵的一些基本操作
public abstract class Matrix {
/**
* 矩阵相乘
* @param a
* @param b
* @return
*/
public double[][] matrixmultiple(int[][] a,double[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(a_col!=b_row){
System.out.println("检查矩阵是否能相乘");
return null;
}
double[][] result = new double[a_row][b_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<b_col;j++){
double temp = 0;
for(int k=0;k<a_col;k++){
temp+= a[i][k]*b[k][j];
}
result[i][j] = temp;
}
}
return result;
}
/**
* 矩阵相乘
* @param a
* @param b
* @return
*/
public double[][] matrixmultiple(double[][] a,int[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(a_col!=b_row){
System.out.println("检查矩阵是否能相乘");
return null;
}

double[][] result = new double[a_row][b_col];

for(int i=0;i<a_row;i++){
for(int j=0;j<b_col;j++){
double temp = 0;
for(int k=0;k<a_col;k++){
temp+= a[i][k]*b[k][j];
}
result[i][j] = temp;
}
}
return result;
}
/**
* 矩阵相乘
* @param a
* @param b
* @return
*/
public double[][] matrixmultiple(double[][] a,double[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(a_col!=b_row){
System.out.println("检查矩阵是否能相乘");
return null;
}
double[][] result = new double[a_row][b_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<b_col;j++){
double temp = 0;
for(int k=0;k<a_col;k++){
temp+= a[i][k]*b[k][j];
}
result[i][j] = temp;
}
}
return result;
}
/**
* 矩阵和一个数相乘
* @param a
* @param b
* @return
*/
public double[][] matrixmultiple(double[][] a,double b){
int a_row = a.length,a_col = a[0].length;
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]*b;
}
}
return result;
}
/**
* 矩阵和一个数相乘
* @param b
* @param a
* @return
*/
public double[][] matrixmultiple(double b,double[][] a){
int a_row = a.length,a_col = a[0].length;
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]*b;
}
}
return result;
}
/**
* 矩阵按位相乘
* @param a
* @param b
* @return
*/
public double[][] matrix_mu(double[][] a,double[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(a_row!=b_row||a_col!=b_col){
System.out.println("检查矩阵是否能*相乘");
return null;
}
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]*b[i][j];
}
}
return result;
}
/**
* 矩阵按位相加
* @param a
* @param b
* @return
*/
public double[][] matrixadd(double[][] a,double[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(!(a_row==b_row&&a_col==b_col)){
System.out.println("检查两个矩阵是否可以相加");
return null;
}
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]+b[i][j];
}
}
return result;
}
/**
* 矩阵按位相减
* @param a
* @param b
* @return
*/
public double[][] matrixsub(double[][] a,double[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(!(a_row==b_row&&a_col==b_col)){
System.out.println("检查两个矩阵是否可以相减");
return null;
}
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]-b[i][j];
}
}
return result;
}
/**
* 矩阵按位相减
* @param a
* @param b
* @return
*/
public double[][] matrixsub(double[][] a,int[][] b){
int a_row = a.length,a_col = a[0].length;
int b_row = b.length,b_col = b[0].length;
if(!(a_row==b_row&&a_col==b_col)){
System.out.println("检查两个矩阵是否可以相减");
return null;
}
double[][] result = new double[a_row][a_col];
for(int i=0;i<a_row;i++){
for(int j=0;j<a_col;j++){
result[i][j] = a[i][j]-b[i][j];
}
}
return result;
}
/**
* 矩阵转置
* @param a
* @return
*/
public double[][] T(double[][] a){
int row = a.length,col = a[0].length;
double[][] result = new double[col][row];
for(int i=0;i<col;i++){
for(int j=0;j<row;j++){
result[i][j] = a[j][i];
}
}
return result;
}
/**
* 矩阵转置
* @param a
* @return
*/
public int[][] T(int[][] a){
int row = a.length,col = a[0].length;
int[][] result = new int[col][row];
for(int i=0;i<col;i++){
for(int j=0;j<row;j++){
result[i][j] = a[j][i];
}
}
return result;
}
/**
* sigmoid激活函数
* @param x
* @return
*/
public double sigmoid(double x){
return 1d/(1d+Math.exp(-x));
}
/**
* sigmoid求导
* @param x
* @return
*/
public double dsigmoid(double x){
return x*(1d-x);
}
/**
* 对一个矩阵求sigmoid
* @param x
* @return
*/
public double[][] sigmoid(double[][] x){
int row = x.length,col = x[0].length;
double[][] result = new double[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
result[i][j] = sigmoid(x[i][j]);
}
}
return result;
}
/**
* 对于一个矩阵求sigmoid倒数
* @param x
* @return
*/
public double[][] dsigmoid(double[][] x){
int row = x.length,col = x[0].length;
double[][] result = new double[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
result[i][j] = dsigmoid(x[i][j]);
}
}
return result;
}
}
3、运行截图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  神经网络 java