本文最后更新于:14 天前
反向传播(back propagation)算法python
实现
根据上一章所推导的反向传播(back propagation)算法所示例代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/8/15 21:32
# @Author : Seven
# @Site :
# @File : bp.py
# @Software: PyCharm
import numpy as np
def sigmod(x):
return 1 / (1 + np.exp(-x))
def sigmodDerivative(x):
return np.multiply(x, np.subtract(1, x))
def forward(weightsA, weightsB, bias):
# 前向传播
# 隐层
neth1 = inputX[0] * weightsA[0][0] + inputX[1] * weightsA[0][1] + bias[0]
outh1 = sigmod(neth1)
print("隐层第一个神经元", neth1, outh1)
neth2 = inputX[0] * weightsA[1][0] + inputX[1] * weightsA[1][1] + bias[1]
outh2 = sigmod(neth2)
print("隐层第二个神经元", neth2, outh2)
# 输出层
neto1 = outh1 * weightsB[0][0] + outh2 * weightsB[0][1] + bias[2]
outo1 = sigmod(neto1)
print("输出层第一个神经元", neto1, outo1)
neto2 = outh1 * weightsB[1][0] + outh2 * weightsB[1][1] + bias[3]
outo2 = sigmod(neto2)
print("输出层第二个神经元", neto2, outo2)
# 向量化
outA = np.array([outh1, outh2])
outB = np.array([outo1, outo2])
Etotal = 1 / 2 * np.subtract(y, outB) ** 2
print("误差值:", Etotal)
return outA, outB
def backpagration(outA, outB):
# 反向传播
deltaB = np.multiply(np.subtract(outB, y), sigmodDerivative(outB))
print("deltaB:", deltaB)
deltaA = np.multiply(np.matmul(np.transpose(weightsB), deltaB), sigmodDerivative(outA))
print("deltaA:", deltaA)
deltaWB = np.matmul(deltaB.reshape(2, 1), outA.reshape(1, 2))
print("deltaWB:", deltaWB)
deltaWA = np.matmul(deltaA.reshape(2, 1), inputX.reshape(1, 2))
print("deltaWA", deltaWA)
# 权重参数更新
weightsB_new = np.subtract(weightsB, deltaWB)
print("weightsB_new", weightsB_new)
bias[3] = np.subtract(bias[3], deltaB[1])
print("biasB", bias[3])
bias[2] = np.subtract(bias[2], deltaB[0])
print("biasB", bias[2])
weightsA_new = np.subtract(weightsA, deltaWA)
print("weightsA_new", weightsA_new)
bias[1] = np.subtract(bias[1], deltaA[1])
print("biasA", bias[1])
bias[0] = np.subtract(bias[0], deltaA[0])
print("biasA", bias[0])
print("all bias", bias)
return weightsA_new, weightsB_new, bias
if __name__=="__main__":
# 初始化数据
# 权重参数
bias = np.array([0.5, 0.5, 1.0, 1.0])
weightsA = np.array([[0.1, 0.3], [0.2, 0.4]])
weightsB = np.array([[0.6, 0.8], [0.7, 0.9]])
# 期望值
y = np.array([1, 0])
# 输入层
inputX = np.array([0.5, 1.0])
print("第一次前向传播")
outA, outB = forward(weightsA, weightsB, bias)
print("反向传播-参数更新")
weightsA_new, weightsB_new, bias = backpagration(outA, outB)
# 更新完毕
# 验证权重参数--第二次前向传播
print("第二次前向传播")
forward(weightsA_new, weightsB_new, bias)
程序执行结果:
第一次前向传播
隐层第一个神经元 0.85 0.7005671424739729
隐层第二个神经元 1.0 0.7310585786300049
输出层第一个神经元 2.0051871483883876 0.8813406204337122
输出层第二个神经元 2.1483497204987856 0.8955144637754225
误差值: [0.00704002 0.40097308]
反向传播-参数更新
deltaB: [-0.01240932 0.08379177]
deltaA: [0.01074218 0.01287516]
deltaWB: [[-0.00869356 -0.00907194]
[ 0.05870176 0.0612567 ]]
deltaWA [[0.00537109 0.01074218]
[0.00643758 0.01287516]]
weightsB_new [[0.60869356 0.80907194]
[0.64129824 0.8387433 ]]
biasB 0.9162082259892468
biasB 1.0124093185565075
weightsA_new [[0.09462891 0.28925782]
[0.19356242 0.38712484]]
biasA 0.48712483967909465
biasA 0.48925781687016445
all bias [0.48925782 0.48712484 1.01240932 0.91620823]
第二次前向传播
隐层第一个神经元 0.8258300879578699 0.6954725026123048
隐层第二个神经元 0.971030889277963 0.7253249281967498
输出层第一个神经元 2.022578998544453 0.8831474198595102
输出层第二个神经元 1.970574942645405 0.8776728542726611
误差值: [0.00682726 0.38515482]
我们可以看出误差值明显下降了,说明我们的权重参数更新是正确的。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!