使用重复元素的网络(VGG)

VGG的名字来源于论文作者所在的实验室Visual Geometry Group,VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路。

VGG Block(VGG 块)

VGG块的组成规律是:连续使用数个相同的填充为1、窗口形状为3×33\times 33×3的卷积层后接上一个步幅为2、窗口形状为2×22\times 22×2的最大池化层。
卷积层保持输入的高和宽不变,而池化层则对其减半。

用函数来实现基础的VGG块,它可以指定卷积层的数量和输入输出通道数。

import time
import torch
from torch import nn, optimdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')def vgg_block(num_convs, in_channels, out_channels):blk = []for i in range(num_convs):if i == 0:blk.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1))else:blk.append(nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1))blk.append(nn.ReLU())blk.append(nn.MaxPool2d(kernel_size=2, stride=2)) # 这里会使宽高减半return nn.Sequential(*blk)

对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核优于采用大的卷积核,因为可以增加网络深度来保证学习更复杂的模式,而且代价还比较小(参数更少)。例如,在VGG中,使用了3个3x3卷积核来代替7x7卷积核,使用了2个3x3卷积核来代替5*5卷积核,这样做的主要目的是在保证具有相同感知野的条件下,提升了网络的深度,在一定程度上提升了神经网络的效果。

VGG 网络

VGG网络由卷积层模块后接全连接层模块构成。卷积层模块串联数个VGG Block,其超参数由变量conv_arch定义。该变量指定了每个VGG块里卷积层个数和输入输出通道数。全连接模块则跟AlexNet中的一样。
构造一个VGG网络。

  • 它有5个卷积块,前2块使用单卷积层,而后3块使用双卷积层。
  • 第一块的输入输出通道分别是1和64
  • 之后每次对输出通道数翻倍,直到变为512

因为这个网络使用了8个卷积层和3个全连接层,所以经常被称为VGG-11。

conv_arch = ((1, 1, 64), (1, 64, 128), (2, 128, 256), (2, 256, 512), (2, 512, 512))
# 经过5个VGG Block, 宽高会减半5次, 变成 224/32 = 7
fc_features = 512 * 7 * 7 # c * w * h
fc_hidden_units = 4096 # 任意设定

实现VGG-11

def vgg(conv_arch, fc_features, fc_hidden_units=4096):net = nn.Sequential()# 卷积层部分for i, (num_convs, in_channels, out_channels) in enumerate(conv_arch):# 每经过一个vgg_block都会使宽高减半net.add_module("vgg_block_" + str(i+1), vgg_block(num_convs, in_channels, out_channels))# 全连接层部分net.add_module("fc", nn.Sequential(d2l.FlattenLayer(),nn.Linear(fc_features, fc_hidden_units),nn.ReLU(),nn.Dropout(0.5),nn.Linear(fc_hidden_units, fc_hidden_units),nn.ReLU(),nn.Dropout(0.5),nn.Linear(fc_hidden_units, 10)))return net

构造一个高和宽均为224的单通道数据样本来观察每一层的输出形状。

net = vgg(conv_arch, fc_features, fc_hidden_units)
X = torch.rand(1, 1, 224, 224)# named_children获取一级子模块及其名字(named_modules会返回所有子模块,包括子模块的子模块)
for name, blk in net.named_children(): X = blk(X)print(name, 'output shape: ', X.shape)

输出:

vgg_block_1 output shape:  torch.Size([1, 64, 112, 112])
vgg_block_2 output shape:  torch.Size([1, 128, 56, 56])
vgg_block_3 output shape:  torch.Size([1, 256, 28, 28])
vgg_block_4 output shape:  torch.Size([1, 512, 14, 14])
vgg_block_5 output shape:  torch.Size([1, 512, 7, 7])
fc output shape:  torch.Size([1, 10])

每次输入的高和宽减半,直到最终高和宽变成7后传入全连接层。与此同时,输出通道数每次翻倍,直到变成512。因为每个卷积层的窗口大小一样,所以每层的模型参数尺寸和计算复杂度与输入高、输入宽、输入通道数和输出通道数的乘积成正比。VGG这种高和宽减半以及通道翻倍的设计使得多数卷积层都有相同的模型参数尺寸和计算复杂度

获取数据

