pytorch全连接神经网络进行MNIST识别

这个例程使用全连接神经网络进行MNIST识别

import numpy as np
import torch
from torchvision.datasets import mnist

from torch import nn
from torch.autograd import Variable
def data_tf(x):
    x = np.array(x, dtype="float32")/255
    x = (x-0.5)/0.5
    x = x.reshape((-1))   # 变成1行n列
    x = torch.from_numpy(x)
    return x

# 加载mnist数据集
train_set = mnist.MNIST("./data", train=True, transform=data_tf, download=False)
test_set = mnist.MNIST("./data", train=False, transform=data_tf, download=False)

a, a_label = train_set[0]
print(a.shape)
print(a_label)
torch.Size([784])
5

展示数据

import matplotlib.pyplot as plt


for i in range(1, 26):
    plt.subplot(5,5,i)
    plt.xticks([])    # 去掉坐标系
    plt.yticks([])
    plt.imshow(train_set.data[i].numpy(), cmap="gray")
    plt.title("%i" % train_set.targets[i])
plt.subplots_adjust(wspace =0, hspace =1)   # 调整子图间距
plt.show()

在这里插入图片描述

将数据加载到DataLoader中

from torch.utils.data import DataLoader
train_data = DataLoader(train_set, batch_size=64, shuffle=True)
test_data = DataLoader(test_set, batch_size=128, shuffle=False)

a, a_label = next(iter(train_data))
print(a.shape)
print(a_label.shape)
torch.Size([64, 784])
torch.Size([64])

下面定义四层神经网络

net = nn.Sequential(
    nn.Linear(784, 400),
    nn.ReLU(),
    nn.Linear(400, 200),
    nn.ReLU(),
    nn.Linear(200, 100),
    nn.ReLU(),
    nn.Linear(100, 10),
    nn.ReLU()
)
if torch.cuda.is_available():
    net = net.cuda()

定义损失函数和优化方法

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), 1e-1)

开始训练

losses = []
acces = []
eval_losses = []
eval_acces = []

for e in range(20):    # 训练20轮
    train_loss = 0
    train_acc = 0
    net.train()
    for im, label in train_data:
        if torch.cuda.is_available():
            im = Variable(im).cuda()
            label = Variable(label).cuda()
        else:
            im = Variable(im)
            label = Variable(label)
        
        # 前向传播
        out = net(im)
        loss = criterion(out, label)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        # 记录误差
        train_loss += loss.item()
        
        # 计算分类的准确率
        # max函数参数1表示按行取最大值,第一个返回值是值,第二个返回值是下标
        # pred是一個1*64的向量
        _, pred = out.max(1)
        num_correct = (pred==label).sum().item()
        acc = num_correct/im.shape[0]
        train_acc += acc
    
    # 此时一轮训练完了
    losses.append(train_loss/len(train_data))
    acces.append(train_acc/len(train_data))
    
    # 在测试集上检验效果
    eval_loss = 0
    eval_acc = 0
    net.eval()
    for im, label in test_data:
        if torch.cuda.is_available():
            im = Variable(im).cuda()
            label = Variable(label).cuda()
        else:
            im = Variable(im)
            label = Variable(label)
        # 前向传播
        out = net(im)
        
        # 计算误差
        loss = criterion(out, label)
        eval_loss += loss.item()
        
        # 计算准确率
        _, pred = out.max(1)
        num_correct = (pred==label).sum().item()
        acc = num_correct/im.shape[0]
        eval_acc += acc
    
    eval_losses.append(eval_loss/len(test_data))
    eval_acces.append(eval_acc/len(test_data))
    
    print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc: {:.6f}'
        .format(e, train_loss / len(train_data), train_acc / len(train_data), 
                    eval_loss / len(test_data), eval_acc / len(test_data)))
        
