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()
将数据加载到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()
推荐阅读
-
(sklearn:Logistic回归)和(keras:全连接神经网络)完成mnist手写数字分类
-
【TensorFlow-windows】(四) CNN(卷积神经网络)进行手写数字识别(mnist)
-
《Pytorch - BP全连接神经网络模型》
-
pytorch全连接神经网络进行MNIST识别
-
pytorch 深度学习入门代码 (四)多层全连接神经网络实现 MNIST 手写数字分类
-
tensorflow实战之全连接神经网络实现mnist手写字体识别
-
(sklearn:Logistic回归)和(keras:全连接神经网络)完成mnist手写数字分类
-
两层全连接神经网络实现手写数字识别
-
pytorch实现MNIST手写体识别(使用全连接神经网络)