之前尝试过自己写一个BP神经网络实现,用来进行中国象棋的局面评估。遇到一些问题,最后才发现网络权重初始化不当——每个权重的初始化值应该是在区间[-1,1]中取,而不是在[0,1]中取!原先写的那个实现里只能有一个隐含层,这里这个新的实现中,可以有多个隐含层。神经元的激励函数取的是sigmoid函数。代码如下
public class BPANN{
/*
* *******************以下是神经网络的参数****************************
*/
//输入数据的维度(每个数据都是0~1的值)
private int inputDim;
//输出数据的维度(每个数据都是0~1的值)
private int outputDim;
//神经网络的层数(输入数据->第1隐含层->...->输出层神经元->输出数据)
//这里的每一层对应一列神经元(每个神经元即加权之后进行sigmoid这样一
//个处理过程)每一列神经元对应有若干个权重,第1隐含层对应的权重个数是
//inputDim*n1,这里n1是第1隐含层中的神经元的个数。
private int numLayers;
//每一层各有多少个神经元
//assert numNeuronsForEachLayer.length==numLayers
//assert numNeuronsForEachLayer[numNeuronsForEachLayer.length-1]=outputDim
private int [] numNeuronsForEachLayer;
/*
* **********************以下是神经网络的状态***************************
*/
//设共有m层神经元,第i层神经元有n[i]个,则每一个神经元有n[i-1]+1个权重,其中多出来的
//那个权重是用来乘以offset(一般都是1)的
//weights.length=numLayers
//weights[i].length=numNeuronsForEachLayer[i]
//weights[i][j].length=numNeuronsForEachLayer[i-1]+1
private double [][][] weights;
/**
* 根据参数构建
* @param inputDimension
* @param outputDimension
* @param numOfLayers
* @param numOfNeuronsForEachLayer
*/
public BPANN(int inputDimension, int outputDimension, int numOfLayers, int[] numOfNeuronsForEachLayer){
construct(inputDimension, outputDimension, numOfLayers, numOfNeuronsForEachLayer);
}
/**
* 根据参数构建
* @param inputDimension
* @param numOfNeuronsForEachLayer
*/
public BPANN(int inputDimension, int[] numOfNeuronsForEachLayer){
assert numOfNeuronsForEachLayer.length>0;
construct(inputDimension, numOfNeuronsForEachLayer[numOfNeuronsForEachLayer.length-1], numOfNeuronsForEachLayer.length, numOfNeuronsForEachLayer);
}
private void construct(int inputDimension, int outputDimension, in