epoch: 0, Train Loss: 0.907578, Train Acc: 0.696812, Eval Loss: 0.643739, Eval Acc: 0.799545
epoch: 1, Train Loss: 0.184014, Train Acc: 0.943064, Eval Loss: 0.145216, Eval Acc: 0.955993
epoch: 2, Train Loss: 0.122061, Train Acc: 0.962437, Eval Loss: 0.106904, Eval Acc: 0.966278
epoch: 3, Train Loss: 0.094608, Train Acc: 0.971332, Eval Loss: 0.140383, Eval Acc: 0.954114
epoch: 4, Train Loss: 0.077595, Train Acc: 0.975380, Eval Loss: 0.146929, Eval Acc: 0.955004
epoch: 5, Train Loss: 0.062536, Train Acc: 0.980360, Eval Loss: 0.077517, Eval Acc: 0.977057
epoch: 6, Train Loss: 0.054142, Train Acc: 0.981926, Eval Loss: 0.075962, Eval Acc: 0.976661
epoch: 7, Train Loss: 0.047080, Train Acc: 0.985191, Eval Loss: 0.075141, Eval Acc: 0.977156
epoch: 8, Train Loss: 0.038137, Train Acc: 0.987507, Eval Loss: 0.091325, Eval Acc: 0.969442
epoch: 9, Train Loss: 0.033889, Train Acc: 0.988806, Eval Loss: 0.071590, Eval Acc: 0.978639
epoch: 10, Train Loss: 0.030078, Train Acc: 0.990055, Eval Loss: 0.087938, Eval Acc: 0.975079
epoch: 11, Train Loss: 0.024422, Train Acc: 0.991871, Eval Loss: 0.075225, Eval Acc: 0.979134
epoch: 12, Train Loss: 0.020831, Train Acc: 0.993387, Eval Loss: 0.063592, Eval Acc: 0.982793
epoch: 13, Train Loss: 0.017959, Train Acc: 0.994253, Eval Loss: 0.072732, Eval Acc: 0.981112
epoch: 14, Train Loss: 0.018088, Train Acc: 0.994236, Eval Loss: 0.076040, Eval Acc: 0.978639
epoch: 15, Train Loss: 0.016643, Train Acc: 0.994736, Eval Loss: 0.097675, Eval Acc: 0.975277
epoch: 16, Train Loss: 0.012496, Train Acc: 0.996135, Eval Loss: 0.071067, Eval Acc: 0.982595
epoch: 17, Train Loss: 0.014088, Train Acc: 0.995469, Eval Loss: 0.072692, Eval Acc: 0.980024
epoch: 18, Train Loss: 0.012286, Train Acc: 0.996269, Eval Loss: 0.069317, Eval Acc: 0.982496
epoch: 19, Train Loss: 0.007021, Train Acc: 0.998018, Eval Loss: 0.073944, Eval Acc: 0.982100

画出loss曲线和准确率曲线

%matplotlib inline
plt.subplot(2, 2, 1)
plt.title("train loss")
plt.plot(np.arange(len(losses)), losses)
plt.grid()
plt.subplot(2, 2, 2)
plt.title("train acc")
plt.plot(np.arange(len(acces)), acces)
plt.grid()
plt.subplot(2, 2, 3)
plt.title("test loss")
plt.plot(np.arange(len(eval_losses)), eval_losses)
plt.grid()
plt.subplot(2, 2, 4)
plt.title("test acc")
plt.plot(np.arange(len(eval_acces)), eval_acces)
plt.grid()
plt.subplots_adjust(wspace =0.5, hspace =0.5)

在这里插入图片描述

我们来测试几个数据吧

for i in range(1, 5):
    im = test_set.data[i]
    label = test_set.targets[i]
    plt.subplot(2, 2, i)
    plt.imshow(im.numpy(), cmap="gray")
    plt.xticks([])
    plt.yticks([])
    im = data_tf(im)
    im = Variable(im).cuda()
    out = net(im)
    _, pred = out.max(0)
    plt.title("outcome=%i" % pred.item())
plt.show()


  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值