【PyTorch】实现多层感知机的构建

1.引入相关的包

import torch
import sys
sys.path.append("..")
import torch.nn as nn
import torchvision
import torch.utils.data as Data
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

这些包有大部分是pytorch自带的,其中matplotlib是一个用来画图的包,在这里我们需要用到。

2.获取fashion-mnist数据集

其中数据集下载的位置如下,自己可以做相关调整。

C:\Users\15347\Datasets\FashionMNIST

第一次下载数据集的时候,需要一段时间。再次运行的时候,数据集已经下载就不要时间了。其中第一次运行时,一定注意把这个属性设置为True,download=True,之后变可以设置为download=False

mnist_train = torchvision.datasets.FashionMNIST(
    root='~/Datasets/FashionMNIST', train=True, download=True, transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(
    root='~/Datasets/FashionMNIST', train=False, download=True, transform=transforms.ToTensor())

3.初始化batch_size,数据集类别

batch_size = 256
class_name = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
              'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

4.获得数据

下面是获得测试集和训练集

batch_size = 256
class_name = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
              'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']if sys.platform.startswith('win'):
    num_workers = 0
else:
    num_workers = 4
train_iter = torch.utils.data.DataLoader(
    mnist_train,batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(
    mnist_test,batch_size=batch_size, shuffle=True, num_workers=num_workers)

5.定义网络模型

定义模型前,首先需要确定输入层,隐藏层,输出层的节点个数。
在这里我是构建了两个隐藏层,关于节点个数的选择,大家可以参考其他知识。

每个样本输入是高和宽均为28像素的图像。模型的输入向量的长度是 28×28=784:该向量的每个元素对应图像中每个像素。由于图像有10个类别,单层神经网络输出层的输出个数为10,因此softmax回归的权重和偏差参数分别为784×10和1×10的矩阵。

num_inputs,num_outputs,num_hiddens1,num_hiddens2= 784,10,256,256

定义网络参数模型,初始化模型参数,代码片段如下:

class FlattenLayer(nn.Module):
    def __init__(self):
        super(FlattenLayer,self).__init__()
    def forward(self,x):
        return x.view(x.shape[0],-1)
net = nn.Sequential(
    FlattenLayer(),
    nn.Linear(num_inputs, num_hiddens1),
    nn.ReLU(),
    nn.Dropout(drop_prob1),
    nn.Linear(num_hiddens1, num_hiddens2),
    nn.ReLU(),
    nn.Dropout(drop_prob2),
    nn.Linear(num_hiddens2,num_outputs)
)
for param in net.parameters():
    nn.init.normal_(param, mean=0, std=0.01)

6.对模型的精度进行评估

def evaluate_accuracy(data_iter,net):
    acc_sum,n = 0.0,0
    for X,y in data_iter:
        if isinstance(net,torch.nn.Module):
            net.eval()
            acc_sum += (net(X).argmax(dim=1)==y).float().sum().item()
            net.train()
        else:
            if ('is_training' in net.__code__.co_varnames):
                acc_sum += (net(X,is_training = False).argmax(dim=1)==y).float().sum()
            else:
                acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
    #返回准确的元素概率
    return acc_sum / n

7.画图函数的定义

def semilogy(x_vals, y_vals, x_label, y_label, x2_vals=None, y2_vals=None,
             legend=None):
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.semilogy(x_vals, y_vals)
    if x2_vals and y2_vals:
        plt.semilogy(x2_vals, y2_vals, linestyle=':')
        plt.legend(legend)
    plt.show()

8.训练模型

这里需要给大家解释一下,为何学习率的选择是100,如此大。

原书的mxnet中的SoftmaxCrossEntropyLoss在反向传播的时候相对于沿batch维求和了,而PyTorch默认的是求平均,所以用PyTorch计算得到的loss比mxnet小很多(大概是maxnet计算得到的1/batch_size这个量级),所以反向传播得到的梯度也小很多,所以为了得到差不多的学习效果,我们把学习率调得成原书的约batch_size倍,原书的学习率为0.5,这里设置成100.0。(之所以这么大,应该是因为d2lzh_pytorch里面的sgd函数在更新的时候除以了batch_size,其实PyTorch在计算loss的时候已经除过一次了,sgd这里应该不用除了)

num_epochs,lr = 20,100
def train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,
                  params=None, lr=None, optimizer=None):
    loss_list,train_list,test_list = [],[],[]

    for epoch in range(num_epochs):
        #损失值、正确数量、总数 初始化
        train_loss_sum,train_acc_sum,n = 0.0,0.0,0

        for X,y in train_iter:
            y_hat = net(X)
            l = loss(y_hat,y).sum()

            # 梯度清零 损失函数和优化函数梯度清零
            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()

            l.backward()
            if optimizer is None:
                sgd(params, lr, batch_size)
            else:
                optimizer.step()

            train_loss_sum += l.item()
            train_acc_sum +=(y_hat.argmax(dim=1)==y).sum().item()
            n += y.shape[0]

        test_acc = evaluate_accuracy(test_iter,net)
        loss_list.append(train_loss_sum/n)
        train_list.append(train_acc_sum/n)
        test_list.append(test_acc)
        print('epoch %d, loss %.4f, train acc %.3f,test acc %.3f'
              %(epoch+1,train_loss_sum/n,train_acc_sum/n,test_acc))

    semilogy(range(1, num_epochs + 1), train_list, 'epochs', 'loss',
             range(1, num_epochs + 1), test_list, ['train', 'test'])
    return loss_list,train_list,test_list

