make_res_layer方法

该篇文章详细介绍了如何使用Python构建ResNet3D模型中的残差层,包括参数解释、功能实现和下采样的条件判断。主要涉及模块、通道数、步长、膨胀选项以及规范化和激活配置。
摘要由CSDN通过智能技术生成
  @staticmethod
    def make_res_layer(block,
                       inplanes,
                       planes,
                       blocks,
                       stride=(1, 1),
                       inflate=1,
                       inflate_style='3x1x1',
                       advanced=False,
                       norm_cfg=None,
                       act_cfg=None,
                       conv_cfg=None):
        """Build residual layer for ResNet3D.

        Args:
            block (nn.Module): Residual module to be built.
            inplanes (int): Number of channels for the input feature in each block.
            planes (int): Number of channels for the output feature in each block.
            blocks (int): Number of residual blocks.
            stride (tuple[int]): Stride (temporal, spatial) in residual and conv layers. Default: (1, 1).
            inflate (int | tuple[int]): Determine whether to inflate for each block. Default: 1.
            inflate_style (str): '3x1x1' or '3x3x3'. which determines the kernel sizes and padding strides
                for conv1 and conv2 in each block. Default: '3x1x1'.
            conv_cfg (dict | None): Config for norm layers. Default: None.
            norm_cfg (dict | None): Config for norm layers. Default: None.
            act_cfg (dict | None): Config for activate layers. Default: None.

        Returns:
            nn.Module: A residual layer for the given config.
        """
        inflate = inflate if not isinstance(inflate, int) else (inflate, ) * blocks
        assert len(inflate) == blocks
        downsample = None
        if stride[1] != 1 or inplanes != planes * block.expansion:
            if advanced:
                conv = ConvModule(
                    inplanes,
                    planes * block.expansion,
                    kernel_size=1,
                    stride=1,
                    bias=False,
                    conv_cfg=conv_cfg,
                    norm_cfg=norm_cfg,
                    act_cfg=None)
                pool = nn.AvgPool3d(
                    kernel_size=(stride[0], stride[1], stride[1]),
                    stride=(stride[0], stride[1], stride[1]),
                    ceil_mode=True)
                downsample = nn.Sequential(conv, pool)
            else:
                downsample = ConvModule(
                    inplanes,
                    planes * block.expansion,
                    kernel_size=1,
                    stride=(stride[0], stride[1], stride[1]),
                    bias=False,
                    conv_cfg=conv_cfg,
                    norm_cfg=norm_cfg,
                    act_cfg=None)

        layers = []
        layers.append(
            block(
                inplanes,
                planes,
                stride=stride,
                downsample=downsample,
                inflate=(inflate[0] == 1),
                inflate_style=inflate_style,
                norm_cfg=norm_cfg,
                conv_cfg=conv_cfg,
                act_cfg=act_cfg))
        inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(
                block(
                    inplanes,
                    planes,
                    stride=(1, 1),
                    inflate=(inflate[i] == 1),
                    inflate_style=inflate_style,
                    norm_cfg=norm_cfg,
                    conv_cfg=conv_cfg,
                    act_cfg=act_cfg))

        return nn.Sequential(*layers)

  def make_res_layer(block,
                       inplanes,
                       planes,
                       blocks,
                       stride=(1, 1),
                       inflate=1,
                       inflate_style='3x1x1',
                       advanced=False,
                       norm_cfg=None,
                       act_cfg=None,
                       conv_cfg=None):
        """Build residual layer for ResNet3D.

        Args:
            block (nn.Module): Residual module to be built.
            inplanes (int): Number of channels for the input feature in each block.
            planes (int): Number of channels for the output feature in each block.
            blocks (int): Number of residual blocks.
            stride (tuple[int]): Stride (temporal, spatial) in residual and conv layers. Default: (1, 1).
            inflate (int | tuple[int]): Determine whether to inflate for each block. Default: 1.
            inflate_style (str): '3x1x1' or '3x3x3'. which determines the kernel sizes and padding strides
                for conv1 and conv2 in each block. Default: '3x1x1'.
            conv_cfg (dict | None): Config for norm layers. Default: None.
            norm_cfg (dict | None): Config for norm layers. Default: None.
            act_cfg (dict | None): Config for activate layers. Default: None.

        Returns:
            nn.Module: A residual layer for the given config.
        """

这段代码定义了一个名为 make_res_layer 的函数,用于建立 ResNet3D 模型的残差层。下面是函数参数的中文解释:

  1. block (nn.Module): 要构建的残差模块。
  2. inplanes (int): 每个块的输入特征通道数。
  3. planes (int): 每个块的输出特征通道数。
  4. blocks (int): 残差块的数量。
  5. stride (tuple[int]): 残差层和卷积层的步长(时间维度,空间维度)。默认为 (1, 1)。
  6. inflate (int | tuple[int]): 决定是否在每个块中进行膨胀。默认为 1。
  7. inflate_style (str): '3x1x1' 或 '3x3x3',决定了每个块中 conv1 和 conv2 的核大小和填充步长。默认为 '3x1x1'。
  8. conv_cfg (dict | None): 卷积层配置,默认为 None。
  9. norm_cfg (dict | None): 归一化层配置,默认为 None。
  10. act_cfg (dict | None): 激活层配置,默认为 None。

