本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/
目录
- 一、BP神经网络原理回顾
- 1.1 BP神经网络的结构简单回顾
- 1.2.BP神经网络的训练算法流程
- 二、python实现BP神经网络代码
- 2.1.数据介绍
- 2.2.pytorch实现BP神经网络代码
在python中要如何使用代码实现一个BP神经网络呢?
在python中可以利用pytorch来实现BP神经网络,这是最简洁也是最常用的方法。
通过本文可以详细掌握怎么使用python的pytorch来实现一个BP神经网络。
一、BP神经网络原理回顾
1.1 BP神经网络的结构简单回顾
BP神经网络的结构如下:
BP神经网络由输入层、隐层、输出层组成,其中隐层可以是有多层的,整个网络以前馈式进行计算,也就是每层的输出作为下层的输入,不断套娃,直到输出层
每层的计算公式如下:
y
=
T
(
W
X
+
B
)
y=T(WX+B)
y=T(WX+B)
其中,
X:该层的输入
W:该层的权重
B:该层的阈值
T:该层的激活函数
1.2.BP神经网络的训练算法流程
梯度下降算法求解BP神经网络的流程如下:
一、先初始化一个解
二、迭代
1. 计算所有w,b在当前处的梯度dw,db
2. 将w,b往负梯度方向更新:
w = w-lr*dw
b = b-lr*db
3. 判断是否满足退出条件,如果满足,则退出迭代
二、python实现BP神经网络代码
在python中只需要使用pytorch就可以简单实现BP神经网络,而且提供了丰富的训练算法。
2.1.数据介绍
为方便理解,不妨采用以下的简单数据:
上述即为sin函数在[-5,5]之间的20个采样数据
2.2.pytorch实现BP神经网络代码
下面展示在pytorch中实现BP神经网络的代码
特别说明:需要先安装pytorch包
import torch
import matplotlib.pyplot as plt
torch.manual_seed(99)
# -----------计算网络输出:前馈式计算---------------
def forward(w1,b1,w2,b2,x):
return w2@torch.tanh(w1@x+b1)+b2
# -----------计算损失函数: 使用均方差--------------
def loss(y,py):
return ((y-py)**2).mean()
# ------训练数据----------------
x = torch.linspace(-5,5,20).reshape(1,20) # 在[-5,5]之间生成20个数作为x
y = torch.sin(x) # 模型的输出值y
#-----------训练模型------------------------
in_num = x.shape[0] # 输入个数
out_num = y.shape[0] # 输出个数
hn = 4 # 隐节点个数
w1 = torch.randn([hn,in_num],requires_grad=True) # 初始化输入层到隐层的权重w1
b1 = torch.randn([hn,1],requires_grad=True) # 初始化隐层的阈值b1
w2 = torch.randn([out_num,hn],requires_grad=True) # 初始化隐层到输出层的权重w2
b2 = torch.randn([out_num,1],requires_grad=True) # 初始化输出层的阈值b2
lr = 0.01 # 学习率
for i in range(5000): # 训练5000步
py = forward(w1,b1,w2,b2,x) # 计算网络的输出
L = loss(y,py) # 计算损失函数
print('第',str(i),'轮:',L) # 打印当前损失函数值
L.backward() # 用损失函数更新模型参数的梯度
w1.data=w1.data-w1.grad*lr # 更新模型系数w1
b1.data=b1.data-b1.grad*lr # 更新模型系数b1
w2.data=w2.data-w2.grad*lr # 更新模型系数w2
b2.data=b2.data-b2.grad*lr # 更新模型系数b2
w1.grad.zero_() # 清空w1梯度,以便下次backward
b1.grad.zero_() # 清空b1梯度,以便下次backward
w2.grad.zero_() # 清空w2梯度,以便下次backward
b2.grad.zero_() # 清空b2梯度,以便下次backward
px = torch.linspace(-5,5,100).reshape(1,100) # 测试数据,用于绘制网络的拟合曲线
py = forward(w1,b1,w2,b2,px).detach().numpy() # 网络的预测值
plt.scatter(x, y) # 绘制样本
plt.plot(px[0,:],py[0,:]) # 绘制拟合曲线
print('w1:',w1)
print('b1:',b1)
print('w2:',w2)
print('b2:',b2)
运行结果如下:
.....
第 4996 轮: tensor(0.0083, grad_fn=<MeanBackward0>)
第 4997 轮: tensor(0.0083, grad_fn=<MeanBackward0>)
第 4998 轮: tensor(0.0083, grad_fn=<MeanBackward0>)
第 4999 轮: tensor(0.0083, grad_fn=<MeanBackward0>)
w1: tensor([[ 0.1742],[-0.8133],[-0.6450],[-0.4054]],requires_grad=True)
b1: tensor([[ 0.8125],[0.0593],[-1.8776],[1.1220]],requires_grad=True)
w2: tensor([[-0.7753,-2.0142,1.1161,1.9635]],requires_grad=True)
b2: tensor([[0.1094]], requires_grad=True)
可以看到,模型根据训练数据,已经较好地拟合出sin函数曲线
相关链接:
《老饼讲解-机器学习》:老饼讲解-机器学习教程-通俗易懂
《老饼讲解-神经网络》:老饼讲解-matlab神经网络-通俗易懂
《老饼讲解-神经网络》:老饼讲解-深度学习-通俗易懂