ratio = 8
small_conv_arch = [(1, 1, 64//ratio), (1, 64//ratio, 128//ratio), (2, 128//ratio, 256//ratio), (2, 256//ratio, 512//ratio), (2, 512//ratio, 512//ratio)]
net = vgg(small_conv_arch, fc_features // ratio, fc_hidden_units // ratio)
print(net)

输出:

Sequential((vgg_block_1): Sequential((0): Conv2d(1, 8, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU()(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(vgg_block_2): Sequential((0): Conv2d(8, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU()(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(vgg_block_3): Sequential((0): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU()(2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(3): ReLU()(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(vgg_block_4): Sequential((0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU()(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(3): ReLU()(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(vgg_block_5): Sequential((0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU()(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(3): ReLU()(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(fc): Sequential((0): FlattenLayer()(1): Linear(in_features=3136, out_features=512, bias=True)(2): ReLU()(3): Dropout(p=0.5)(4): Linear(in_features=512, out_features=512, bias=True)(5): ReLU()(6): Dropout(p=0.5)(7): Linear(in_features=512, out_features=10, bias=True))
)

训练:

def load_data_fashion_mnist(batch_size, resize=None, root='~/Datasets/FashionMNIST'):"""Download the fashion mnist dataset and then load into memory."""trans = []if resize:trans.append(torchvision.transforms.Resize(size=resize))trans.append(torchvision.transforms.ToTensor())transform = torchvision.transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=True, transform=transform)mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=True, transform=transform)if sys.platform.startswith('win'):num_workers = 0  # 0表示不用额外的进程来加速读取数据else:num_workers = 4train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)return train_iter, test_iter
batch_size = 64
# 如出现“out of memory”的报错信息,可减小batch_size或resize
train_iter, test_iter = load_data_fashion_mnist(batch_size, resize=224)lr, num_epochs = 0.001, 5
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)

(pytorch-深度学习系列)使用重复元素的网络(VGG)相关推荐

  1. 卷积神经网络之(使用重复元素的网络)VGG

    卷积神经网络之VGG VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路. VGG模型 VGG块的组成规律是: 连续使用数个相同的填充为1,.窗口形状为3*3的卷积层 后接一个步幅为2.窗口 ...

  2. [pytorch、学习] - 5.7 使用重复元素的网络(VGG)

    参考 5.7 使用重复元素的网络(VGG) AlexNet在LeNet的基础上增加了3个卷积层.但AlexNet作者对它们的卷积窗口.输出通道数和构造顺序均做了大量的调整.虽然AlexNet指明了深度 ...

  3. Pytorch深度学习实战教程:UNet语义分割网络

    1 前言 本文属于Pytorch深度学习语义分割系列教程. 该系列文章的内容有: Pytorch的基本使用 语义分割算法讲解 本文的开发环境如下: 开发环境:Windows 开发语言:Python3. ...

  4. PyTorch 深度学习实践 第13讲

    PyTorch 深度学习实践 第13讲 引言 代码 结果 引言 近期学习了B站 刘二大人的PyTorch深度学习实践,传送门PyTorch 深度学习实践--循环神经网络(高级篇),感觉受益匪浅,发现网 ...

  5. 《PyTorch深度学习实践》

    [<PyTorch深度学习实践>完结合集] https://www.bilibili.com/video/BV1Y7411d7Ys/?share_source=copy_web&v ...

  6. PyTorch实现 | 车牌OCR识别,《PyTorch深度学习之目标检测》

    注:本文选自中国水利水电出版社出版<PyTorch深度学习之目标检测>一书,有改动 福利!免费寄送图书!! 公众号[机器学习与AI生成创作]后台回复:168.即可参与免费寄送图书活动,活动 ...

  7. PyTorch深度学习笔记之四(深度学习的基本原理)

    本文探讨深度学习的基本原理.取材于<PyTorch深度学习实战>一书的第5章.也融入了一些自己的内容. 1. 深度学习基本原理初探 1.1 关于深度学习的过程的概述 给定输入数据和期望的输 ...

  8. Pytorch 深度学习实战教程(二):UNet语义分割网络

    本文 GitHub https://github.com/Jack-Cherish/PythonPark 已收录,有技术干货文章,整理的学习资料,一线大厂面试经验分享等,欢迎 Star 和 完善. 一 ...

  9. Pytorch深度学习实战教程(二):UNet语义分割网络

    1 前言 本文属于Pytorch深度学习语义分割系列教程. 该系列文章的内容有: Pytorch的基本使用 语义分割算法讲解 如果不了解语义分割原理以及开发环境的搭建,请看该系列教程的上一篇文章< ...

最新文章

  1. 一文讲清楚什么是迁移学习?以及它都用在哪些深度学习场景?
  2. CentOS 7 yum源安装Nginx
  3. Linux常用系统管理命令(top、free、kill、df)
  4. 你知道吗…我不知道…你知道吗
  5. 说说那些死于决斗的大牛
  6. linux的 dev vdal,RAZVOJ DELA NA DALJAVO V SLOVENIJI
  7. 有关emoji表情以及utf-16编码
  8. 研磨数据结构与算法-03栈与队列
  9. Spring概况(一)
  10. VS2017编译Detours1.5
  11. [分块]Most Influential Pumpkin
  12. 冰刃-删除顽固文件的利器!
  13. 应用pagehelper实现大屏展示自动换页
  14. 神经网络性能评价指标
  15. 计算机安装重装出现错误,如何解决重装系统失败无法开机进入系统的问题
  16. Ubuntu 安装MySQL 并设置其他主机可访问
  17. vs code + mingw64配置C语言环境
  18. 高清无线投影服务器,投影+高清+无线 教你轻松玩转家庭影院
  19. 看图说话:从图片到文字
  20. 去图片水印软件有哪些?安利这几个实用的工具给你们

热门文章

  1. php xampp bug,PHP网站访问慢的处理方法
  2. 非对称加密算法 --- RSA签名算法
  3. 最新软件工程总结,项目模板,软工作业下载
  4. php分区表,【MYSQL】分区表
  5. python数据可视化的特点_6 种 Python 数据可视化工具
  6. 交叉线和直通线各自用于什么场合?为什么?_【小麓讲堂】偏振光与LCD、OLED、3D、AR到底有什么关系?...
  7. 经常被问到的十个 Java 面试题?你Get了吗?
  8. 微软私有云解决方案_微软发布电信云平台 ,互联网巨头争夺5G网络商机
  9. opcua 入门简介 java_大二的学生自学Java有出路吗?
  10. 【LeetCode笔记】98. 验证二叉搜索树(Java、dfs、中序遍历、二叉树)