刘二大人——卷积神经网络

基于MNIST数据集解决多分类问题+基于MNIST使用CNN

  1. 使用Softmax和CrossEntroyLoss解决多分类问题(MNIST数据集)

多分类问题:实际上求解的是随机事件的分布,解决方案应该基于两个要求:

  1. 每个分类出现的概率≥0(对所有输出进行指数运算)

  1. 各个分类出现的概率之和=1(对结果进行归一化处理)

基于以上分析引入了softmax来实现多分类问题的基本要求。

损失Loss:使用pytorch中的交叉熵损失即可,将由类别(label)生成的one-hot编码和softmax经过求对数之后进行的运算,这些计算过程合并到一起就是交叉熵损失,所以使用交叉熵损失的时候神经网络最后一层不能激活,因为包含在交叉熵损失里面。

所以,解决多分类问题可以分为四个步骤,分别是:

  1. 准备数据

  1. 设计模型

  1. 定义损失和优化器

  1. 进行训练和测试

准备数据之前先导入在torch中我们需要的包,包括transforms、datasets、DataLoader等

  1. 准备数据,MNIST数据集是Pytorch自带的数据集,将download设置为True就会自动下载该数据集。

下载成功以后可以提取图片并使用cv2保存图片。

  1. 定义模型

如下图,左图是MNIST中的一个图片,右图对应的是将其用矩阵表示的形式,MNIST数据集中单张数字图片都是28*28=784大小的灰度图,每个像素值的取值是{0,255},需要将每个像素点的值映射到[0,1]。

在这个例子中要把原始图像转变成张量,所以每个批量输入神经网络的数据将会是(N,1,28,28),每个里面有N个样本,每个样本是1维(通道)的28*28的图像。

由于全连接神经网络要求输入的是矩阵,首先需要做的是1*28*28的三阶张量变成1阶向量,(就是把多行拼接成一行),使用view就可以改变张量形状,784指的是像素数量,-1可以自动计算N,接下来就是对应的模型。

在代码中,首先初始化线性层,在初始化方法里定义线性模型,一共五层,最后变成10。

然后在forward里面使用relu对每一层进行激活,最后一层不需要激活,因为直接是线性层的输出接到softmax层,最后网络定义层model。

  1. 关于损失和优化

损失使用pytorch自带的交叉熵损失,经过softmax求对数然后和one-hot做相应的乘法计算出损失,优化器使用带有冲量值的梯度下降,优化训练过程。

  1. 训练和测试

将一轮循环封装成一个函数train,使用enumerate将训练样本提取出来,inputs相当于x,target相当于Y,然后将优化器清零;接下来就是前馈(计算输出和损失)、反馈和优化;最后累计损失,每训练300次进行一次迭代,输出其损失。

在测试过程中不需要反向传播,只需要计算正向传播和分类正确的数量即可。在测试过程中不需要计算梯度,此时使用with torch.no_grad(),correct是指计算正确的是多少,然后从test_loader里面提取数据做预测,使用torch.max()计算出每一行的最大值和下标(预测结果),然后求总数total(size(0)取得是样本形状的第一个值,如(N,1)就是N),接下来将预测出来的值和真实值作比较,相等为真,否则为假。最后正确数除以总数就是正确率。

  1. 使用CNN跑MNIST数据集

CNN更多是针对具有某种特征的图像的处理,如下图所示,他可以分为两个步骤,分别是特征提取和图像分类,在特征提取过程中包含两个步骤,分别是卷积和下采样。在卷积层,可以通过不断的改变卷积核矩阵的值来关注不同的细节,提取不同的特征;也就是说,在初始化卷积核的矩阵值(即权重参数)后,我们通过梯度下降不断降低loss来获得最好的权重参数,整个过程都是自动调整的。在池化层(也称之为下采样)可以对数据进行降维避免过拟合,如下图就是基本的一个使用CNN进行图像处理的一个过程。

利用CNN跑MNIST数据集的过程如下图所示,将一个(1, 28, 28)的图像张量输入进卷积网络中:

  1. 首先经过一个卷积核大小为(5,5) 输出通道数为10的卷积层;

  1. 经过一个(2,2)的最大池化层(取出2*2范围内的最大值返回给输出);

  1. 再经过一个卷积核大小为(5,5) 输出通道数为20的卷积层,通道数变为20;

  1. 又经过一个(2,2)的最大池化层;

  1. 最终通过一个输入为320维输出为10为的全连接层(作为分类器),得到10个概率值对应于10种类型 320由上一层的参数总数计算而来(20 * 4 * 4);

运算过程中,池化层不关注输入输出的维度,但是卷积层和全连接层的输入和输出维度一定要和前后层相对应。

它对应的步骤及其核心函数如下:

代码实现如下,初始化了两个卷积层、1个池化层、1个全连接层。在forward中,先从x数据维度获得batch_size,然后按照卷积层至池化层至激活函数的顺序定义每一层,最后将数据展开,为输入全连接层做准备。

如果将模型移动到GPU上运行,需要添加如下相应的代码,将数据一同移动到GPU上。

如上图所示,第一张图是全连接神经网络测试的准确率,第二张图是CNN测试得出的准确率,上升了1%,从错误率的角度来看,降低了1%,效果提升的还是比较明显的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值