# 定义ResNet50/101/152的残差结构,为1x1+3x3+1x1的卷积
class Bottleneck(nn.Module):
# expansion是指在每个小残差块内,减小尺度增加维度的倍数,如64*4=256
# Bottleneck层输出通道是输入的4倍
expansion = 4
# init():进行初始化,申明模型中各层的定义
# downsample=None对应实线残差结构,否则为虚线残差结构,专门用来改变x的通道数
def __init__(self, in_channel, out_channel, stride=1, downsample=None,
groups=1, width_per_group=64):
super(Bottleneck, self).__init__()
width = int(out_channel * (width_per_group / 64.)) * groups
self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=width,
kernel_size=1, stride=1, bias=False)
# 使用批量归一化
self.bn1 = nn.BatchNorm2d(width)
self.conv2 = nn.Conv2d(in_channels=width,out_channels=width, groups=groups,kernel_size=3, stride=stride, bias=False, padding=1)
self.bn2 = nn.BatchNorm2d(width)
self.conv3 = nn.Conv2d(in_channels=width, out_channels=out_channel * self.expansion,kernel_size=1, stride=1, bias=False)
self.bn3 = nn.BatchNorm2d(out_channel * self.expansion
# 使用ReLU作为激活函数
self.relu = nn.ReLU(inplace=True)
self.downsample = downsample
# forward():定义前向传播过程,描述了各层之间的连接关系
def forward(self, x):
# 残差块保留原始输入
identity = x
# 如果是虚线残差结构,则进行下采样
if self.downsample is not None:
identity = self.downsample(x)
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
# 主分支与shortcut分支数据相加
out += identity
out = self.relu(out)
return out
【无标题】
最新推荐文章于 2024-07-09 20:15:48 发布