Skip to content

Latest commit

 

History

History
113 lines (80 loc) · 3.45 KB

09_多分类问题.md

File metadata and controls

113 lines (80 loc) · 3.45 KB

多分类问题

代码示例

代码功能:通过一个5层全连接神经网络,演示 Torch.nn.CrossEntropyLoss 的用法。

  • 这里的 Y_pred 都是没有激活过的
  • 关于 Tensor 的 view 方法的使用请参考官方文档

image-20200820232054345

import torch
import torchvision
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

####################### Part1. Prepare Dataset #######################

batch_size = 64

# 依次执行其中的transform
# 1. 将PIL图像转为Pytorch的Tensor,图像张量的形状一般为(m,W*H*C),但在pytorch中是(m,C*W*H)
# 2. 将输入参数归一化,使其均值为0,标准差为1
# 其中,0.1307是整个mnist数据集的均值,0.3081是整个mnist数据集的标准差
transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize(0.1307, 0.3081)
])

x_train = torchvision.datasets.MNIST(root="D:/Drafts/mnist", train=True, download=True, transform=transform)
train_loader = DataLoader(x_train, shuffle=True, batch_size=batch_size)

x_test = torchvision.datasets.MNIST(root="D:/Drafts/mnist", train=False, download=True, transform=transform)
test_loader = DataLoader(x_test, shuffle=False, batch_size=batch_size)


####################### Part2. Design Model #######################

class MyModule(torch.nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.l1 = torch.nn.Linear(784, 512)
        self.l2 = torch.nn.Linear(512, 256)
        self.l3 = torch.nn.Linear(256, 128)
        self.l4 = torch.nn.Linear(128, 64)
        self.l5 = torch.nn.Linear(64, 10)
        self.activate = torch.nn.ReLU()

    def forward(self, x):
        # 类似于np.array的reshape,-1表示根据其他维数来推算这一维
        x = x.view(-1, 784)
        x = self.activate(self.l1(x))
        x = self.activate(self.l2(x))
        x = self.activate(self.l3(x))
        x = self.activate(self.l4(x))
        # 使用的损失函数是CrossEntropyLoss,因此最后一步不要激活
        x = self.l5(x)
        return x


model = MyModule()

####################### Part3. Construct Loss and Optimizer #######################

criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)


def train():
    cost_total = 0
    for i, data in enumerate(train_loader):
        inputs, labels = data

        y_pred = model(inputs)

        cost = criterion(y_pred, labels)
        cost_total += cost.item()

        optimizer.zero_grad()
        cost.backward()
        optimizer.step()

    return cost_total


####################### Part4. Train and Test #######################

def test():
    correct = 0
    total = 0

    with torch.no_grad():
        for i, data in enumerate(test_loader):
            inputs, labels = data

            y_pred = model(inputs)
            _, outputs = torch.max(y_pred.data, dim=1)

            # np.array用shape看各维度的维数,torch.Tensor用size看各维度的维数
            total += labels.size(0)
            correct += (outputs == labels).sum().item()

    print("test accuracy:", correct / total)


if __name__ == "__main__":
    for epoch in range(10):
        train()
        test() # 最终的准确率大致是96%