一、前置工作—确定神经网络结构
搭建神经网络完成某项特定任务,就像做一项工程,需要了解该项目的大致基本情况,准备图纸,才能确定每一步的落实方案。我在学校学习时忽视了这一点,只是老师下达了任务便埋头去构建网络,这其实不利于我对神经网络的深入理解。
首先,应该了解数据的基本情况,如手写数字识别任务中,图片的大小是多少,数据集规模有多大等。
在构建网络的部分,我们需要了解确定的是需要多少层卷积、全连接层,当然,为了填入具体的参数,也必须了解图片大小。通常深度学习项目需要一个卷积神经网络结构图,后续搭建网络都依据该图展开。现实中,设计每层卷积层输出通道也是需要通过训练才能得出最好参数的(相当于确定隐藏层),但在学习过程中直接采用较好的参数训练即可。
已知MNIST数据集图像大小为28×28的灰度图,设置神经网络卷积核为5*5,第一层输出通道数为6,第二层输出通道数为16,那么可以大致绘出神经网络结构图如下:

从左至右,最左的1@28×28表示输入图像(其实一般LeNet图不会标出,此处是为了方便理解)。输入进入网络,进行第一层卷积,第一层卷积输出通道为6,原图像大小不变,便得出6@28×28;卷积下一步即池化,这里采用2*2最大池化,即将原图像缩小到原来的一半,缩小的每个区域取最大值代替,依照这个流程完成若干层卷积池化的构造。在进入全连接层前,要注意先展平,最后输出分类结果数即可(0-9有10个数字,所以最终输出应为10).
二、开始搭建神经网络
根据上面画出的神经网络结构图,已经能够开始搭建神经网络了。
首先导入必要的库:
# 实现基本运算:
import torch
# 搭建网络结构:
import torch.nn as nn
# 实现前馈运算:
import torch.functional as f
开始编写神经网络架构:
# file:CNN.py
Class ConvNet(nn.Module):
"""编写一个卷积神经网络类"""
def __init__(self):
""" 初始化网络,将网络需要的模块拼凑出来。 """
super(ConvNet, self).__init__()
# 卷积层:
self.conv1 = nn.Conv2d(1, 6, 5, padding=2)
self.conv2 = nn.Conv2d(6, 16, 5, padding=2)
# 最大池化处理:
self.pooling = nn.MaxPool2d(2, 2)
# 全连接层:
self.fc1 = nn.Linear(16*7*7, 512)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
"""前馈函数"""
x = f.relu(self.conv1(x)) # = [b, 6, 28, 28]
x = self.pooling(x) # = [b, 6, 14, 14]
x = f.relu(self.conv2(x)) # = [b, 16, 14, 14]
x = self.pooling(x) # = [b, 16, 7, 7]
x = x.view(x.shape[0], -1)# = [b, 16 * 7 * 7]
x = f.relu(self.fc1(x))
x = self.fc2(x)
output = f.log_softmax(x, dim=1)
return output
为了后续计算准确率需要,此处还应加上一个计算准确率的方法:
def cal_correction(output, target)

本文介绍了如何从头开始构建一个卷积神经网络(CNN)来识别MNIST数据集的手写数字。首先强调了理解数据和确定网络结构的重要性,然后详细展示了使用PyTorch实现CNN的步骤,包括定义网络结构、导入数据、训练模型和测试模型的代码示例。最后,提到了模型的可视化测试,以验证其识别能力。

2万+

被折叠的 条评论
为什么被折叠?



