欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-04 21:09:42
...

这个例程使用全连接神经网络进行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()

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

将数据加载到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)

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

我们来测试几个数据吧

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()

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


相关标签: 计算机视觉