目录
卷积神经网络
LeNet是最早发布的卷积神经网络之一,因为它在计算机视觉任务中的高效性-能而广泛受到关注。
目的是识别手写的数字。
在总体上看:LeNet由两个部分组成:
卷积编码器(由两个卷积层组成)
全连接层密集块(由三个全连接层组成)
上图中的卷积块中的基本单位是一个卷积层、一个sigmoid激活函数和平均汇聚层。为了将卷积块的输出传递给稠密块,我们需要将这个四维输入转换成全连接层所期望的二维输入
模型设计
import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(), #卷积
nn.AvgPool2d(kernel_size=2, stride=2), #池化
nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(), #卷积
nn.AvgPool2d(kernel_size=2, stride=2), #池化
nn.Flatten(), #展平
nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(), #全连接
nn.Linear(120, 84), nn.Sigmoid(),
nn.Linear(84, 10))
将这个神经网络的每一层的输出形状打印下来:
从上面的形状中我们可以看出,和上一层相比较来看,每一层特征的高度和宽度都减小了。
输入的 size=(1, 1, 28, 28)
第一个卷积层使用了padding=2来进行两个像素的填充补偿5 x 5卷积和导致的特征减少;第二个卷积层没有填充所以高度和宽度都减少了4个像素。
随着层叠上升,通道数量从1到6再到16,同时通过汇聚层池化后的高度和宽度都减半。
最后到了全连接层,每个全连接层减少维度,最终输出一个维度和结果分类相匹配的输出。
因为这里识别数字(类别0~9,一共十类)所以输出就是10个通道。
总结
为了构造高性能的卷积神经网络,我们通常对卷积层进行排列,逐渐降低其表示的空间和分辨率,同时增加通道数。
在传统的神经网络中,卷积块编码得到的表征在输出之前需由一个或者多个全连接层进行处理。
现代卷积神经网络
2012年,AlexNet的横空出世,首次正面了学习到的特征可以超越手工设计的特征。AlexNet使用了八层卷积神经网络(这里去除了当年需要两个小型GPU同时运算的特点)
AlexNet与LeNet对比
这两个网络的设计理念非常相似,但是AlexNet由八层组成(五个卷积层,两个全连接隐藏层和一个全连接输出层。
而且它使用费是的ReLU而不是sigmoid作为激活函数。
模型设计
第一层卷积层需要一个更大的卷积窗口来捕获目标,所以设计窗口的形状是11 x 11,然后在第二层中是5 x 5,然后后三层卷积层是3 x 3;除此之外,在第一、二、五层卷积层后面加上3 x 3最大步幅为2的最大汇聚层。
ReLU激活函数的设计也更加简单,不需要像sigmoid激活函数那般复杂的求幂运算。在另一方面,在使用不同的参数初始化方法的时候,ReLU激活函数会使训练模型更加容易。
import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
# 这里使用一个11*11的更大窗口来捕捉对象。
# 同时,步幅为4,以减少输出的高度和宽度。
# 另外,输出通道的数目远大于LeNet
nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 使用三个连续的卷积层和较小的卷积窗口。
# 除了最后的卷积层,输出通道的数量进一步增加。
# 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Flatten(),
# 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
nn.Linear(6400, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
# 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
nn.Linear(4096, 10))
AlexNet的每个层的形状输出:
总结
AlexNet使用了更多的卷积层和更多的参数来拟合大规模的数据集
它标志着浅层网络到深层网络的关键一步。这里面的暂退法、ReLU和预处理使提升计算机视觉任务性能的其他关键步骤。