【转载】关于Resnet18的结构参数以及每层卷积池化后的特征图大小和通道数变化

实验需要查到了这篇博客浅显易懂,真的是值得转载记录一下。
更多需要的人阅读哦~

以下完整的记录了原版博客,想看原版请戳ResNet18结构、各层输出维度

网络结构及参数:

import torchvision.models as models
resnet18 = models.resnet18()
print(resnet18)

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, track_running_stats=True)
  (relu): ReLU(inplace=True)
  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
  (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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=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, track_running_stats=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, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (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, track_running_stats=True)
    )
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
  (fc): Linear(in_features=512, out_features=1000, bias=True)
)

每层特征图大小及通道数,附计算公式:

ResNet18

Input:3@224*224

conv1:64@112*112 # 112 == (224-7+2+3*2)/2

bn1:64@112*112

relu:64@112*112

maxpool:64@56*56 # 56 == (112-3+2+1*2)/2

layer1:
	0:
		conv1:64@56*56
		bn1:64@56*56
		relu:64@56*56
		conv2:64@56*56
		bn2:64@56*56
	1:
		conv1:64@56*56
		bn1:64@56*56
		relu:64@56*56
		conv2:64@56*56
		bn2:64@56*56

layer2:
	0:
		conv1:128@28*28
		bn1:128@28*28
		relu:128@28*28
		conv2:128@28*28
		bn2:128@28*28
		downsample:
			0:128@28*28
			1:128@28*28
	1:
		conv1:128@28*28
		bn1:128@28*28
		relu:128@28*28
		conv2:128@28*28
		bn2:128@28*28

layer3:
	0:
		conv1:256@14*14
		bn1:256@14*14
		relu:256@14*14
		conv2:256@14*14
		bn2:256@14*14
		downsample:
			0:256@14*14
			1:256@14*14
	1:
		conv1:256@14*14
		bn1:256@14*14
		relu:256@14*14
		conv2:256@14*14
		bn2:256@14*14

layer4:
	0:
		conv1:512@7*7
		bn1:512@7*7
		relu:512@7*7
		conv2:512@7*7
		bn2:512@7*7
		downsample:
			0:512@7*7
			1:512@7*7
	1:
		conv1:512@7*7
		bn1:512@7*7
		relu:512@7*7
		conv2:512@7*7
		bn2:512@7*7

avgpool:512@1*1

fc:1000
ResNet(残差网络)是一种非常流行的深度神经网络结构,它利用了残差学习的思想,允许网络在更深的层下仍然能够训练有效的模型。ResNet的每一层都包含了一个残差块,其中每个块由两个或三个卷积层组成。每个残差块的输入和输出都有一个跨越连接(shortcut connection),跨越了一到两层的卷积层。 ResNet每一层的变化和作用如下: 1. 输入层:将输入的像进行卷积操作,将像从低级特征逐渐转化为高级特征。 2. 残差块:每个残差块都包含了一个或两个卷积层和跨越连接。它们的作用是在输入和输出之间添加一个残差,允许网络更容易地学习到更深层次的特征。 3. 残差连接(shortcut connection):每个残差块的跨越连接将输入直接连接到输出,允许信息直接绕过块内的卷积层。这有助于避免梯度消失和梯度爆炸的问题,并使得网络能够更深层次地学习。 4. 池化层:对于某些层,池化操作可以将特征缩小到更小的尺寸,减少计算成本并提高模型鲁棒性。 5. 全局平均池化层:将最后一个卷积层的输出进行全局平均池化,将特征压缩成一个向量,作为模型的最终输出。 总之,ResNet的每一层都通过残差块和跨越连接来使得模型更加深层次,能够更好地学习输入据的特征,同时有效地避免了梯度消失和梯度爆炸的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值