使用EMNIST数据集训练第一个pytorch CNN手写字母识别神经网络( 二 )

字符编码表(UTF-8)

使用EMNIST数据集训练第一个pytorch CNN手写字母识别神经网络

文章插图
字符编码表
首先我们建立一个字符编码表的规则,这是由于此数据集的label,是反馈一个字母的字符编码,我们只有通过此字符编码表才能对应起来神经网络识别的是那个字母
使用EMNIST数据集训练第一个pytorch CNN手写字母识别神经网络

文章插图
 
通过观察其数据集,此字母总是感觉怪,这是由于EMNIST数据集左右翻转图片后,又进行了图片的逆时针旋转90度,小编认为是进行图片数据的特征增强,目前没有一个文件来介绍为什么这样做,大家可以讨论
搭建神经网络神经网络的搭建,我们直接使用MNIST神经网络
# 定义神经网络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,# 输入通道数out_channels=16,# 输出通道数kernel_size=5,# 卷积核大小stride=1,#卷积步数padding=2,# 如果想要 con2d 出来的图片长宽没有变化,# padding=(kernel_size-1)/2 当 stride=1),# output shape (16, 28, 28)nn.ReLU(),# activationnn.MaxPool2d(kernel_size=2),# 在 2x2 空间里向下采样, output shape (16, 14, 14))self.conv2 = nn.Sequential(# input shape (16, 14, 14)nn.Conv2d(16, 32, 5, 1, 2),# output shape (32, 14, 14)nn.ReLU(),# activationnn.MaxPool2d(2),# output shape (32, 7, 7))self.out = nn.Linear(32 * 7 * 7, 37)# 全连接层,A/Z,a/z一共37个类def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = x.view(x.size(0), -1)# 展平多维的卷积图成 (batch_size, 32 * 7 * 7)output = self.out(x)return output以上代码在介绍手写数字时有详细的介绍,大家可以参考文章开头的文章链接,这里不再详细介绍了,这里需要注意的是神经网络有37个分类
神经网络的训练cnn = CNN() # 创建CNN# cnn = cnn.cuda() # 若有cuda环境,取消注释optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)# optimize all cnn parametersloss_func = nn.CrossEntropyLoss()# the target label is not one-hottedfor epoch in range(EPOCH):for step, (b_x, b_y) in enumerate(train_loader):# 每一步 loader 释放50个数据用来学习#b_x = b_x.cuda() # 若有cuda环境,取消注释#b_y = b_y.cuda() # 若有cuda环境,取消注释output = cnn(b_x)# 输入一张图片进行神经网络训练loss = loss_func(output, b_y)# 计算神经网络的预测值与实际的误差optimizer.zero_grad() #将所有优化的torch.Tensors的梯度设置为零loss.backward()# 反向传播的梯度计算optimizer.step()# 执行单个优化步骤if step % 50 == 0: # 我们每50步来查看一下神经网络训练的结果test_output = cnn(test_x)pred_y = torch.max(test_output, 1)[1].data.squeeze()# 若有cuda环境,使用84行,注释82行# pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()accuracy = float((pred_y == test_y).sum()) / float(test_y.size(0))print('Epoch: ', epoch, '| train loss: %.4f' % loss.data,'| test accuracy: %.2f' % accuracy)神经网络的训练部分也是往期代码,这里建议大家训练的EPOCH设置的大点,毕竟37个分类若只是训练一两次,其精度也很难保证
测试神经网络与保存模型# test 神经网络test_output = cnn(test_x[:10])pred_y = torch.max(test_output, 1)[1].data.squeeze()# 若有cuda环境,使用92行,注释90行#pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()print(pred_y, 'prediction number')print(test_y[:10], 'real number')# save CNN# 仅保存CNN参数,速度较快torch.save(cnn.state_dict(), './model/CNN_letter.pk')# 保存CNN整个结构#torch.save(cnn(), './model/CNN.pkl')训练完成后,我们可以检测一下神经网络的训练结果,这里需要注意的是,pred_y与test_y只是字母的编码,并不是真实的字母,最后我们保存一下神经网络的模型,方便下期进行手写字母的识别篇




推荐阅读