利用pytorch搭建第一个卷积神经网络,实现minst手写数字识别
注意:若未安装GPU版本的pytorch,记得删掉代码中所有的 .cuda() 。
( .cuda() 为网络模型、输入图片、输入标签移至GPU的操作)
库函数的导入
import torchvision: torchvision包是服务于pytorch深度学习框架的,用来生成图片,视频数据集,和一些流行的模型类和预训练模型,包含以下四个模块
1. **torchvision.datasets** : 用于流行视觉数据集的数据加载器
2. **torchvision.models** : 流行模型架构的定义,例如 alexnet、 vgg 和 resnet 以及预先训练的模型。
3. **torchvision.transforms** :常见的图像转换,如随机作物,旋转等。
4. **torchvision.utils** : 有用的东西,如保存张量(3 x h x w)作为图像到磁盘,给定一个小批创建一个图像网格,等等。
import torch.utils.data as Data :加载数据用
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
import torch
import torchvision
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.utils.data as Data #加载数据用
下载数据并批量加载备用
EPOCH = 1 # 训练整批数据多少次
BATCH_SIZE = 64 # 每次批数的数据量
LR = 0.001 # 学习率,学习率的设置直接影响着神经网络的训练效果
#下载数据
train_data = torchvision.datasets.MNIST( # 训练数据
root='./mnist_data/',
train=True,
transform=torchvision.transforms.ToTensor(),
download=True
)
test_data = torchvision.datasets.MNIST(
root='./mnist_data/',
train=False,
transform=torchvision.transforms.ToTensor(),
download=True
)
# 批量加载
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
test_loader = Data.DataLoader(dataset=test_data, batch_size=BATCH_SIZE, shuffle=False)
数据可视化,读取一个批次的数据(64张图片),并单独显示第一张图片
# 数据可视化
images, label = next(iter(train_loader))
images_example = torchvision.utils.make_grid(images)
images_example = images_example.numpy().transpose(1, 2, 0)
mean = [0.5,0.5,0.5]
std = [0.5,0.5,0.5]
images_example = images_example * std + mean
plt.imshow(images_example)
plt.show()
image_array, _ = train_data[0] # 把一个批数的训练数据的第一个取出
image_array = image_array.reshape(28, 28)
plt.imshow(image_array)
plt.show()
搭建卷积神经网络,规定前向传播过程,选择优化函数和损失函数
#创建卷积神经网络类
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # input shape (1, 28, 28)
nn.Conv2d(
in_channels=1, # input height输入
out_channels=16, # n_filters输出
kernel_size=5, # filter size滤波核大小
stride=1, # filter movement/step步长
padding=2,
),
nn.ReLU(), # activation
nn.MaxPool2d(kernel_size=2),
)
self.conv2 = nn.Sequential(
nn.Conv2d(16, 32, 5, 1, 2),
nn.ReLU(), # activation
nn.MaxPool2d(2), # output shape (32, 7, 7)
)
self.out = nn.Linear(32 * 7 * 7, 10) # fully connected layer, output 10 classes
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1)
output = self.out(x)
return output
cnn = CNN().cuda()
print(cnn) # 显示神经网络
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # Adam优化函数
loss_func = nn.CrossEntropyLoss() # 损失函数(损失函数分很多种,CrossEntropyLoss适用于作为多分类问题的损失函数)
训练并测试神经网络
# training and testing
for epoch in range(EPOCH): # 训练批数
for step, (x, y) in enumerate(train_loader): # 每个批数的量
b_x = x.cuda() # batch x
b_y = y.cuda() # batch y
output = cnn(b_x) # cnn output
loss = loss_func(output, b_y) # cross entropy loss
print('epoch: %s step: %s loss: %s' % (epoch, step, loss))
optimizer.zero_grad() # 梯度清零
loss.backward() # 损失函数的反向传导
optimizer.step() # 对神经网络中的参数进行更新
print('**********************开始测试************************')
for step, (x, y) in enumerate(test_loader):# 在测试集上测试,并计算准确率
test_x, test_y = x.cuda(), y.cuda()
test_output = cnn(test_x)
# 以下三行为pytorch标准计算准确率的方法,十分推荐,简洁明了易操作
pred_y = torch.max(test_output.cpu(), 1)[1].numpy()
label_y = test_y.cpu().numpy()
accuracy = (pred_y == label_y).sum() / len(label_y)
print(test_output) # 查看一下预测输出值
print('acc: ', accuracy)