残差神经网络ResNet学习,以ResNet18为例代码剖析
2020-01-14 18:46
4047 查看
1.首先导入需要使用的包
[code]import torch import torch.nn as nn import torch.nn.functional as F
我用的是pytorch,所以导入这三个。
2.定义的残差模块结构
残差块有两种设计方式,左边的是用于18,34层的,这样参数多,右面这种设计方式参数少,适用于更深度的
[code]class ResidualBlock(nn.Module): def __init__(self, inchannel, outchannel, stride): super(ResidualBlock, self).__init__() self.left = nn.Sequential( nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False), nn.BatchNorm2d(outchannel), nn.ReLU(inplace=True), nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False), nn.BatchNorm2d(outchannel) ) self.shortcut = nn.Sequential() if stride != 1 or inchannel != outchannel: self.shortcut = nn.Sequential( nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(outchannel) ) def forward(self, x): out = self.left(x) out += self.shortcut(x) out = F.relu(out) return out
这段代码包括三个部分,
(1)self.left 这段代码主要是定义左边包括两个卷积层,其顺序为Conv2d—>BatchNorm2d—>ReLU—>Conv2d—>BatchNorm2
(2)self.shortcut 这段代码有两种情况,如果是每层的第一个残差块,则对上一层残差块进行降维,降维方法是使用1*1的卷积核,设置步长为2*2,使其与self.left执行后的保持一致。如果不是每层的第一个残差块,则对上一层残差块的输出不做处理,
(2)forward 这段代码主要实现了前面两段的相加,这样一个残差块就定义结束,这也就是残差的精髓。
3、ResNet主体部分的实现
[code]class ResNet(nn.Module): def __init__(self, ResidualBlock, num_classes=10): super(ResNet, self).__init__() self.inchannel = 64 self.conv1 = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False), nn.BatchNorm2d(64), nn.ReLU(), ) self.layer1 = self.make_layer(ResidualBlock, 64, 2, stride=1) self.layer2 = self.make_layer(ResidualBlock, 128, 2, stride=2) self.layer3 = self.make_layer(ResidualBlock, 256, 2, stride=2) self.layer4 = self.make_layer(ResidualBlock, 512, 2, stride=2) self.fc = nn.Linear(512, num_classes) def make_layer(self, block, channels, num_blocks, stride): strides = [stride] + [1] * (num_blocks - 1) #strides=[1,1] print(strides) layers = [] for stride in strides: layers.append(block(self.inchannel, channels, stride)) self.inchannel = channels return nn.Sequential(*layers) def forward(self, x): out = self.conv1(x) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = self.layer4(out) out = F.avg_pool2d(out,4) out = out.view(out.size(0), -1) out = self.fc(out) return out
这段代码也分为4个部分,
(1)self.conv1,这里首先对输入图像进行一次卷机
(2)self.layer 这里定义4个大layer,每个layer包括两个残差块,这里定义的是ResNet18,所以每个层都是2,
上边的一起看成是五个阶段
(3)make_layer函数,首先判断步长,主要是由于每个层的残差块的第一个卷积层的步长不同,之后将layers中的所有残差块按顺序接在一起。
(4)forward函数,这个函数的作用是将每个layer连接起来。
4、定义ResNet18网络与查看网络模型
[code]def ResNet18(): return ResNet(ResidualBlock) if __name__=='__main__': model = ResNet18() print(model) input = torch.randn(1, 3, 32, 32) out = model(input) print(out.shape)
在分析残差网络的时候,打印出网络模型,更容易理解点。
下面是我画的一个ResNet18模型架构,我是在cifar-10上跑的,所以输入是32*32,输出是10
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 深度学习之神经网络结构——残差网络ResNet
- 深度学习——残差神经网络ResNet在分别在Keras和tensorflow框架下的应用案例
- 深度学习之经典神经网络框架详解(四):ResNet-v1残差神经网络
- Tensorflow学习:ResNet代码(详细剖析)-待补充,非最终版本
- 深度学习: ResNet (残差) 网络
- 人人都能用Python写出LSTM-RNN的代码![你的神经网络学习最佳起步]
- 残差网络resnet学习
- Deep Q-Network 学习笔记(二)—— Q-Learning与神经网络结合使用(有代码实现)
- 斯坦福大学深度学习公开课cs231n学习笔记(9)softmax分类和神经网络分类代码实现
- 【深度学习_4.2】Keras构建残差神经网络
- 《python深度学习》学习笔记与代码实现(第六章,6.2理解循环神经网络)
- mxnet,gluon学习笔记3——主干网络实现代码对比:AlexNet,VGG,NIN,googLeNet,ResNet,DesNet
- 深度学习源码剖析:使用双线性插值方式初始化神经网络的可训练参数
- 深度学习论文-神经网络的代码实现(python版本)
- 残差网络resnet学习
- 深度学习之Pytorch(一)神经网络基础及代码实现
- 求各位深度学习的大佬看看下面代码,为什么我的神经网络的测试集学习率总是在0.1左右?小白
- 人人都能用Python写出LSTM-RNN的代码![你的神经网络学习最佳起步]
- 深度学习笔记:ResNet(残差网络)
- 深度学习神经网络从欠拟合到拟合的调整方法及示例代码