东莞做门户网站,郑州最好的品牌策划公司,路由 拦截 网站开发,济南集团网站建设价格一. 残差块与残差层 简单来说#xff0c;残差块是构成残差层的基本单元#xff0c;而残差层则是由多个残差块组成的。在ResNet中#xff0c;通常会堆叠多个残差层来构建深度模型。
(一).残差块#xff08;Residual Block#xff09; 这是ResNet的基本构建单元。一个残差块…一. 残差块与残差层 简单来说残差块是构成残差层的基本单元而残差层则是由多个残差块组成的。在ResNet中通常会堆叠多个残差层来构建深度模型。
(一).残差块Residual Block 这是ResNet的基本构建单元。一个残差块通常包含两个或三个卷积层加上激活函数和批量归一化然后将这个卷积操作的输出与输入直接相加。这种设计可以帮助解决深度神经网络训练过程中的梯度消失问题。
class Bottleneck(nn.Module):#这个类实现了一个残差块Residual Block这是典型的ResNet的Bottleneck设计。expansion 4#表示输出特征图的通道数是输入特征图的通道数的4倍。def __init__(self, inplanes, planes, stride1, downsampleNone):super(Bottleneck, self).__init__()self.conv1 nn.Conv2d(inplanes, planes, kernel_size1, biasFalse)self.bn1 nn.BatchNorm2d(planes)self.conv2 nn.Conv2d(planes, planes, kernel_size3, stridestride,padding1, biasFalse)self.bn2 nn.BatchNorm2d(planes)self.conv3 nn.Conv2d(planes, planes * 4, kernel_size1, biasFalse)self.bn3 nn.BatchNorm2d(planes * 4)self.relu nn.ReLU(inplaceTrue)self.downsample downsampleself.stride stride#stride步长def forward(self, x):residual x#目的是保存输入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)if self.downsample is not None:residual self.downsample(x)out residualout self.relu(out)return out
在ResNet残差网络的设计中self.downsample通常是一个卷积层用于改变输入数据的维度例如改变通道数或者空间尺寸以便与主路径上卷积层的输出匹配。
如果self.downsample被定义了即self.downsample is not None那么输入数据x会通过self.downsample处理然后作为残差连接添加到主路径上卷积层的输出上。这样即使主路径上的卷积层改变了数据的维度也能保证残差连接的输入和输出的维度是匹配的从而可以进行相加。
(二).残差层Residual Layer 这是由多个残差块串联组成的。在一个残差层中输入数据首先通过一个残差块然后输出被用作下一个残差块的输入以此类推。每个残差层的输出通道数通常是固定的但是可以通过调整残差块中卷积层的滤波器数量来改变。 def _make_layer(self, block, planes, blocks, stride1):downsample Noneif stride ! 1 or self.inplanes ! planes * block.expansion:downsample nn.Sequential(nn.Conv2d(self.inplanes, planes * block.expansion,kernel_size1, stridestride, biasFalse),nn.BatchNorm2d(planes * block.expansion),)layers []layers.append(block(self.inplanes, planes, stride, downsample))self.inplanes planes * block.expansionfor i in range(1, blocks):layers.append(block(self.inplanes, planes))return nn.Sequential(*layers)在ResNet残差网络的设计中每个残差层Residual Layer由多个残差块Residual Block组成。在每个残差层中第一个残差块可能会改变输入的通道数和空间尺寸宽度和高度但是剩余的残差块都会保持通道数和空间尺寸不变。 在PyTorch中nn.Sequential 是一个容器模块它包含了一系列子模块这些子模块按照它们在构造函数中被传入的顺序进行排列。当 nn.Sequential 的 forward 方法被调用时这些子模块会按照它们的排列顺序依次执行。
二.加载预训练模型参数 def load_param(self, model_path):param_dict torch.load(model_path)for i in param_dict:if fc in i:continueself.state_dict()[i].copy_(param_dict[i]) param_dict torch.load(model_path)使用 PyTorch 的 torch.load() 函数从指定的文件中加载模型参数。这些参数被保存在一个字典中字典的键是参数的名称值是参数的值。 for i in param_dict:遍历加载的参数字典。 if fc in i: continue如果当前参数的名称中包含 fc则跳过这个参数。这通常用于在加载参数时跳过全连接层Fully Connected layer简称fc的参数。 self.state_dict()[i].copy_(param_dict[i])将加载的参数复制到当前模型的对应参数中。self.state_dict() 是获取当前模型的参数字典[i] 是获取对应的参数copy_ 函数是将加载的参数复制到当前参数中。