手写数字识别【刘二大人《PyTorch深度学习实践】p9 多分类问题

手写数字识别【刘二大人《PyTorch深度学习实践】

代码:

import torch
from torchvision import transforms  # 数据集相关  针对图像进行原始处理的工具
from torchvision import datasets  # 数据集相关
from torch.utils.data import DataLoader  # 数据集相关
import torch.nn.functional as F  # 全连接层中的激活函数不用sigmod(),使用更加主流的ReLU()
import torch.optim as optim  # 优化器的包

#########################################################################################################################################
#数据准备

batch_size = 64
#pytorch读图像,用python中的PIL/Pillow读入:神经网络来做处理时,要求输入数据较小且最好在0-1之间,输入呈现正态分布,这样对于神经网络的训练时最好
#即 transform就是将 原始数据转化为张量,并做normalization(数据标准化)
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))  # 归一化 (0.1307,)->均值mean, (0.3081,)->标准差std
])                                         
# Normalize过程:Pixel(norm) = (Pixel(origin)-mean)/std

train_dataset = datasets.MNIST(root='../dataset/mnist/',
                               train=True,
                               download=True,
                               transform=transform)
train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size)

test_dataset = datasets.MNIST(root='../dataset/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, 24)   ##自己修改的
        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))
        #x = F.relu(self.l5(x))
        return self.l5(x)    #最后一层不用激活函数,线性层输出就是结果->交叉熵中有softmax激活函数

model = Net()

#########################################################################################################################################
#选择损失和优化器

criterion = torch.nn.CrossEntropyLoss()   # 使用交叉熵损失 交叉熵中包含了softmax()激活函数+NLLLoss  所以直接线性层输出即可!!!
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)  # 随机梯度下降优化器 momentum动量为0.5

#########################################################################################################################################
#train and test

def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data   # inputs = x ,target =  y
        optimizer.zero_grad()   # 优化器清零

        # forward + backward + update
        outputs = model(inputs)            # 输出
        loss = criterion(outputs, target)  # 算损失
        loss.backward()                    # 反馈
        optimizer.step()                   # 优化

        running_loss += loss.item()       # 累积loss
        if batch_idx % 300 == 299:        # 每300迭代轮输出一次running_loss
            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:          # 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)
        #if epoch % 10 == 9:  # 每10轮输出一个test
        test()

结果:

[1, 300] Loss: 2.179
[1, 600] Loss: 0.865
[1, 900] Loss: 0.398
Accuracy on test set: 89 %
[2, 300] Loss: 0.309
[2, 600] Loss: 0.258
[2, 900] Loss: 0.230
Accuracy on test set: 94 %
[3, 300] Loss: 0.189
[3, 600] Loss: 0.176
[3, 900] Loss: 0.155
Accuracy on test set: 95 %
[4, 300] Loss: 0.135
[4, 600] Loss: 0.124
[4, 900] Loss: 0.121
Accuracy on test set: 96 %
[5, 300] Loss: 0.101
[5, 600] Loss: 0.093
[5, 900] Loss: 0.100
Accuracy on test set: 96 %
[6, 300] Loss: 0.080
[6, 600] Loss: 0.080
[6, 900] Loss: 0.072
Accuracy on test set: 97 %
[7, 300] Loss: 0.062
[7, 600] Loss: 0.065
[7, 900] Loss: 0.066
Accuracy on test set: 97 %
[8, 300] Loss: 0.052
[8, 600] Loss: 0.052
[8, 900] Loss: 0.054
Accuracy on test set: 97 %
[9, 300] Loss: 0.042
[9, 600] Loss: 0.041
[9, 900] Loss: 0.044
Accuracy on test set: 97 %
[10, 300] Loss: 0.034
[10, 600] Loss: 0.032
[10, 900] Loss: 0.038
Accuracy on test set: 97 %

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值