这个函数会返回一个包含指定残差层配置的 PyTorch 模块。

        inflate = inflate if not isinstance(inflate, int) else (inflate, ) * blocks
        assert len(inflate) == blocks
        downsample = None
        if stride[1] != 1 or inplanes != planes * block.expansion:
            if advanced:
                conv = ConvModule(
                    inplanes,
                    planes * block.expansion,
                    kernel_size=1,
                    stride=1,
                    bias=False,
                    conv_cfg=conv_cfg,
                    norm_cfg=norm_cfg,
                    act_cfg=None)
                pool = nn.AvgPool3d(
                    kernel_size=(stride[0], stride[1], stride[1]),
                    stride=(stride[0], stride[1], stride[1]),
                    ceil_mode=True)
                downsample = nn.Sequential(conv, pool)
            else:
                downsample = ConvModule(
                    inplanes,
                    planes * block.expansion,
                    kernel_size=1,
                    stride=(stride[0], stride[1], stride[1]),
                    bias=False,
                    conv_cfg=conv_cfg,
                    norm_cfg=norm_cfg,
                    act_cfg=None)

这段代码中的每一行解释如下:

  1. inflate = inflate if not isinstance(inflate, int) else (inflate, ) * blocks

    • 如果 inflate 不是一个整数,那么保持原值;否则将其转换为一个元组,并将其重复 blocks 次。
  2. assert len(inflate) == blocks

    • 断言 inflate 的长度与 blocks 的值相等。
  3. downsample = None

    • 初始化 downsample 为 None
  4. if stride[1] != 1 or inplanes != planes * block.expansion:

    • 如果空间维度的步长不为 1,或者输入通道数与输出通道数 (planes * block.expansion) 不匹配,则执行以下操作。
  5. if advanced:

    • 如果 advanced 为 True,则使用更复杂的下采样方式。
  6. conv = ConvModule(inplanes, planes * block.expansion, kernel_size=1, stride=1, bias=False, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=None)

    • 创建一个 1x1 卷积层,用于调整通道数。
  7. pool = nn.AvgPool3d(kernel_size=(stride[0], stride[1], stride[1]), stride=(stride[0], stride[1], stride[1]), ceil_mode=True)

    • 创建一个平均池化层,用于执行下采样。
  8. downsample = nn.Sequential(conv, pool)

    • 将卷积层和池化层组合成一个 downsample 模块。
  9. else:

    • 如果 advanced 为 False,则使用更简单的下采样方式。
  10. downsample = ConvModule(inplanes, planes * block.expansion, kernel_size=1, stride=(stride[0], stride[1], stride[1]), bias=False, conv_cfg=conv_cfg, norm_cfg=norm_cfg, act_cfg=None)

    • 创建一个 1x1 卷积层,用于执行下采样。

总的来说,这段代码确定了是否需要下采样,并根据 advanced 标志选择不同的下采样方式。

        layers = []
        layers.append(
            block(
                inplanes,
                planes,
                stride=stride,
                downsample=downsample,
                inflate=(inflate[0] == 1),
                inflate_style=inflate_style,
                norm_cfg=norm_cfg,
                conv_cfg=conv_cfg,
                act_cfg=act_cfg))
        inplanes = planes * block.expansion

这段代码继续实现 make_res_layer 函数的功能。下面是每一行的解释:

  1. layers = []

    • 初始化一个空的列表 layers
  2. layers.append()

    • 向 layers 列表中添加一个元素。
  3. block(inplanes, planes, stride=stride, downsample=downsample, inflate=(inflate[0] == 1), inflate_style=inflate_style, norm_cfg=norm_cfg, conv_cfg=conv_cfg, act_cfg=act_cfg)

    • 创建一个 block 模块实例,并传入以下参数:
      • inplanes: 输入通道数
      • planes: 输出通道数
      • stride: 步长
      • downsample: 下采样模块
      • inflate: 是否膨胀,取决于 inflate[0] 的值
      • inflate_style: 膨胀的样式
      • norm_cfg: 归一化层配置
      • conv_cfg: 卷积层配置
      • act_cfg: 激活层配置
  4. inplanes = planes * block.expansion

    • 更新 inplanes 的值为 planes * block.expansion。这是因为每个残差块的输出通道数是 planes * block.expansion

通过这段代码,我们创建了一个包含一个残差块的列表 layers,并更新了 inplanes 的值,为下一个残差块的创建做好准备。

  for i in range(1, blocks):
            layers.append(
                block(
                    inplanes,
                    planes,
                    stride=(1, 1),
                    inflate=(inflate[i] == 1),
                    inflate_style=inflate_style,
                    norm_cfg=norm_cfg,
                    conv_cfg=conv_cfg,
                    act_cfg=act_cfg))

        return nn.Sequential(*layers)

这段代码继续实现 make_res_layer 函数的功能。下面是每一行的中文解释:

  1. for i in range(1, blocks):

    • 从 1 开始,循环 blocks-1 次。这是因为第 0 个块已经在前面创建了。
  2. layers.append()

    • 向 layers 列表中添加一个元素。
  3. block(inplanes, planes, stride=(1, 1), inflate=(inflate[i] == 1), inflate_style=inflate_style, norm_cfg=norm_cfg, conv_cfg=conv_cfg, act_cfg=act_cfg)

    • 创建一个 block 模块实例,并传入以下参数:
      • inplanes: 输入通道数
      • planes: 输出通道数
      • stride: 步长设为 (1, 1)
      • inflate: 是否膨胀,取决于 inflate[i] 的值
      • inflate_style: 膨胀的样式
      • norm_cfg: 归一化层配置
      • conv_cfg: 卷积层配置
      • act_cfg: 激活层配置
  4. return nn.Sequential(*layers)

    • 将 layers 列表中的所有元素组装成一个 PyTorch 的 nn.Sequential 模块,并返回。

通过这段代码,我们创建了剩余的 blocks-1 个残差块,并将它们组装成一个 nn.Sequential 模块返回。这就完成了 make_res_layer 函数的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值