2

以下是RestNet-18的Pytorch实现: https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py 以下是ResNet-18的结构,任何人都知道为什么这个网络有18层?如何判断ResNet-18中的层数?

ResNet (
    (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False) 
    (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) 
    (relu): ReLU (inplace) 
    (maxpool): MaxPool2d (size=(3, 3), stride=(2, 2), padding=(1, 1), dilation=(1, 1)) 
    (layer1): Sequential (
    (0): BasicBlock (
     (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) 
    ) 
    (1): BasicBlock (
     (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) 
    ) 
) 
    (layer2): Sequential (
    (0): BasicBlock (
     (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) 
     (downsample): Sequential (
     (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False) 
     (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) 
    ) 
    ) 
    (1): BasicBlock (
     (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) 
    ) 
) 
    (layer3): Sequential (
    (0): BasicBlock (
     (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) 
     (downsample): Sequential (
     (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False) 
     (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) 
    ) 
    ) 
    (1): BasicBlock (
     (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) 
    ) 
) 
    (layer4): Sequential (
    (0): BasicBlock (
     (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) 
     (downsample): Sequential (
     (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False) 
     (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) 
    ) 
    ) 
    (1): BasicBlock (
     (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) 
     (relu): ReLU (inplace) 
     (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) 
     (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) 
    ) 
) 
    (avgpool): AvgPool2d (
) 
    (fc): Linear (512 -> 1000) 
) 
+0

它被设计成有18层,可能是通过实验,所以没有“为什么”我们可以告诉你。 –

+0

谢谢,但是必须有一种方法来通过代码来计数层,比如CNN,我们可以通过'__init __()'统计层数,但ResNet-18有'layer1〜4',每层都会调用'_make_layer ()',就像上面的输出一样,有54个图层。 – mcgG

+0

我想要做的是记录每个图层的渐变,所以我需要弄清楚网络中有多少图层。 – mcgG

回答

1

从你的输出,我们可以知道,有20个卷积层(一个7x7的转换次数,16 3x3的转换次数,并加上下采样3的1x1 CONV)。基本上,如果你忽略1x1转换,并计算fc(线性)层,层数为18.

而且我也做了一个示例https://gist.github.com/wangg12/f11258583ffcc4728eb71adc0f38e832如何通过graphviz在pytorch中可视化您的体系结构,希望它会帮助你理解你的架构。

+0

谢谢,所以层数并不严格? – mcgG

+0

基本上我们通常只计算卷积和完全连接层的数量。但是在resnet中,我不确定是否应该计算快捷卷积层。应该由作者的定义决定。 –