9.代入运行

loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(),lr=0.5)
train_softmax(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)

10.运行结果

有关每次计算后的损失、测试、训练率的大小如下:

epoch 1, loss 0.0044, train acc 0.561,test acc 0.720
epoch 2, loss 0.0023, train acc 0.786,test acc 0.790
epoch 3, loss 0.0019, train acc 0.824,test acc 0.766
epoch 4, loss 0.0017, train acc 0.840,test acc 0.781
epoch 5, loss 0.0016, train acc 0.848,test acc 0.837
epoch 6, loss 0.0015, train acc 0.859,test acc 0.854
epoch 7, loss 0.0015, train acc 0.863,test acc 0.852
epoch 8, loss 0.0014, train acc 0.868,test acc 0.852
epoch 9, loss 0.0014, train acc 0.872,test acc 0.862
epoch 10, loss 0.0013, train acc 0.875,test acc 0.843
epoch 11, loss 0.0013, train acc 0.878,test acc 0.840
epoch 12, loss 0.0013, train acc 0.881,test acc 0.868
epoch 13, loss 0.0012, train acc 0.883,test acc 0.868
epoch 14, loss 0.0012, train acc 0.887,test acc 0.851
epoch 15, loss 0.0012, train acc 0.887,test acc 0.876
epoch 16, loss 0.0012, train acc 0.888,test acc 0.865
epoch 17, loss 0.0012, train acc 0.890,test acc 0.871
epoch 18, loss 0.0011, train acc 0.893,test acc 0.875
epoch 19, loss 0.0011, train acc 0.895,test acc 0.862
epoch 20, loss 0.0011, train acc 0.896,test acc 0.880

代码最后运行结果画出图像如下:

在这里插入图片描述

参考内容

动手学深度学习pytorch实现这本书:https://tangshusen.me/Dive-into-DL-PyTorch/#/

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多层感知(Multilayer Perceptron,MLP)是一种深度学习模型,它是在单层神经网络的基础上添加了一个或多个隐藏层的神经网络。在PyTorch中,可以使用torch.nn模块来构建多层感知模型。以下是构建一个简单的多层感知模型的步骤: 1. 导入所需的库: ``` import torch from torch import nn ``` 2. 定义多层感知模型类: ``` class MLP(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MLP, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, output_size) def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.fc2(x) return x ``` 这个模型有一个输入层(input_size)、一个隐藏层(hidden_size)和一个输出层(output_size)。在模型的构造函数中,使用nn.Linear定义了两个全连接层,使用nn.ReLU作为激活函数。 3. 实例化模型: ``` input_size = 784 # 输入特征的大小 hidden_size = 128 # 隐藏层的大小 output_size = 10 # 输出的类别数 model = MLP(input_size, hidden_size, output_size) ``` 4. 定义损失函数和优化器: ``` criterion = nn.CrossEntropyLoss() # 分类任务常用的交叉熵损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 使用随梯度下降优化器 ``` 5. 训练模型: ``` # 假设有训练数据集train_loader for images, labels in train_loader: # 将数据转换为模型所需的张量形式 images = images.view(-1, 28*28) labels = labels # 前向传播 outputs = model(images) # 计算损失 loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() ``` 以上是使用PyTorch实现多层感知的基本步骤。根据具体的任务和数据集,你可以调整模型的结构、超参数和优化策略来提高模型性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值