ResNet的pytorch实现与解析

您所在的位置:网站首页 网络class是什么意思 ResNet的pytorch实现与解析

ResNet的pytorch实现与解析

2024-07-17 11:10| 来源: 网络整理| 查看: 265

恒等快,若x和H(x)的维度相等 在这里插入图片描述 恒等快,若x和H(x)的维度不相等,需要将x卷积bn,relu在送入H(x) 在这里插入图片描述

自适应池化操作

在这里插入图片描述 inplanes 是提供给block的通道数,planes表示block的输出通道。大家知道,在做残差相加的时候,我们必须保证残差的维度与真正输出的维度相等(注意这里维度是宽高以及深度)这样我们才能把它们堆到一起,所以程序中出现了降采样操作。

if stride != 1 or self.inplanes != planes * block.expansion:大家注意到这个if语句,它存在两种条件使他为真。第一就是stride != 1,我们以下图为例,输入56×56×256输出为28×28×512,显然stride=2(resnet没有pooling)这时我们满足第一个条件,所以进入降采样操作,令stride=2,这样我的残差输出就变成了28×28。

再看第二个条件 self.inplanes != planes * block.expansion,这是self.inplanes=256,而planes =512(这里因为basic block,block.expansion=1),所以第二个条件满足,那么进行降采样用1×1卷积改变通道数。

总之,这个步骤就是为了匹配维度。 在这里插入图片描述 resnet结构如图 在这里插入图片描述 pytorch代码如下`

# -*- coding: utf-8 -*- # @Time : 2020/11/24 18:05 # @Author : Refrain_ouc # @FileName: resnet_ouc.py # @Software: PyCharm import torch import torch.nn as nn import torch.nn.functional as F class BasicBlock(nn.Module): expansion =1 def __init__(self,in_planes,planes,stride=1): self.conv1=nn.Sequential( nn.Conv2d(in_planes,planes,kernel_size=3,stride=stride,padding=1), nn.BatchNorm2d(planes), nn.ReLU(True) ) self.conv2=nn.Sequential( nn.Conv2d(planes,planes*self.expansion,kernel_size=3,stride=1,padding=1), nn.BatchNorm2d(planes*self.expansion), ) self.shortcut=nn.Sequential() if stride!=1 or in_planes!=planes*self.expansion: self.shortcut=nn.Sequential( nn.Conv2d(in_planes,planes*self.expansion,kernel_size=1,stride=stride), nn.BatchNorm2d(planes*self.expansion) ) def forward(self,input): output=self.conv1(input) output=self.conv2(output) output=output+self.shortcut output=F.relu(output) return output class BottleBolck(nn.Module): expansion=4 def __init__(self,in_planes,planes,stride=1): self.conv1=nn.Sequential( nn.Conv2d(in_planes,planes,kernel_size=1,stride=stride), nn.BatchNorm2d(planes), nn.ReLU(True) ) self.conv2=nn.Sequential( nn.Conv2d(planes,planes,kernel_size=3,stride=1,padding=1), nn.BatchNorm2d(planes), nn.ReLU(True) ) self.conv3=nn.Sequential( nn.Conv2d(planes,planes*self.expansion,kernel_size=1,stride=1), nn.BatchNorm2d(planes*self.expansion) ) self.shortcut=nn.Sequential() if stride!=1 or in_planes!=planes*self.expansion: self.shortcut=nn.Sequential( nn.Conv2d(in_planes,planes*self.expansion,kernel_size=1,stride=1), nn.BatchNorm2d(planes*self.expansion) ) def forward(self,input): output=self.conv1(input) output=self.conv2(output) output=self.conv3(output) output=output+self.shortcut output=F.relu((output)) return output class Resnet(nn.Module): def __init__(self,block,num_layer,num_class=10): self.in_planes=64 self.conv=nn.Sequential( nn.Conv2d(3,64,kernel_size=7,stride=2,padding=3), nn.BatchNorm2d(64), nn.ReLU(True), nn.MaxPool2d(kernel_size=3,stride=2,padding=1), ) self.conv1=self.make_layer(block=block,planes=64,num_layer=num_layer[0],stride=1) self.conv2=self.make_layer(block=block,planes=128,num_layer=num_layer[1],stride=2) self.conv3=self.make_layer(block=block,planes=256,num_layer=num_layer[2],stride=2) self.conv4=self.make_layer(block=block,planes=512,num_layer=num_layer[3],stride=2) self.aver_pool=nn.AdaptiveAvgPool2d((1,1)) self.linera=nn.Linear(512*block.expansion,num_class) def forward(self,x): output=self.conv(x) output=self.conv1(output) output=self.conv2(output) output=self.conv3(output) output=self.conv4(output) output=self.aver_pool(output) #output.size(channel,h,w) output=output.view(output.size(0),-1) output=self.linera(output) return output def make_layer(self,block,planes,num_layer,stride): layer=[] strides=[stride]+[1]*(num_layer-1) for stride in strides: layer.append(block(self.in_planes,planes,stride)) self.in_plances=planes*block.expansion return nn.Sequential(*layer)


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3