- ResNet50
- Vgg16
- ———————————————————#
self.classifier = nn.Sequential(
nn.Linear(512 7 7, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, num_classes),
)
if init_weights:
self._initialize_weights() - ———————————————————#
特征提取部分
#———————————————————#
def make_layers(cfg, batch_norm=False):
layers = []
in_channels = 3
for 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)
if batch_norm:
layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
else:
layers += [conv2d, nn.ReLU(inplace=True)]
in_channels = v
return nn.Sequential(*layers)
ResNet50
Bottleneck layer瓶颈层

有bottleneck(右)和没有bottleneck的ResNet模块(左)
nn.Conv2d
inplanes: 输入数据的通道数,例RGB图片通道数为3;
planes: 输出数据的通道数,这个根据模型调整;
kennel_size: 卷积核大小,可以是int,或tuple;kennel_size=1,意味着卷积大小, kennel_size=(2,3),意味着卷积在第一维度大小为2,在第二维度大小为3;
stride:步长,默认为1,与kennel_size类似,stride=2,意味在所有维度步长为2, stride=(2,3),意味着在第一维度步长为2,意味着在第二维度步长为3;
padding填充
nn.BatchNorm2d()
转载处/详情查看https://blog.csdn.net/bigFatCat_Tom/article/details/91619977
数学原理

BatchNorm2d()内部的参数如下
1.num_features:一般输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量
2.eps:分母中添加的一个值,目的是为了计算的稳定性,默认为:1e-5
3.momentum:一个用于运行过程中均值和方差的一个估计参数(我的理解是一个稳定系数,类似于SGD中的momentum的系数)
4.affine:当设为true时,会给定可以学习的系数矩阵gamma和beta
nn.ReLU
激活函数
继续向下看,定义该神经网络的向前传播函数
这一部分好像没啥说的
ResNet(nn.Module):

nn.MaxPool2d(池化)
转载于
作者:乔大叶_803e
链接:https://www.jianshu.com/p/9d93a3391159
来源:简书
- kernel_size(int or tuple) - max pooling的窗口大小,
- stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
- padding(int or tuple, optional) - 输入的每一条边补充0的层数
- dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
- return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
- ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
nn.Linear(全连接)

对于每个layer而言,每经过一个block之后,通道数变为了4_planes,因此下一个block的输入通道数应为4_planes,故定义self.inplanes = planes * block.expansion。planes不变,总是为传入的参数,如64,128,256,512。变得是每次经过一个block之后的输出通道数,也就意味着下一个block的输入通道数变了。

调用ResNet
Vgg16
![1365470-20190307201654594-510842148[1].png](https://cdn.nlark.com/yuque/0/2020/png/1915285/1597760593581-df596821-7a27-419c-818f-d6bdaae822ff.png#align=left&display=inline&height=755&margin=%5Bobject%20Object%5D&name=1365470-20190307201654594-510842148%5B1%5D.png&originHeight=2124&originWidth=588&size=118910&status=done&style=none&width=209)
import torch
import torch.nn as nn
cfg = [64, 64, ‘M’, 128, 128, ‘M’, 256, 256, 256, ‘M’, 512, 512, 512, ‘M’, 512, 512, 512, ‘M’]
#———————————————————#
VGG16的结构
#———————————————————#
class VGG(nn.Module):
def init(self, features, num_classes=1000, init_weights=True):
super(VGG, self).init()
self.features = features
平均池化到7x7大小
self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
#———————————————————#
分类部分
———————————————————#
self.classifier = nn.Sequential(
nn.Linear(512 7 7, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, num_classes),
)
if init_weights:
self._initialize_weights()
def forward(self, x):# 特征提取x = self.features(x)# 平均池化x = self.avgpool(x)# 平铺后x = torch.flatten(x, 1)# 分类部分x = self.classifier(x)return xdef _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')if m.bias is not None:nn.init.constant_(m.bias, 0)elif isinstance(m, nn.BatchNorm2d):nn.init.constant_(m.weight, 1)nn.init.constant_(m.bias, 0)elif isinstance(m, nn.Linear):nn.init.normal_(m.weight, 0, 0.01)nn.init.constant_(m.bias, 0)
———————————————————#
特征提取部分
#———————————————————#
def make_layers(cfg, batch_norm=False):
layers = []
in_channels = 3
for 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)
if batch_norm:
layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
else:
layers += [conv2d, nn.ReLU(inplace=True)]
in_channels = v
return nn.Sequential(*layers)
def decom_vgg16():
model = VGG(make_layers(cfg))
# 获取特征提取部分
features = list(model.features)[:30]
# 获取分类部分
classifier = model.classifier
classifier = list(classifier)
# 除去Dropout部分
del classifier[6]
del classifier[5]
del classifier[2]
features = nn.Sequential(features)
classifier = nn.Sequential(classifier)
# print(classifier)
return features,classifier
