本文来自《老饼讲解-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神经网络-通俗易懂
 《老饼讲解-神经网络》:老饼讲解-深度学习-通俗易懂


















