前言

上一个博客简要介绍了CNN,接下来我们用CNN搭建一个神经网络,在做图像分类问题时,之前将二维图像平铺成一维矩阵,使用MLP来解决问题,当图像不大的时候,可以实现最终的要求,但是这样做有两个弊端:一是当图像像素高的时候,这样的方法会增加模型复杂度;二是这种二向箔一样的降维会使得图像特征丢失,因此我们希望直接能够将二维矩阵作为输入,保留图像特征,将这个二维矩阵作为神经网络的一个神经元,参与到神经网络的运算中,这就引出了上个世纪风靡的卷积神经网络:LeNet,如今仍广泛应用于米国的图像识别中。

LeNet介绍

下图是LeNet的架构图,通过上文的学习,可以比较容易的理解其中意思。

LeNet使用的是MNIST数据集,该数据集是一堆手写数字,希望通过算法将他们分成0-9十个类,下文会展示该算法在MNIST数据集上的效果。
该算法首先以28*28的图像作为二维矩阵输入,然后在卷积层中,将卷积核与图像的二维矩阵作互相关运算得到卷积层的结果,然后将该结果传入池化层,通过池化操作对卷积层的二维矩阵结果进一步缩小尺寸,然后再重复上述操作一次,可以将二维图像进一步缩小,然后将缩小后的二维图像矩阵通过平铺的方式降维,导入MLP中训练,整体就是这样一个流程,接下来通过代码来细化每一步操作。

