源代码
- 通过截取 vgg19 feature map 不同 size 特征段,获取多种 size 的 feature map
- 具体为 5 种 feature map size:
[1, 1/2, 1/4, 1/8, 1/8]
import torch.nn as nn
from torchvision import models
class VGG19(nn.Module):
def __init__(self):
super(VGG19, self).__init__()
# 查看 vgg19 结构,得知 features 为 nn.Sequential,可用 idx 获取特定 layer 参数
features = models.vgg19(pretrained=True).features
self.to_relu_1_1 = nn.Sequential()
self.to_relu_2_1 = nn.Sequential()
self.to_relu_3_1 = nn.Sequential()
self.to_relu_4_1 = nn.Sequential()
self.to_relu_4_2 = nn.Sequential()
# 截取 vgg19 不同 feature map size 的特征段,参照下方源代码
for x in range(2):
self.to_relu_1_1.add_module(str(x), features[x]) # 1/1
for x in range(2, 7):
self.to_relu_2_1.add_module(str(x), features[x]) # 1/2
for x in range(7, 12):
self.to_relu_3_1.add_module(str(x), features[x]) # 1/4
for x in range(12, 21):
self.to_relu_4_1.add_module(str(x), features[x]) # 1/8
for x in range(21, 25):
self.to_relu_4_2.add_module(str(x), features[x]) # 1/8
for param in self.parameters():
param.requires_grad = False
def forward(self, x):
h = self.to_relu_1_1(x)
h_relu_1_1 = h
h = self.to_relu_2_1(h)
h_relu_2_1 = h
h = self.to_relu_3_1(h)
h_relu_3_1 = h
h = self.to_relu_4_1(h)
h_relu_4_1 = h
h = self.to_relu_4_2(h)
h_relu_4_2 = h
out = (h_relu_1_1, h_relu_2_1, h_relu_3_1, h_relu_4_1, h_relu_4_2)
return out # 返回 [1, 1/2, 1/4, 1/8, 1/8] 5 种 size 的中间特征
用 print 直观查看 vgg19 模型原始结构
from torchvision import models
vgg = models.vgg19(pretrained=False)
print(vgg)
卷积核输出 feature map size
VGG(
# features = models.vgg19(pretrained=True).features
# 此项为 获取的 pretrained vgg19 参数;如下注释显示 self.relu 使用的参数块
(features): Sequential(
# self.to_relu_1_1 -> 1/1
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
# self.to_relu_2_1 -> 1/2
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
# self.to_relu_3_1 -> 1/4
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
# self.to_relu_4_1 -> 1/8
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(17): ReLU(inplace=True)
(18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(19): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
# self.to_relu_4_2 -> 1/8
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(24): ReLU(inplace=True)
# 之后参数,没有使用
(25): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(26): ReLU(inplace=True)
(27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(31): ReLU(inplace=True)
(32): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(33): ReLU(inplace=True)
(34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(35): ReLU(inplace=True)
(36): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
(classifier): Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace=True)
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)