深度学习-一篇入门

【模型】一篇入门之-多层感知机MLP-一篇总述

作者 : 老饼 发表日期 : 2024-01-20 09:28:16 更新日期 : 2024-11-28 18:02:44
本站原创文章,转载请说明来自《老饼讲解-深度学习》www.bbbdata.com



多层感知机(MLP,Multilayer Perceptron)是一种全连接神经网络,属于深度学习的一种基础模型

本文讲解MLP的模型结构,前馈计算公式,以及MLP的训练方法,并展示一个MLP的代码实现例子

通过本文可以快速了解MLP多层感知机是什么,有什么用途,以及如何使用MLP来拟合输入与输出的关系





    01. 什么是多层感知机MLP     



本节讲解MLP多层感知机神经网络的模型结构与计算




     MLP多层感知机    


MLP在ANN中被称为BP神经网络,而在深度学习中,则常被称为全连接神经网络
多层感知机(MLP,Multilayer Perceptron)是深度学习中最基础、最常用的一种神经网络
MLP神经网络最基础的用途是数值预测,即解决输入为连续的数值,输出也为连续的数值的任务
 MLP多层感知机的结构如下:
  MLP多层感知机的拓扑结构   
如图,MLP由输入层、隐层、输出层组成(其中隐层可以是有多层的),各层则由神经元构成
 
MLP以前馈方式进行计算,即每层的输出作为下层的输入,不断套娃,直到输出层
 每层的计算公式如下:
 
其中,X:该层的输入           
W:该层的权重     
B:该层的阈值     
T:该层的激活函数 
比较经典的激活函数是tanh函数,它是一个S型函数,
但在深度学习中,由于层数过多tanh会导致训练困难,所以往往用ReLu函数作为激活函数
✍️MLP神经网络的生物意义
 MLP神经网络就是模仿人的大脑,在输入层接受到输入后,将值进行前馈式逐层传递,
每层的神经元都接受来自上层各个神经元的值,并且每个神经元都有自己的激活值和激活函数
在接受到上层的值之后,加上自身的阈值并通过激活函数进行转换后,再传给下一层,如此反复,直到最后一层(输出层)







    02. 三层MLP的结构与意义     



本节介绍最常用的三层MLP的结构及其意义




     三层MLP的结构与模型公式    


MLP神经网络虽然在提出时的结果是多层的、灵活的
但经过一段时间的实践后,MLP神经网络最常用的是如下的三层结构:
 
  三层MLP神经网络的结构  
 这种三层MLP只有一个隐层,隐层的神经元个数由具体问题具体设定
隐层的激活函数为tanh函数,输出层一般没有激活函数

 假设网络的输入只有两个、隐层有三个隐神经元,则它的数学表达式如下:
 三层MLP神经网络的数学表达式
 
 其中,tanh函数的数学表达式为:
   
 三层MLP的隐层使用tanh函数,主要是为了提供非线性影射功能
而输出层没有设置激活函数,则是为了不限制输出的范围




     如何理解三层MLP    


MLP最常用的就是三层结构,因为三层MLP就已经能够拟合任意x,y的关系
对于三层MLP,我们可以将其理解为使用多个tanh曲线来拟合目标曲线 
 如何理解三层MLP的数学表达式     
从图中可以看到,三层MLP的本质就是使用多个tanh曲线来拼凑目标曲线
而其中的各个W、b则控制了tanh曲线的高矮肥瘦与位置 
 三层MLP神经网络的本质  
可以说,隐层设置了多少个隐节点,就相当于用多少个tanh函数来拼凑目标曲线
只要隐节点设置得足够多,它就可以拟合任意形态的曲线
一般来说,如果需要拟合的目标曲线相对平滑简单,那么隐节点个数就少一些,否则,则需要多一些
三层MLP的意义
 三层MLP结构既简单,又能拟合出任意形态的曲线,
因此在深度学习中一般被当作一个“能拟合任意关系的黑箱模型”这样的小组件来使用
即,当X和y的关系不明确的时候,就直接假设它们的关系是y = MLP(x),然后再用数据来训练它






    03. MLP多层感知机的训练    



本节介绍MLP神经网络是如何训练的




     MLP神经网络的训练    


MLP的训练就是指求一组参数w,b,使得网络的输出误差(损失)越小越好
 
 MLP神经网络的损失函数
MLP的损失函数一般使用均方差误差函数:
 
其中,m为训练样本个数,k为输出个数,
 为第i个样本第j个输出的预测值,为对应的真实值
 MLP神经网络的训练算法
MLP神经网络的训练算法可以使用梯度下降算法
 梯度下降算法求解MLP神经网络的流程如下:
 梯度下降算法求解MLP神经网络的算法流程
一、先初始化一个解                                                 
二、迭代                                                                  
1. 计算所有w,b在当前处的梯度dw,db           
2. 将w,b往负梯度方向更新:                       
 w = w-lr*dw                       
b = b-lr*db                      

         3. 判断是否满足退出条件,如果满足,则退出迭代






   04. MLP神经网络-代码实现   




本节展示一个MLP神经网络用于数值预测的代码实现例子




     MLP神经网络应用于数值预测-代码实现    


本节展示如何使用MLP神经网络来解决数值预测问题,为方便理解,不妨采用以下的简单数据:
 MLP神经网络代码例子的数据 
 上述即为sin函数在[-5,5]之间的20个采样数据
 在pytorch中可以使用深度学习的相关框架来实现MLP神经网络
这里为了更具体了解MLP神经网络,尽量不使用pytorch的框架,而仅利用pytorch的自动求导功能
 用pytorch实现一个MLP神经网络的代码如下:
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)         
 
MLP神经网络代码运行结果 
可以看到,模型根据训练数据,已经较好地拟合出sin函数曲线
 将模型参数代回MLP神经网络的数学表达式,即可得到模型的数学表达式为:
 






好了,以上就是多层感知机MLP的全部内容了~









 End 




联系老饼