1、定义:BP神经网络是一种按照误差逆向传播算法训练的多层前馈神经网络。
2、BP神经网络的结构:BP网络具有输入层、隐藏层和输出层。
2、BP神经网络的计算过程:由正向计算过程和反向计算过程组成。正向传播过程,输入模式从输入层经隐单元层逐层处理,并转向输出层,每一层神经元的状态只影响下一层神经元的状态。如果在输出层不能得到期望的输出,则转入反向传播,将误差信号沿原来的连接通路返回,通过修改各神经元的权值,使得误差信号小。
3、BP算法
BP算法是一种监督式的学习算法,其主要思想是︰输入学习样本,使用反向传播算法对网络的权值和偏差进行反复的调整训练,使输出的向量与期望向量尽可能地接近。当网络输出层的误差平方和小于指定的误差时,训练完成。此时保存网络的权值和偏差。
假设w=[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.35,0.65],利用BP算法计算下图。
Note:网络层输出设为net,线性激活值为out
前向传播计算(eg:o1其他节点类似):
net_h1 = In1✖W1 + In2✖W2 + b1✖1
out_h1=1/(1+e^(-net_h1))
net_o1 = out_h1 ✖W7 + out_h2✖W9 + out_h3✖W11 + b2✖1
out_o1=1/(1+e^(-net_o1))
计算输出层的误差平方和:(1/2)*(d-o)^2
E_o1 = 0.5(0.01-out_o1)2
E_o2 = 0.5(0.99-out_o2)2
E_total= E_o1 + E_o2
计算输出层的误差平方和:(1/2)*(d-o)^2
后向传播计算(eg:W7,其他边类似):
算法实现:
# BP算法模拟
import numpy as np
w = [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.35,0.65]
In = [5,10]
# sigmoid函数:1/(1+e^(-x)) 用于线性转换
def sigmoid(x):
return 1/(1.0 + np.exp(-x))
# 线性计算
def comline(In1,w1,In2,w2,In3,w3,b):
return In1*w1+In2*w2+In3*w3+b*1
def Com_BP(In,w,b):
# 正向传播计算
net_h1 = comline(In[0],w[0],In[1],w[1],0,0,b[0])
out_h1=sigmoid(net_h1)
net_h2 = comline(In[0],w[2],In[1],w[4],0,0,b[0])
out_h2=sigmoid(net_h2)
net_h3 = comline(In[0],w[3],In[1],w[5],0,0,b[0])
out_h3=sigmoid(net_h3)
net_o1 = comline(out_h1,w[6],out_h2,w[8],out_h3,w[10],b[1])
out_o1=sigmoid(net_o1)
net_o2 = comline(out_h1,w[7],out_h2,w[9],out_h3,w[11],b[1])
out_o2=sigmoid(net_o2)
# 计算输出层的误差平方和
E_o1 = 0.5*(0.01-out_o1)**2
E_o2 = 0.5*(0.99-out_o2)**2
E_total = E_o1 + E_o2
#反向传播计算
#因为每个求导结果有公共的乘数,所以可以提取出来
# t1 = -(target-out_o1)*out_o1*(1-out_o1)
# t2 = -(target-out_o2)*out_o2*(1-out_o2)
t1 =-(0.01-out_o1) * out_o1 * (1-out_o1)
t2 =-(0.99-out_o2) * out_o2 * (1-out_o2)
w[0] = w[0] - 0.5*(t1*w[6]+t2*w[7]) * out_h1*(1-out_h1)*In[0]
w[1] = w[1] - 0.5*(t1*w[6]+t2*w[7]) * out_h1*(1-out_h1)*In[1]
w[2] = w[2] - 0.5*(t1*w[8]+t2*w[9]) * out_h2*(1-out_h2)*In[0]
w[3] = w[3] - 0.5*(t1*w[10]+t2*w[11]) * out_h3*(1-out_h3)*In[0]
w[4] = w[4] - 0.5*(t1*w[8]+t2*w[9]) * out_h2*(1-out_h2)*In[1]
w[5] = w[5] - 0.5*(t1*w[10]+t2*w[11]) * out_h3*(1-out_h3)*In[1]
w[6] = w[6] - 0.5*t1 * out_h1
w[7] = w[7] - 0.5*t2 * out_h1
w[8] = w[8] - 0.5*t1 * out_h2
w[9] = w[9] - 0.5*t2 * out_h2
w[10] = w[10] - 0.5*t1 * out_h3
w[11] = w[11] - 0.5*t2 * out_h3
return out_o1,out_o2,w
for i in range(100000):
OUT_O1,OUT_O2,W = Com_BP(In,w,b)
w = W
print(f'第{i}次:',OUT_O1,OUT_O2)
# print(OUT_O1,OUT_O2)
# print(W)
4、使用python实现BP神经网络对公路客运量和公路货运量的预测
代码如下:
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
#解决图片中文无法显示
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_csv('traffic_data.csv',encoding='GBK',delimiter='\t')
# print(data.head)
X = data[['人口数量','机动车数量','公路面积']]
Y = data[['公路客运量','公路货运量']]
print(X)
print(Y)
#对数据进行最大最小值归一化
X_scaler = MinMaxScaler(feature_range=(-1,1))
Y_scaler = MinMaxScaler(feature_range=(-1,1))
X = X_scaler.fit_transform(X)
Y = Y_scaler.fit_transform(Y)
#对样本进行转置,矩阵运算
sample_in = X
sample_out = Y
#BP神经网络网络参数
max_epochs = 60000 #循环迭代次数
learn_rate = 0.035 #学习率
mse_final = 6.5e-4 #设置一个均方误差的阈值,小于它则停止迭代
sample_number = 20#样本数
input_number = 3 #输入特征数
output_number = 2 #输出目标个数
hidden_number = 8 #隐含层神经元个数
#定义激活函数Sigmod
# sigmoid = 1/1+e^(-x)
def sigmoid(x):
return 1/(1+np.exp(-x))
def sigmoid_delta(z): #偏导数
return 1/((1+np.exp(-z))**2)*np.exp(-z)
#一层隐含层
#W1矩阵:M行N列,M等于该层神经元个数,N等于输入特征个数
w1 = 0.5 * np.random.rand(input_number,hidden_number) - 0.1
b1 = 0.5 * np.random.rand(1,hidden_number) - 0.1
w2 = 0.5 * np.random.rand(hidden_number,output_number) - 0.1
b2 = 0.5 * np.random.rand(1,output_number) - 0.1
mse_history=[] #空列表,存储迭代的误差
# bp
for i in range(max_epochs):
#FP
hidden_out = sigmoid(np.dot(sample_in,w1)+b1)
net_out = np.dot(hidden_out,w2)+b2
#误差
error = sample_out-net_out
mse_err = np.average(np.square(error)) #均方误差
mse_history.append(mse_err)
if mse_err<mse_final:
break
#BP
#误差向量
delta2 = -error #最后一层的误差 (20*2)
delta1 = np.dot(delta2 , w2.transpose()) * (1 - hidden_out) * hidden_out #(20*8)
dw2 = np.dot(hidden_out.transpose(),delta2) # (8*2)
dw1 = np.dot(sample_in.transpose(),delta1) #(3*8)
db2 = np.dot(np.ones((1,sample_number)),delta2) # (1*2)
db1 = np.dot(np.ones((1,sample_number)),delta1)# (1*8)
w2 = w2 - learn_rate * dw2
w1 = w1 - learn_rate * dw1
b2 = b2 - learn_rate * db2
b1 = b1 - learn_rate * db1
#损失值画图
print(mse_history)
loss=np.log10(mse_history)
min_mse=min(loss)
plt.plot(loss,label='loss')
plt.plot([0,len(loss)],[min_mse,min_mse],label='min_mse')
plt.xlabel('iteration')
plt.ylabel('MSE loss')
plt.title('Log10 MSE History',fontdict={'fontsize':18,'color':'red'})
plt.legend()
plt.show()
#模型预测输出和实际输出对比图
hidden_out=sigmoid(np.dot(sample_in,w1)+b1)
network_out=np.dot(hidden_out,w2)+b2 # (20 *2)
plt.figure(figsize=(8, 6))
plt.plot(network_out[:,0],label='pred')
plt.plot(sample_out[:,0],'r.',label='actual')
plt.title('客运量 ',)
plt.legend()
plt.show()
plt.figure(figsize=(8, 6))
plt.plot(network_out[:,1],label='pred')
plt.plot(sample_out[:,1],'r.',label='actual')
plt.title('货运量 ')
plt.legend()
plt.show()