09.PyTorch深度学习实践——多分类问题

本次使用minist数据集学习多分类任务

minist数据集是多分类常用数据集,经常用作测试模型是否有效。数据集如下:

在这里插入图片描述
还得二分类任务时,分类目标是0,1,我们只需计算一种结果得概率就行,但是在多分类任务中,还采用传统方法就有些不合适了。这里我们得要求是使输出满足分布,即单个概率大于0,概率和为1。
softmax函数可以很好地解决这个问题,所以我们要引入softmax函数作为最后一层的激活函数。激活函数如下:

在这里插入图片描述
这里理解原理,在实际使用的时候,softmax被封装在了CrossEntropyLoss(交叉熵损失)这个函数中,我们只需注意网络的最后一层不加激活函数,并且在配置损失函数时调用即可。

本节要做图像的训练,所以还需要了解一点图像的处理步骤。
图像是由像素点组成的矩阵,每个像素点的值都不同。在最简单的黑白图像中,每个像素点的值是0-255,根据值的大小,像素点的颜色深度有所变化,由像素点构成的举证就构成了图像。

图像:
在这里插入图片描述
像素矩阵:
在这里插入图片描述

彩色图像的构成大同小异,是根据三颜色原理,由红绿蓝三张矩阵叠加在一起,可以看作一个三维矩阵,在本节不在详述。
所以我们处理图像时需要进行图像转换,才能交给网络进行学习。其中最简单的一种方法是将像素点拍成一行,看作一个一维矩阵,这里我们也采用了这种方法,但是这样有一个缺点,就是会丢失结构信息,并且由于像素点多,全连接网络的训练需要特别漫长的时间,所以才引入了cnn这一经典模型,这点我们后话再说。

首先,我们将图像矩阵转置,图像矩阵是[w, h, c],即宽,高,通道。我们需要将其转置为[c, w, h],将其变为张量,便于pytorch运算,同时对于神经网络而言,希望数值在-1——1之间,所以还要对图像进行标准化。
这些步骤说来麻烦,用起来也就两个函数,理解原理总是好的。

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307, ), (0.3081, ))
])
train_dataset = datasets.MNIST(root='data/MNIST/',
                               train=True,
                               download=True,
                               transform=transform)
train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size)
test_dataset = datasets.MNIST(root='data/MNIST/',
                              train=False,
                              download=True,
                              transform=transform)
test_loader = DataLoader(test_dataset,
                         shuffle=False,
                         batch_size=batch_size)


class Net(torch.nn.Module):
    def __init__(self):
        super(Net, 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)

    def forward(self, x):
        x = x.view(-1, 784)
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return self.l5(x)


model = Net()
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)


def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data
        optimizer.zero_grad()
        # forward + backward + update
        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        if batch_idx % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0


def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            outputs = model(images)
            _, predicted = torch.max(outputs.data, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set: %d %%' % (100 * correct / total))


if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()
        

输出:

[1,   300] loss: 2.209
[1,   600] loss: 0.844
[1,   900] loss: 0.395
Accuracy on test set: 89 %
[2,   300] loss: 0.308
[2,   600] loss: 0.263
[2,   900] loss: 0.234
Accuracy on test set: 93 %
[3,   300] loss: 0.189
[3,   600] loss: 0.174
[3,   900] loss: 0.154
Accuracy on test set: 95 %
[4,   300] loss: 0.133
[4,   600] loss: 0.128
[4,   900] loss: 0.121
Accuracy on test set: 96 %
[5,   300] loss: 0.104
[5,   600] loss: 0.098
[5,   900] loss: 0.093
Accuracy on test set: 96 %
[6,   300] loss: 0.080
[6,   600] loss: 0.078
[6,   900] loss: 0.073
Accuracy on test set: 96 %
[7,   300] loss: 0.063
[7,   600] loss: 0.062
[7,   900] loss: 0.061
Accuracy on test set: 97 %
[8,   300] loss: 0.049
[8,   600] loss: 0.049
[8,   900] loss: 0.051
Accuracy on test set: 97 %
[9,   300] loss: 0.040
[9,   600] loss: 0.037
[9,   900] loss: 0.043
Accuracy on test set: 97 %
[10,   300] loss: 0.031
[10,   600] loss: 0.031
[10,   900] loss: 0.035
Accuracy on test set: 97 %
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值