神經網絡模型中-model/model.name_module()的區別

標題 model / model.name_module()的區別:

對於已經訓練好的網絡模型,爲了方便後續使用和提取某一層的參數,在儲存模型時,我們會對網絡每一層進行命名+儲存參數數據。所以我們可以對每一層進行操作,例如剪枝操作。
在判斷當前層時,使用:

for name, m0 in model.name_module():
	if isinstance(m0, Conv):
		....(argument you need)
		

那麼到底print(model)和print(model.name_module())到底有什麼區別呢?
當我們使用 print(model)時,輸出model中全部結構和層,例如:
[下列打印的輸出是博主在進行shuffleNetV2剪枝的時候輸出的模型結構]

ShuffleNetV2_2(
  (conv1): Conv2d(3, 24, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
  (stage2): Sequential(
    (ShuffleUnit_Stage2_0): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(24, 50, kernel_size=(1, 1), stride=(1, 1))
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 176, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(176, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_1): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_2): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_3): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
 ])

但我們打印print(model.name_module()):

爲了方便各位觀看,這裏只截取一小部分,進行講解展示

  1. model.name_module()先將model全部內容打印一邊,如同前面print(model)結果一樣
  2. 打印一邊全部內容後,進行迭代,將結構中的全部block中的每一層打印一邊:
    1)先打印當前block,2)後打印當前block中的每一層
    3)以此類推,把全部結構打印出來
    舉個本文代碼的例子,結構共16個block,但最後打印出來166個結果,具體打印出來多少,根據每一個block中的層數而定!
0  ShuffleNetV2_2(
  (conv1): Conv2d(3, 24, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
  (stage2): Sequential(
    (ShuffleUnit_Stage2_0): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(24, 50, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50, bias=False)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 176, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(176, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_1): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50, bias=False)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_2): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50, bias=False)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (ShuffleUnit_Stage2_3): ShuffleUnit(
      (g_conv_1x1_compress): Sequential(
        (conv1x1): Conv2d(200, 50, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU()
      )
      (depthwise_conv3x3): Conv2d(50, 50, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=50, bias=False)
      (bn_after_depthwise): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (g_conv_1x1_expand): Sequential(
        (conv1x1): Conv2d(50, 200, kernel_size=(1, 1), stride=(1, 1), groups=2, bias=False)
        (batch_norm): BatchNorm2d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )

下面的輸出結果解釋什麼叫迭代輸出:

4 是當前block,內含conv,bn,relu三層
5 是迭代4中的block內容,依次輸出 5 conv,6 bn,7 relu

4 stage2.ShuffleUnit_Stage2_0.g_conv_1x1_compress Sequential(
  (conv1x1): Conv2d(24, 50, kernel_size=(1, 1), stride=(1, 1), bias=False)
  (batch_norm): BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU()
)
5 stage2.ShuffleUnit_Stage2_0.g_conv_1x1_compress.conv1x1 Conv2d(24, 50, kernel_size=(1, 1), stride=(1, 1), bias=False)
6 stage2.ShuffleUnit_Stage2_0.g_conv_1x1_compress.batch_norm BatchNorm2d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
7 stage2.ShuffleUnit_Stage2_0.g_conv_1x1_compress.relu ReLU()

所以在使用model中block內容的時候,一定弄清兩者區別
尤其要注意後者的輸出內容和輸出順序!!

祝好

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章