本站原创文章,转载请说明来自《老饼讲解-深度学习》www.bbbdata.com
MLP神经网络在用于类别预测时使用的是交叉熵损失函数,并以softmax作为输出层激活函数
本文展示一个MLP神经网络用于类别预测的例子,并用pytorch进行实现与训练
通过本文可以具体了解如何使用MLP神经网络进行类别预测以及pytorch的代码实现
本节展示一个用MLP解决类别预测的例子,以及具体代码实现
MLP神经网络类别预测-数据说明
本节展示如何使用MLP神经网络来预测类别,为方便理解,不妨采用以下的简单数据:
其中,x1,x2是样本的输入变量,y是样本的类别标签
pytorch实现MLP神经网络-类别预测
由于样本较为简单,因此本文只采用常规的三层MLP神经网络、4个隐节点进行拟合,
整体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 %
实心点的颜色是样本的真实类别,圆圈的颜色是样本的预测类别
可以看到,模型对所有样本的类别预测都是准确的
好了,以上就是在pytorch上实现MLP神经网络类别预测的代码例子了~
End