本文是对学些B站东方耀老师教程bp算法的一个笔记。曲线救国第一步,先学算法对应的python编程,再将python程序改写为matlab程序。
BP算法,back propagation algorithm,全称是误差反向传播函数,就是在进行正向传播后计算出误差和预测值,再根据预测值和实际值的差距不断去调整网络中每一条链路的权重,从而使预测值不断接近实际值。但这种算法有一个缺点就是容易过拟合。
本文基于BP算法的神经网络如下图所示,输入层神经元个数为2个,输出层神经元个数为2个,中间隐藏层的神经元个数为3个;激活函数使用sigmoid函数;误差函数采用误差均方函数;用梯度下降的方法更新权重,学习率为0.5。
其详细的推导过程可见东方耀老师的视频,里面有很详尽的推导过程,这里不再赘述。
跟着视频打出来的python程序如下:
import numpy as np
w = [0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65]
b = [0, 0.35, 0.65]
l = [0, 5, 10]
s = 0.5 # 学习率
def sigmoid(z):
return 1.0/(1+np.exp(-z))
# print(sigmoid(0))
def bp(w, b, l):
# fp 前向传播,计算预测值与误差
h1 = sigmoid(w[1] * l[1] + w[2] * l[2] + b[1])
h2 = sigmoid(w[3] * l[1] + w[4] * l[2] + b[1])
h3 = sigmoid(w[5] * l[1] + w[6] * l[2] + b[1])
o1 = sigmoid(h1 * w[7] + h2 * w[9] + h3 * w[11]+b[2])
o2 = sigmoid(h1 * w[8] + h2 * w[10] + h3 * w[12]+b[2])
e = 1/2.0 * np.square(0.01 - o1)+1/2.0 * np.square(0.99 - o2)
# bp 后向传播,更新各个权重
t1 = -(0.01 - o1) * o1 * (1 - o1)
t2 = -(0.99 - o2) * o2 * (1 - o2)
w[7] = w[7] - s * (t1 * h1)
w[9] = w[9] - s * (t1 * h2)
w[11] = w[11] - s * (t1 * h3)
w[8] = w[8] - s * (t2 * h1)
w[10] = w[10] - s * (t2 * h2)
w[12] = w[12] - s * (t2 * h3)
w[1] = w[1] - s * (t1 * w[7] + t2 * w[8]) * h1 * (1 - h1) * l[1]
w[2] = w[2] - s * (t1 * w[7] + t2 * w[8]) * h1 * (1 - h1) * l[2]
w[3] = w[3] - s * (t1 * w[9] + t2 * w[10]) * h2 * (1 - h2) * l[1]
w[4] = w[4] - s * (t1 * w[9] + t2 * w[10]) * h2 * (1 - h2) * l[2]
w[5] = w[5] - s * (t1 * w[11] + t2 * w[12]) * h3 * (1 - h3) * l[1]
w[6] = w[6] - s * (t1 * w[11] + t2 * w[12]) * h3 * (1 - h3) * l[2]
return o1, o2, w, e
for i in range(1001):
o1, o2, w, e = bp(w, b, l)
print('第{}次迭代:预测值为:({},{}),总误差:{},权重系数{}'.format(i, o1, o2, e, w))
把python程序改写为matlab程序如下:
clc;
sym o1;
sym o2;
sym s;
w= {0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65};
b= {0, 0.35, 0.65};
l= {0, 5, 10};
for i=1:8000 %迭代8000次
[o1,o2,w]=backpropagation(w,b,l);
fprintf("第%d次:\r\n预测值:%f,%f\r\n%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\r\n", ...
i,o1,o2,w{2},w{3},w{4},w{5},w{6},w{7},w{8},w{9},w{10},w{11},w{12},w{13})
end
function [y]=sigmoid(x) %定义sigmoid激活函数
y=1.0/(1+exp(-x));
end
function[o1,o2,w]=backpropagation(w,b,l) %定义bp函数
s=0.5; % 学习率
% fp 前向传播,计算预测值与误差
h1 = sigmoid(w{1} * l{1} + w{2} * l{2} + b{1});
h2 = sigmoid(w{3} * l{1} + w{4} * l{2} + b{1});
h3 = sigmoid(w{5}* l{1} + w{6} * l{2} + b{1});
o1 = sigmoid(h1 * w{7} + h2 * w{9} + h3 * w{11}+b{2});
o2 = sigmoid(h1 * w{8} + h2 * w{10} + h3 * w{12}+b{2});
e = 1/2.0 * (0.01 - o1)^2+1/2.0 * (0.99 - o2)^2;
% bp 后向传播,更新各个权重
t1 = -(0.01 - o1) * o1 * (1 - o1);
t2 = -(0.99 - o2) * o2 * (1 - o2);
w{7} = w{7} - s * (t1 * h1);
w{9} = w{9} - s * (t1 * h2);
w{11} = w{11} - s * (t1 * h3);
w{8} = w{8} - s * (t2 * h1);
w{10} = w{10} - s * (t2 * h2);
w{12} = w{12} - s * (t2 * h3);
w{1} = w{1} - s * (t1 * w{7} + t2 * w{8}) * h1 * (1 - h1) * l{1};
w{2} = w{2} - s * (t1 * w{7} + t2 * w{8}) * h1 * (1 - h1) * l{2};
w{3} = w{3} - s * (t1 * w{9} + t2 * w{10}) * h2 * (1 - h2) * l{1};
w{4} = w{4} - s * (t1 * w{9} + t2 * w{10}) * h2 * (1 - h2) * l{2};
w{5} = w{5} - s * (t1 * w{11} + t2 * w{12}) * h3 * (1 - h3) * l{1};
w{6} = w{6} - s * (t1 * w{11} + t2 * w{12}) * h3 * (1 - h3) * l{2};
end
迭代了8000次后的结果: