本文主要是介绍秃姐学AI系列之:使用块的网络——VGG,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
VGG
VGG块
VGG架构
总结
模型演变进度
代码实现
QA
VGG
上文讲的 AlexNet 虽然证明了深层神经网络卓有成效,但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。
与芯片设计中工程师从放置晶体管到逻辑元件再到逻辑块的过程类似,神经网络架构的设计也逐渐变得更加抽象。研究人员开始从单个神经元的角度思考问题,发展到整个层,现在又转向块,重复层的模式。
- AlexNet 比 LeNet 更深更大得到更好的精度,有人就会想:能不能更大?更深?
- 就会出现以下三种选项:
- 更多的全连接层(代价太贵了)
- 更多的卷积层
- 将卷积层组合成块
VGG块
其实就是 AlexNet 思路的一个扩展
- 3 x 3卷积,padding = 1:n层,m通道(两个超参数,且输出通道都为m)
- 2 x 2最大池化层,stride = 2
核心思想就是用大量的VGG块来堆积成网络
为什么VGG使用3 x 3而不是5 x 5?
- 试过,因为5 x 5计算量变大了,所以需要网络浅一些
- 在同样计算开销的情况下,发现 深但窄 的网络效果更好,即堆更多的3 x 3Conv层
VGG架构
-
多个VGG块后接全连接层
-
不同次数的重复块得到不同的架构:VGG-16(3个全连接+13个卷积),VGG-19.....
相当于从 AlexNet 较 LeNet 后面新增的结构抽出来构造了块,顶替掉了前面四层不规则的结构
总结
-
VGG使用可复用的卷积块构造网络。不同的VGG模型可通过每个块中卷积层数量和输出通道数量的差异来定义。
-
块的使用导致网络定义的非常简洁。使用块可以得到不同复杂度的变种网络(之后很多网络都有 高配版 和 低配版)。
-
在VGG论文中,Simonyan 和 Ziserman 尝试了各种架构。特别是他们发现深层且窄的卷积(即3×3)比较浅层且宽的卷积更有效。
模型演变进度
-
LeNet(1995):2卷积 + 池化层 + 2全连接
-
AlexNet:更大更深LeNet + ReLU + Dropout + 数据增强
-
VGG:更大更深AlexNet(重复的VGG块)
代码实现
VGG块
import torch
from torch import nn
from d2l import torch as d2l# 卷积层的数量num_convs、输入通道的数量in_channels 和输出通道的数量out_channels
def vgg_block(num_convs, in_channels, out_channels):layers = []for _ in range(num_convs): # 下划线是忽略值,即不需要的值layers.append(nn.Conv2d(in_channels, out_channels,kernel_size=3, padding=1))layers.append(nn.ReLU())in_channels = out_channelslayers.append(nn.MaxPool2d(kernel_size=2,stride=2))return nn.Sequential(*layers) # 把这些层丢进Sequential里面,*layers是解包,可以理解成把列表layers里面的元素拿出来放在那。其中:*=》list;**=》dict
VGG网络:原始VGG网络有5个卷积块,其中前两个块各有一个卷积层,后三个块各包含两个卷积层。 第一个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。由于该网络使用8个卷积层和3个全连接层,因此它通常被称为VGG-11。
为啥是五层:因为224每次卷积数据量减少一半,最后第五层会得到7,是个奇数哈哈哈
PS:每一层卷积几乎都是:高宽减半,通道数翻倍,这个要记住,是个很经典的设计
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))def vgg(conv_arch):conv_blks = []in_channels = 1# 卷积层部分for (num_convs, out_channels) in conv_arch:conv_blks.append(vgg_block(num_convs, in_channels, out_channels))in_channels = out_channelsreturn nn.Sequential(*conv_blks, nn.Flatten(),# 全连接层部分nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 10))net = vgg(conv_arch)
老样子,观察每个层输出的形状
X = torch.randn(size=(1, 1, 224, 224))
for blk in net:X = blk(X)print(blk.__class__.__name__,'output shape:\t',X.shape)
QA
训练loss一直降,测试loss从开始起就一点不降,呈水平状是什么原因
①代码写错了
②已经过拟合了
这篇关于秃姐学AI系列之:使用块的网络——VGG的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!