从一个简单的例子开始
Predict,从sample中分离出来的子项目,使用tanh函数作为激活函数(默认,可以选择sigmoid)
下图为encog支持的各种激活函数(好吧,高斯函数,不论是作为核函数还是正态分布,哪里都能找到它)。
public static final String AF_BIPOLAR="bipolar";
public static final String AF_COMPETITIVE="comp";
public static final String AF_GAUSSIAN="gauss";
public static final String AF_LINEAR="linear";
public static final String AF_LOG="log";
public static final String AF_RAMP="ramp";
public static final String AF_SIGMOID="sigmoid";
public static final String AF_SSIGMOID="ssigmoid";
public static final String AF_SIN="sin";
public static final String AF_SOFTMAX="softmax";
public static final String AF_STEP="step";
public static final StringAF_TANH="tanh";
确认节点数目,初始化节点
从构建一个空的神经网络开始,
EncogUtility.simpleFeedForward(INPUT_WINDOW,PREDICT_WINDOW*2,0,1,true);
其中,显然INPUT_WINDOW作为入参表达入参数量(也就是输入层节点数),然后是隐藏层1节点数,隐藏层2节点数(如果为0,表示无此层),输出层节点数,激活函数类型(true表示sanh激活函数,false表示sigmoid)。
在simpleFeedForward首先创建一个pattern,用于记录各层数据,
final FeedForwardPattern pattern = new FeedForwardPattern();
之后由
final BasicNetwork network = (BasicNetwork)pattern.generate();
执行创建神经网络。
在generate函数内开始按照节点创建各种BasicLayer,注意这是一个通用类型,可以是输入层,隐藏层或者输出层。创建完成后,
result.getStructure().finalizeStructure();
进行层的管理,从注释的表达上说,应该是为了构建一个可动态增加修改层和节点数的神经网络,因此对诸多层进行了浅复制和构建了一个FlatNetwork,注意FlatNetwork和BasicNetwork没有继承派生关系。这个flat存储于structure的flat。
flat是用于实际计算的神经网络,存储了权重,偏置等量
随后既是随机各层参数result.reset();。值得一提的是,NguyenWidrowRandomizer这个类根据
double b = 0.7d *Math.pow(toCount,(1d/fromCount))/(high-low);
计算出随机数的范围,而不再是传统意义上的BP神经网络的-0.5到0.5的范围。
同时,认定The bias neuron is alwaysthe last neuron on a layer.也就是每一层都会设置一个偏置神经元,这个神经元是所属层最末(右,下,参考神经元整体图像)。
对于这种偏置神经元设置的范围为-b到b,而其它节点都是0至b之间。、
疑问:final BasicNetwork network = (BasicNetwork)pattern.generate();
network.reset();
generate内已经reset一次,为什么还要reset一次?
在Predict内依旧再次reset
准备训练样本
TemporalWindowArray temp = new TemporalWindowArray(INPUT_WINDOW,PREDICT_WINDOW);
temp.analyze(a);
return temp.process(a);最终生成MLDataSet也就是最终的训练样本集。
Process是较为重要的一个过程,他包含了数据的整理,比如入参和出参的配对。
/**
* Process the array.
* @param data The array to process.
* @return A neural data set that contains the time-series.
*/
public final MLDataSet process(final double[] data) {
final MLDataSet result = new BasicMLDataSet();
final int totalWindowSize = this.inputWindow + this.predictWindow;
final int stopPoint = data.length - totalWindowSize;
for (int i = 0; i < stopPoint; i++) {
final MLData inputData
= new BasicMLData(this.inputWindow);
final MLData idealData
= new BasicMLData(this.predictWindow);
int index = i;
// handle input window
for (int j = 0; j < this.inputWindow; j++) {
inputData.setData(j, data[index++]);
}//显然inputWindow决定了每个点用来训练的样本是从此点起向后inputWindow个点
// handle predict window
for (int j = 0; j < this.predictWindow; j++) {
idealData.setData(j, data[index++]);
}//设置已知的值作为校验字段
假设输入窗口5,输出窗口2
那么,训练样本是从i开始5个数据,6-7个数据作为验证样本
final MLDataPair pair = new BasicMLDataPair(inputData,
idealData); //设置一组样本和实际值
result.add(pair);
}
return result;
}