在计算 perceptual loss 的时候,需要从一个训练好的 VGG16 或者 VGG19 的中间层提取出待测图像的特征并进行比较。在 PyTorch 中,已经训练好的网络模型很可能是通过 nn.Sequetial 来定义的,中间层的名字未知,该如何进行提取?
Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv1_1
(1): ReLU(inplace) # relu1_1
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv1_2
(3): ReLU(inplace) # relu1_2
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool1
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv2_1
(6): ReLU(inplace) # relu2_1
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv2_2
(8): ReLU(inplace) # relu2_2
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool2
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_1
(11): ReLU(inplace) # relu3_1
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_2
(13): ReLU(inplace) # relu3_2
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_3
(15): ReLU(inplace) # relu3_3
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool3
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_1
(18): ReLU(inplace) # relu4_1
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_2
(20): ReLU(inplace) # relu4_2
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_3
(22): ReLU(inplace) # relu4_3
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool4
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_4
(25): ReLU(inplace) # relu4_4
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_1
(27): ReLU(inplace) # relu5_1
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_2
(29): ReLU(inplace) # relu5_2
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool5
)
Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv1_1
(1): ReLU(inplace) # relu1_1
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv1_2
(3): ReLU(inplace) # relu1_2
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool1
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv2_1
(6): ReLU(inplace) # relu2_1
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv2_2
(8): ReLU(inplace) # relu2_2
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool2
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_1
(11): ReLU(inplace) # relu3_1
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_2
(13): ReLU(inplace) # relu3_2
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_3
(15): ReLU(inplace) # relu3_3
(16): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv3_4
(17): ReLU(inplace) # relu3_4
(18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool3
(19): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_1
(20): ReLU(inplace) # relu4_1
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_2
(22): ReLU(inplace) # relu4_2
(23): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_3
(24): ReLU(inplace) # relu4_3
(25): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv4_4
(26): ReLU(inplace) # relu4_4
(27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool4
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_1
(29): ReLU(inplace) # relu5_1
(30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_2
(31): ReLU(inplace) # relu5_2
(32): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_3
(33): ReLU(inplace) # relu5_3
(34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) # conv5_4
(35): ReLU(inplace) # relu5_4
(36): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) # pool5
)
在计算 perceptual loss 的时候,需要从一个训练好的 VGG16 或者 VGG19 的中间层提取出待测图像的特征并进行比较。在 PyTorch 中,已经训练好的网络模型很可能是通过
nn.Sequetial来定义的,中间层的名字未知,该如何进行提取?How to extract the features of an image from a trained model in PyTorch?
https://discuss.pytorch.org/t/how-to-extract-features-of-an-image-from-a-trained-model/119
VGG16 Features
VGG19 Features