【问题标题】:How downsample work in ResNet in pytorch code?pytorch 代码中 ResNet 中的下采样如何工作?
【发布时间】:2019-09-05 09:41:37
【问题描述】:

在这个 pytorch ResNet 代码示例中,他们在第 44 行将下采样定义为变量。第 58 行将其用作函数。作为 CNN 的观点和 python 代码的观点,这个下采样在这里是如何工作的。

代码示例:pytorch ResNet

我搜索了下采样是否是任何 pytorch 内置函数。但事实并非如此。

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, norm_layer=None):
        super(BasicBlock, self).__init__()
        if norm_layer is None:
            norm_layer = nn.BatchNorm2d
        if groups != 1:
            raise ValueError('BasicBlock only supports groups=1')
        # Both self.conv1 and self.downsample layers downsample the input when stride != 1
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = norm_layer(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = norm_layer(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

return out

【问题讨论】:

    标签: deep-learning conv-neural-network pytorch torchvision


    【解决方案1】:

    如果您查看原始 ResNet 论文 (http://openaccess.thecvf.com/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf),他们会使用跨步卷积对图像进行下采样。正如您在代码中所做的那样,使用这些跨步卷积自动对主路径进行下采样。残差路径使用 (a) 添加零条目以不添加额外参数的恒等映射或 (b) 具有相同步幅参数的 1x1 卷积。

    第二个选项可能如下所示:

    if downsample:
        self.downsample = conv1x1(inplanes, planes, strides)
    

    【讨论】:

    • 您好托马斯,感谢您的回答。我理解(b)使用 1x1 来获得所需的维度以将剩余连接作为输入传递,而我无法完全了解(a)如何使用零条目进行身份映射。您能否澄清或指出一些有助于理解选项(a)的资源
    【解决方案2】:

    在这个 ResNet 示例中,当我们定义 BasicBlock 类时,我们将 downsample 作为构造函数参数传递。

    def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, norm_layer=None):
    

    如果我们什么都不传递给类,那么 downsample = None ,结果 identity 不会改变。

    当我们将downsample = "some convolution layer" 作为类构造函数参数传递时,它将通过传递的卷积层对identity进行下采样以成功执行加法。如前所述,该层将通过代码对身份进行下采样

      if self.downsample is not None:
            identity = self.downsample(x)
    

    【讨论】:

      【解决方案3】:

      我相信在这种情况下,它可以是平均池化或最大池化。它们都降低了维度并保留了输入的大部分属性。

      【讨论】:

        【解决方案4】:

        除了托马斯·皮内茨所说的:

        resnet-50 架构中,这是作为下采样步骤发生的:

        downsample = nn.Sequential(conv1x1(self.inplanes, planes * block.expansion, stride),norm_layer(planes * block.expansion))
        

        注意 - 1*1 卷积和批量归一化

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-22
          • 2020-04-14
          • 2021-11-13
          • 2021-07-09
          • 2012-06-08
          • 2020-02-17
          相关资源
          最近更新 更多