VggNet简介
VGG是在2014年由牛津大学著名研究组VGG提出,战火概念ImageNet竞赛中LocalizationTask(定位任务)第一名和Classification Task(分类任务)第二名
关于神经网络中的一些自己还尚不能理解的一些关键步骤的解释
神经网络初始化权重的作用
初始化权重的作用是放置神经网络的正向(前向)传播过程中层激活函数的输出损失梯度出现爆炸或者小时,发生任何一种情况,损失梯度太大或者太小,就无法有效向后反传,即便可以向后反传,网络也需要花费更长的时间来达到收敛。这是十分重要的一部,虽然目前欠缺数学的基础知识,希望这个问题可以在以后的学习过程中得到解决。
对于深度学习代码tensor数据结构的理解
在很多的深度学习的代码中,我们经常见到将数组结构的数组转化为tensor格式的数据的操作
原因是:tensor数据类型是专门为GPU加速而设计的矩阵,而普通的数据结构不行,其实就可理解为是一个专门为GPU设计的数据结构,可以使模型的训练更加迅速。
VggNet网络的结构
感受野的定义
在卷积神经网络中,决定某一层输出结果中一个元素所对应的输入层的区域大小,被称作感受野,通俗来讲就是输出的feature map上的一个单元对应输出层上的区域大小
卷积层的基本的运算公式

- out为输出的神经元的大小
- in为输入神经元的大小
- F表示卷积核的大小
- P表示padding参数的大小
-
感受野的计算公式

F(i)表示第i层的感受野的大小
- Stride为第i层的步距的大小
- Ksize表示卷积核或池化核的大小
根据该公式可以推导出每一层的感受野的大小
在VGG网络中卷积核的默认的布局是1
使用多个卷积核的感受野的堆叠来代替一个大的感受野的参数,是为了减少网络的训练参数的个数
关于一些参数的作用效果的表示

根据改图可以很清除的看出来,在卷积层的stride和padding参数都设置为1的时候,输出的数据的大小是与原来输出的大小相一致的,深度为卷积核的数目大小
maxpooling最大下采样的层数的size和stride的参数均设置为2的时候的输出的数据的长和宽都会变成原来的一半,深度变为最大下采样层的采样核的大小
有利于初学者对于卷积层和最大下采样层的参数有更加详细的理解
关于VGG卷积神经网络的每一层
VGG网络结构搭建的代码展示
import torch.nn as nnimport torch# official pretrain weightsmodel_urls = {'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth','vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth','vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth','vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth'}#VGG类的定义class VGG(nn.Module):def __init__(self, features, num_classes=1000, init_weights=False):super(VGG, self).__init__()self.features = featuresself.classifier = nn.Sequential(nn.Linear(512*7*7, 4096),nn.ReLU(True),nn.Dropout(p=0.5),nn.Linear(4096, 4096),nn.ReLU(True),nn.Dropout(p=0.5),nn.Linear(4096, num_classes))if init_weights:self._initialize_weights()#定义数据的传播方向def forward(self, x):# N x 3 x 224 x 224x = self.features(x)# N x 512 x 7 x 7x = torch.flatten(x, start_dim=1)# N x 512*7*7x = self.classifier(x)return x#初始化权重函数def _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):# nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')nn.init.xavier_uniform_(m.weight)if m.bias is not None:nn.init.constant_(m.bias, 0)elif isinstance(m, nn.Linear):nn.init.xavier_uniform_(m.weight)# nn.init.normal_(m.weight, 0, 0.01)nn.init.constant_(m.bias, 0)#特征提取模块的函数的定义def make_features(cfg: list):layers = []in_channels = 3for v in cfg:if v == "M":layers += [nn.MaxPool2d(kernel_size=2, stride=2)]else:conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)layers += [conv2d, nn.ReLU(True)]in_channels = vreturn nn.Sequential(*layers)#特征提取模型的每一层的参数cfgs = {'vgg11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],'vgg13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],'vgg16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],'vgg19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],}#vgg模型的选择函数def vgg(model_name="vgg16", **kwargs):assert model_name in cfgs, "Warning: model number {} not in cfgs dict!".format(model_name)cfg = cfgs[model_name]model = VGG(make_features(cfg), **kwargs)return model
学习到现在,神经网络的每一层的每一个参数都至少见过和使用过两次了,都至少介绍过一次,已经对神经网络的基本构架有了不错的理解。
