头一次写BP算法,写的过程中遇到了很多卡壳的地方,反复上网搜索,参考了很多牛人的大作,终于逐一解决了。现在拿出来总结一下,因为我发现这些问题具有共性,但是大多文章里却并不集中。
BP网络(Back Propagation Network)全名叫前馈向后传播网络.
0、BP网络原理
神经元仅向前连接。
每一层网络包涵者到下一层网络的连接,但没有下一层没有指向上一层的连接。
向后传播是一种有导师的学习,使用有道是的训练方法。
必须给网络提供输入样本和对应的期望输出。
BP训练算法将计算好的误差和各层的权值调整从输出层一路(经过若干隐层)倒着传回到输入层。
向后传播(BackPropagation--计算误差)和前馈(FeedForward--决定输出)通常同时发生。
1、建立算法的总结
抽象实体 建立类图
Neuron --> 神经元节点 ---Set<Link>-->(data)---Set<Link>-->
成员: Set<Link>:source 连接该节点的Link
成员: Set<Link>:target 该节点伸出去的Link
成员: double:data 该节点的状态值,隐节点的状态值是中间结果, 输入节点的data是输入样本,输出节点的data是样本的预测输出值
输入层节点: 0个source , hn个target (hn为隐节点个数)
隐层节点: in 个source, out个targe。
输出层节点:hn个source,1个target。
Link --> 神经元间的连接 (Neuron)---weight--->(Neuron) 连接是向前的,不能由后向前。
成员: Neuron: owner 发出该连接的节点
成员:Neuron:linker链接指向的节点
成员:double:weight神经元的权值
BackPropagation:
Neuron[]: input 输入层
Neuron[]: hidden 隐层
Neuron[]: output 输出层
double:learnrate 学习率(学习步长)
double:maxlen 最大学习次数(训练超过最大次数仍未收敛则训练失败)
2、节点个数的选取:
输入节点数就是样本维数,当然不包括被预测的期望值在内
输出节点数就是预测值的个数,一般是一个。
隐层节点个数的选取:有算法
过少导致低度拟合,过多导致过度拟合。
3、权值的初始值:
一般取取随机数或固定值。
4、输入归一化(包括期望输出):
输入值若不做归一化处理,则会导致
x = (xj- x(min))/(x(max)-x(min)) 对于列向量归一化。
5、学习率的调整
学习率:又叫学习速率或学习步长。
6、训练函数
权值修正向后传播,误差向前传播。训练算法采用梯度最速下降算法(LMS算法)。
传递函数使用Math.tanh(x)函数,值遇为[-1,1]的S型函数。
sigmoid(y)= tanh(x);
sigmoid'(y)=1.0 - sigmoid(y) * y;
8、总结
缺点:容易陷入局部最小收敛(意味着全局并不是最小的)
调试的重要性:算法中遇到问题,调试时很重要的,因为涉及到的参数太多,函数调用关系复杂(尤其是递归调用)若不养成一个很好的调试习惯很难检查出问题所在。笔者就有这样的经验。所以一定要养成良好的调试习惯,掌握设断点的技巧,适当的利用WatchExpression(Debug视图下的一个View)会节省不少时间。有时间的话,我会总结一下调试的经验。
作者是新手,见识有限,还望大家不要笑话。希望大家多多鼓励,以后还会贴出更多的开发经验。本文仍在在不断补充中,希望对刚接触算法有迷惑的朋友有所帮助。