深度学习-一篇入门

【代码】一个实例之-实现一个MLP神经网络用于类别预测

作者 : 老饼 发表日期 : 2023-05-08 11:43:12 更新日期 : 2024-11-28 08:11:35
本站原创文章,转载请说明来自《老饼讲解-深度学习》www.bbbdata.com


MLP神经网络在用于类别预测时使用的是交叉熵损失函数,并以softmax作为输出层激活函数

本文展示一个MLP神经网络用于类别预测的例子,并用pytorch进行实现与训练

通过本文可以具体了解如何使用MLP神经网络进行类别预测以及pytorch的代码实现




   01. MLP神经网络类别预测-例子   




本节展示一个用MLP解决类别预测的例子,以及具体代码实现




     MLP神经网络类别预测-数据说明    


本节展示如何使用MLP神经网络来预测类别,为方便理解,不妨采用以下的简单数据:
 MLP神经网络类别预测-数据 
其中,x1,x2是样本的输入变量,y是样本的类别标签






     pytorch实现MLP神经网络-类别预测     


由于样本较为简单,因此本文只采用常规的三层MLP神经网络、4个隐节点进行拟合,
 整体MLP神经网络模型结构如下:
 MLP神经网络模型结构 
设置好以上的模型之后,将交叉熵作为损失函数,使用梯度下降法对其进行训练即可
在pytorch中可以使用深度学习的相关框架来实现MLP神经网络
本文为了更具体了解MLP神经网络,尽量不使用pytorch的框架,而仅利用pytorch的自动求导功能

使用pytorch实现MLP神经网络进行类别预测的代码如下:
import torch
import matplotlib.pyplot as plt 
import numpy as np
torch.manual_seed(99)      # 设定随机种子,使得每次运行结果一样

# -----------计算网络输出:前馈式计算---------------
def forward(w1,b1,w2,b2,x):                                   
    return torch.nn.Softmax(dim=0)(w2@torch.tanh(w1@x+b1)+b2)                    

# -----------计算损失函数: 使用交叉熵--------------
def loss(y,py):
    loss = 0                                                                        # 初始化损失值
    class_num,sample_num = y.shape                                                  # 类别个数与样本个数
    for i in range(class_num):                                                      # 累计每一类别的损失值
        loss = loss -torch.log(py[i,y[i,:]==1]).sum()/sample_num                    # loss = loss-sum(ln(p))/m
    return loss                                                                    
																			                                                         
# ------生成训练数据----------------                                                   
X = np.array([[2.5, 1.3, 6.2, 1.3, 5.4, 6 ,4.3, 8.2]                               
                ,[-1.2,2.5,3.6,4,3.4,2.3,7.2,3.9]])                                # 样本的输入数据
Y = np.array([[1,1,0,1,0,0,0,0],[0,0,1,0,1,1,1,1]])                                # 样本的标签,one-hot格式
x = torch.tensor(X).float()                                                        # 将训练数据X转为tensor
y = torch.tensor(Y).float()                                                        # 将训练数据y转为tensor

#-----------训练模型------------------------
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
															                      
# -------打印模型训练结果----------                                                              
labels   = torch.argmax(y, dim=0)                                                  # 将one-hot转为类别标签
py       = forward(w1,b1,w2,b2,x)                                                  # 计算网络的预测值
p_labels = torch.argmax(py, dim=0)                                                 # 将网络的预测转为类别标签
print('准确率:' ,((labels==p_labels).sum()/p_labels.numel()).numpy()*100,'%')      # 计算准确率 
# 绘制预测结果                                                                    
colors = ['red','g']                                                               # 定义0类的颜色为red,1类样本的颜色为green
labels_color   = [ colors[i] for i in labels]                                      # 各个样本真实对应的颜色  
p_labels_color = [ colors[i] for i in p_labels]                                    # 各个样本预测对应的颜色 
plt.scatter(X[0,:], X[1,:],c=labels_color,s=20)                                    # 绘制真实样本
plt.scatter(X[0,:], X[1,:],marker='o',c='none',edgecolors=p_labels_color,s=80)     # 绘制预测样本
plt.legend(['true label','predict label'])                                         # 显示图例
运行结果如下:
....                                                        
第 4995 轮损失函数值: tensor(0.0127, grad_fn=<SubBackward0>)
第 4996 轮损失函数值: tensor(0.0127, grad_fn=<SubBackward0>)
第 4997 轮损失函数值: tensor(0.0127, grad_fn=<SubBackward0>)
第 4998 轮损失函数值: tensor(0.0127, grad_fn=<SubBackward0>)
第 4999 轮损失函数值: tensor(0.0127, grad_fn=<SubBackward0>)
准确率: 100.0 %                                               
 
MLP神经网络类别预测-代码运行结果 
实心点的颜色是样本的真实类别,圆圈的颜色是样本的预测类别
可以看到,模型对所有样本的类别预测都是准确的





好了,以上就是在pytorch上实现MLP神经网络类别预测的代码例子了~








 End 




联系老饼