ANN神经网络训练使用back propagation算法
bp算法
利用输出后的误差来估计输出层的直接前导层的误差,再用这个误差估计更前一层的误差,如此一层一层的反传下去,就获得了所有其他各层的误差估计。
激活函数
激活函数使用sigmod函数,该函数处处可导。
使用sigmod函数时,bp网络输入与输出关系:
- 输入:
- 输出:
学习过程
神经网络在外界输入样本的刺激下不断改变网络的连接权值,以使网络的输出不断地接近期望的输出。
学习的本质是对各连接权值的动态调整。
核心思想:将输出误差以某种形式通过隐层向输入层逐层反传。
过程推导
定义
层网络结构:输入层有n个神经元,隐含层有p个神经元,输出层有q个神经元。
变量
输入向量:
隐含层输入向量:
隐含层输出向量:
输出层输入向量:
输出层输出向量:
期望输出向量:
输入层与隐含层连接权值:
隐含层与输出层连接权值:
隐含层各神经元阈值:
输出层各神经元阈值:
样本数据个数:k=1,2,…,m
激活函数:f(*)
误差函数:
隐含层和输出层的输入和输出:
*误差函数对输出层的各神经元的偏导数:
*误差函数对输出层的各神经元的偏导数:
修正隐含层与输出层之间的连接权值:
修正输入层与隐含层之间的连接权值:
ann前馈网络计算给定输入时的输出结果:
def feedForward(self, inputs):
''' 前馈计算各层结果
:param inputs:
:return:
'''
if len(inputs) != self.input - 1:
raise ValueError('Wrong number of inputs you silly goose!')
# input activations
for i in range(self.input-1):
self.ai[i] = inputs[i]
# hidden activations
for h in range(self.hidden):
sum = 0.0
for i in range(self.input):
sum += self.ai[i] * self.wih[i][h]
self.ah[h] = sigmod(sum)
# output activations
for o in range(self.output):
sum = 0.0
for h in range(self.hidden):
sum += self.ah[h] * self.who[h][o]
self.ao[o] = sigmod(sum)
return self.ao[:]
反馈网络计算delta并更新权重:
def backPropagate(self, targets, tmpLambda, correct):
''' 反馈算法,计算delta,以及更新权重
:param targets:
:param tmpLambda:
:param correct:
:return:
'''
if len(targets) != self.output:
raise ValueError('Wrong number of targets you silly goose!')
# calculate error terms for output
# the delta tell you which direction to change the weights
output_deltas = [0.0] * self.output
for o in range(self.output):
error = -(targets[o] - self.ao[o])
output_deltas[o] = dsigmod(self.ao[o]) * error
# calculate error terms for hidden
# delta tells you which direction to change the weights
hidden_deltas = [0.0] * self.hidden
for h in range(self.hidden):
error = 0.0
for o in range(self.output):
error = output_deltas[o] * self.who[h][o]
hidden_deltas[h] = dsigmod(self.ah[h]) * error
# update the weights connecting hidden to output
for h in range(self.hidden):
for o in range(self.output):
change = output_deltas[o] * self.ah[h]
self.who[h][o] -= tmpLambda * change + correct * self.cho[h][o]
self.cho[h][o] = change
# update the weights connecting input to hidden
for i in range(self.input):
for h in range(self.hidden):
change = hidden_deltas[h] * self.ai[i]
self.wih[i][h] -= tmpLambda * change + correct * self.cih[i][h]
self.cih[i][h] = change
# calculate error
error = 0.0
for k in range(len(targets)):
error += 0.5 * ((targets[k] - self.ao[k]) ** 2)
return error
参考:
https://databoys.github.io/Feedforward/
http://www.cnblogs.com/Finley/p/5946000.html
完整代码参考:
https://github.com/zhanggw/algorithm/tree/master/machine-learning/ANN