import torch
from torch import nn
from d2l import torch as d2l
#初始图像28*28
net = nn.Sequential(#输入1个二维矩阵图像,卷积第一层输出6个二维矩阵,这里二维矩阵可以类比MLP中的神经元#卷积第一层类比隐藏层第一层#padding=2,图像四周将两圈白边,相当于图像变成32*32#kernel_size=5,卷积核5*5,这里的卷积核可以类比MLP中的权重,是一个可学习的参数#通过与卷积核的互相关运算可以使得图像变成28*28#Sigmoid使得该卷积神经网络非线性化nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),#池化层中的池化矩阵2*2,步长2,说明每次池化的图像不重叠,图像变成14*14nn.AvgPool2d(kernel_size=2, stride=2),#第二个卷积层&池化层,与上面类似,不再详细讲解#第二卷积层有16个神经元输出,卷积核4*4,使得图像变成10*10nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),#池化2*2,步长2,使得图像变成5*5nn.AvgPool2d(kernel_size=2, stride=2),#二维矩阵图像降维,平铺nn.Flatten(),#转入MLP模型#因为第二卷积层是16个输出通道,因此转入MLP后的一维矩阵是16*5*5作为输入#后面就是MLP的操作了nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),nn.Linear(120, 84), nn.Sigmoid(),#经过2个MLP隐藏层,输出10个结果类nn.Linear(84, 10))

MNIST数据集实例展示

接下来我们运行一下当年LeNet跑的数据集

载入MNIST数据集

import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2ldef load_data_mnist(batch_size, resize=None):  #@save"""下载Fashion-MNIST数据集,然后将其加载到内存中"""# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式# 并除以255使得所有像素的数值均在0到1之间trans = [transforms.ToTensor()]#默认图像是28*28的尺寸,resize变量可以更改尺寸大小if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)#读取训练与测试数据mnist_train = torchvision.datasets.MNIST(root="../data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.MNIST(root="../data", train=False, transform=trans, download=True)#返回batch_size个训练和测试数据,shuffle变量表示是否要打乱下标,上一个blog有讲过#打乱下标可以让每一次的迭代选取的顺序不一样,训练需要,测试一般不需要#get_dataloader_workers表示需要几个进程来读取数据return (data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False,num_workers=get_dataloader_workers()))def get_dataloader_workers():  #@save"""使用4个进程来读取数据"""return 4batch_size = 256
train_iter, test_iter = load_data_mnist(batch_size=batch_size)

模型精度计算

之前讲到用GPU跑模型,相较于CPU,速度是有很大提升的,当然也取决于GPU的运行效率,本人用的是1050,速度也就快一倍…
这里除了计算精度外,就是将所有所需数据全部放到显存中。

def evaluate_accuracy_gpu(net, data_iter, device=None): #@save"""使用GPU计算模型在数据集上的精度"""if isinstance(net, nn.Module):net.eval()  # 设置为评估模式if not device:device = next(iter(net.parameters())).device# 正确预测的数量,总预测的数量metric = d2l.Accumulator(2)with torch.no_grad():for X, y in data_iter:if isinstance(X, list):# BERT微调所需的(之后将介绍)X = [x.to(device) for x in X]else:X = X.to(device)y = y.to(device)metric.add(d2l.accuracy(net(X), y), y.numel())return metric[0] / metric[1]

训练函数

在之前MLP用的训练函数基础上,将神经网络放到了GPU上,损失函数用的是交叉熵损失函数。

def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU训练模型(在第六章定义)"""def init_weights(m):if type(m) == nn.Linear or type(m) == nn.Conv2d:nn.init.xavier_uniform_(m.weight)net.apply(init_weights)print('training on', device)net.to(device)optimizer = torch.optim.SGD(net.parameters(), lr=lr)loss = nn.CrossEntropyLoss()animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],legend=['train loss', 'train acc', 'test acc'])timer, num_batches = d2l.Timer(), len(train_iter)for epoch in range(num_epochs):# 训练损失之和,训练准确率之和,样本数metric = d2l.Accumulator(3)net.train()for i, (X, y) in enumerate(train_iter):timer.start()optimizer.zero_grad()X, y = X.to(device), y.to(device)y_hat = net(X)l = loss(y_hat, y)l.backward()optimizer.step()with torch.no_grad():metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])timer.stop()train_l = metric[0] / metric[2]train_acc = metric[1] / metric[2]if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:animator.add(epoch + (i + 1) / num_batches,(train_l, train_acc, None))test_acc = evaluate_accuracy_gpu(net, test_iter)animator.add(epoch + 1, (None, None, test_acc))print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, 'f'test acc {test_acc:.3f}')print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec 'f'on {str(device)}')

结果

可以看到精度还是挺高的,我的1050显卡每秒处理10000条数据,我的i5-7代CPU每秒5000条,提升一倍,好的GPU可以跑到60000+,深度学习需要钞能力。

lr, num_epochs = 0.9, 10
train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果:loss 0.128, train acc 0.960, test acc 0.965
10621.3 examples/sec on cuda:0

使用Fashion—MNIST实例

除了训练数据集不一样,其他操作都一样。

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)

最终的精度结果在0.82,相比softmax回归可能还差点,这个模型还需要调整。

小结

LeNet卷积神经网络可以看作是CNN与MLP的一种结合,他的优点在于可以将二维图像作为模型的输入,可以避免降维带来的图像特征丢失,卷积神经网络在很多场景都可以使用,例如自然语言处理等等,使得我们的深度学习库变得更为丰富。

深度学习(14)——LeNet卷积神经网络相关推荐

  1. [人工智能-深度学习-33]:卷积神经网络CNN - 常见分类网络- LeNet网络结构分析与详解

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

  2. 深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-04-基于Python的LeNet之MLP

    原文地址可以查看更多信息 本文主要参考于:Multilayer Perceptron  python源代码(github下载 CSDN免费下载) 本文主要介绍含有单隐层的MLP的建模及实现.建议在阅读 ...

  3. 深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-03-基于Python的LeNet之LR

    原地址可以查看更多信息 本文主要参考于:Classifying MNIST digits using Logistic Regression  python源代码(GitHub下载 CSDN免费下载) ...

  4. 【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理(1)

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  5. 深度学习教程(10) | 卷积神经网络解读(吴恩达·完整版)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/35 本文地址:http://www.showmeai.tech/article-det ...

  6. 吴恩达.深度学习系列-C4卷积神经网络-W2深度卷积模型案例

    吴恩达.深度学习系列-C4卷积神经网络-W2深度卷积模型案例 (本笔记部分内容直接引用redstone的笔记http://redstonewill.com/1240/.原文整理的非常好,引入并添加我自 ...

  7. 深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)

    目录 一.前期准备 1.1 环境配置 1.2 CPU和GPU 1.2.1 CPU 1.2.2 GPU 1.2.3 CPU和GPU的区别 第一步:设置GPU 1.3 MNIST 手写数字数据集 第二步: ...

  8. 深度学习算法中卷积神经网络的应用

    下面一起来探讨一下关于深度学习算法中卷积神经网络的基本概念和应用: 1.卷积神经网络基本概念 卷积神经网络也是在传统人工神经网络的基础上发展起来的,它与 BP 神经网络有很大的相似之处,但也有很大的区 ...

  9. 记录|深度学习100例-卷积神经网络(CNN)彩色图片分类 | 第2天

    记录|深度学习100例-卷积神经网络(CNN)彩色图片分类 | 第2天 1. 彩色图片分类效果图 数据集如下: 测试图1如下 训练/验证精确图如下: 优化后:测试图--打印预测标签: 优化后:测试图- ...

  10. 深度学习的数学-卷积神经网络的误差反向传播

    文章目录 前言 正文 卷积神经网络中的关系式 卷积层 池化层 输出层 平方误差(损失函数) 梯度下降法 卷积层和输出层的神经单元误差(重点) 输出层的神经单元误差计算 输出层的神经单元与其权重偏置的关 ...

最新文章

  1. 14行代码AC_Break the Chocolate HDU-4112(数学推导+解析)
  2. get assigned pageset and my pages
  3. Linux中基于eBPF的恶意利用与检测机制(rootkit、驱动)
  4. 转载:建设工程中常见的项目建设管理模式有哪些(DBB模式、EPC模式)
  5. 机器学习系列——随机森林(五)
  6. PHP自学笔记 ---李炎恢老师PHP第一季 TestGuest0.5
  7. 资源搜索神器 海量精品资源教程 大大啦啦资源神器
  8. 用cube移植PS2手柄--HAL库
  9. 压缩图片的三种方式(Java)
  10. 拼多多电商外部工具(浏览器插件)
  11. html图片定位代码怎么写,如何在css中设置插入图片定位
  12. Windows无法连接到打印机怎么办?快收藏这些正确做法!
  13. 通过代码实现EXE文件图标的替换
  14. Java 正则表达式 中的 任意字符
  15. 杨绛:越是难熬的时候,人越要体面
  16. (转载)Java反射机制
  17. SAP推出On-Demand创新软件 瞄准中型企业
  18. Autodesk 3ds Max 2013 下载 破解 教程
  19. 【英语】克拉申博士的五大假说
  20. asciidoc html java_如何使用AsciiDoclet从.java文件中的javadoc注释生成asciidoc文件

热门文章

  1. linux盒子怎样重装,linux – 更新生产Ubuntu盒子的注意事项
  2. oracle 报未明确定义列
  3. 双网双待 玫瑰金镶边 酷派奢华旗舰N900+图赏
  4. 【报告分享】2021百度智慧城市白皮书-百度智能云(附下载)
  5. 了解3dmax炸开功能
  6. Service-黑名单来电自动挂断
  7. 计算机考研复习重点-计算机网络
  8. Unity 3D - UGUI 自适应文本框
  9. Android 语音合成
  10. 微信恶搞很火官方提醒方法