【PyTorch系列】PyTorch -多层感知机(MLP)的从零开始实现

学习教材:
动手学深度学习 PYTORCH 版(DEMO)

(https://github.com/ShusenTang/Dive-into-DL-PyTorch)
PDF 制作by [Marcus Yang](https://github.com/chenyang1999)

直接代码:

import torch
from torch import nn
from torch.nn import init
import random
from IPython import display
from matplotlib import pyplot as plt
import torchvision

def load_data_fashion_mnist(batch_size, resize=None,root='./Datasets/FashionMNIST'):
    """
    Download the fashion mnist dataset and then load into memory.
    """
    trans = []
    if resize:
        trans.append(torchvision.transforms.Resize(size=resize))
    trans.append(torchvision.transforms.ToTensor())
    transform = torchvision.transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(root=root,
                                                    train=True, download=True, transform=transform)
    mnist_test = torchvision.datasets.FashionMNIST(root=root,
                                                   train=False, download=True, transform=transform)
    train_iter = torch.utils.data.DataLoader(mnist_train,
                                             batch_size=batch_size, shuffle=True, num_workers=4)
    test_iter = torch.utils.data.DataLoader(mnist_test,
                                            batch_size=batch_size, shuffle=False, num_workers=4)
    return train_iter, test_iter

# 以评价模型 net 在数据集 data_iter 上的准确率
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
    return acc_sum / n

# 对 x 的形状转换的这个功能⾃定义⼀个 FlattenLayer
class FlattenLayer(nn.Module):
    def __init__(self):
        super(FlattenLayer, self).__init__()
    def forward(self, x): # x shape: (batch, *, *, ...)
        return x.view(x.shape[0], -1)

# sgd算法:⾃动求梯度模块计算得来的梯度是⼀个批量样本的梯度和,
# 将它除以批量⼤⼩来得到平均值。
def sgd(params, lr, batch_size):
    for param in params:
        param.data -= lr * param.grad / batch_size # 注意这⾥更改param时⽤的param.data

#训练模型
def train_ch3(net, train_iter, test_iter, loss, num_epochs,batch_size,params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_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()  # “softmax回归的简洁实现”⼀节将⽤到

        train_l_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)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / n, train_acc_sum / n,
                 test_acc))
'''
多层感知机(MLP)的实现
'''

'''
    定义模型
'''

num_inputs, num_outputs, num_hiddens = 784, 10, 256
net = nn.Sequential()
net.add_module('flattenlayer',FlattenLayer())
net.add_module('linear1',nn.Linear(num_inputs,num_hiddens))
net.add_module('relu',nn.ReLU())
net.add_module('linear2',nn.Linear(num_hiddens,num_outputs))

for params in net.parameters():
    init.normal_(params,mean=0,std=0.01)

'''
    读取数据并训练模型
'''
batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
num_epochs = 5
train_ch3(net, train_iter, test_iter, loss, num_epochs,
batch_size, None, None, optimizer)

猜你喜欢

转载自blog.csdn.net/sazass/article/details/109731352