考虑以下代码,这些代码将在PyTorch中打印带有resnet50主干的fast_rcnn模型的模块。
model_fastercnn = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
modules_2 = list(model_fastercnn.children())
for iter, module in enumerate(modules_2):
print("###### {} ######".format(iter))
print(module)
这是由先前代码打印的最后一个模块。
###### 3 ######
RoIHeads(
(box_roi_pool): MultiScaleRoIAlign()
(box_head): TwoMLPHead(
(fc6): Linear(in_features=12544, out_features=1024, bias=True)
(fc7): Linear(in_features=1024, out_features=1024, bias=True)
)
(box_predictor): FastRCNNPredictor(
(cls_score): Linear(in_features=1024, out_features=91, bias=True)
(bbox_pred): Linear(in_features=1024, out_features=364, bias=True)
)
)
现在假设我们要使用“ fc7”的输出(RoIHeads-> box_head-> fc7)作为另一个自定义层的输入,例如,一个Linear 1024-> 512,也要使用预先训练的直到fc7的权重,然后为某些损失函数训练最后添加的层的权重。由于最后一个模块是用该类包装的,所以有什么办法吗?
我提出了最后一句话,因为例如考虑了PyTorch中的resnet152预训练模型,通过打印模块(如上),我了解到它包含“ 9”层,最后一层是FC(只是一个nn.Linear),我省略了最后一层并构建了另一个顺序网络,然后添加了另一层并仅使用最后一层的参数来训练模型。有关更多信息,请参见以下来自here的代码:
class EncoderCNN(nn.Module):
def __init__(self, embed_size):
"""Load the pretrained ResNet-152 and replace top fc layer."""
super(EncoderCNN, self).__init__()
resnet = models.resnet152(pretrained=True)
modules = list(resnet.children())[:-1] # delete the last fc layer.
self.resnet = nn.Sequential(*modules)
self.linear = nn.Linear(resnet.fc.in_features, embed_size)
self.bn = nn.BatchNorm1d(embed_size, momentum=0.01)
def forward(self, images):
"""Extract feature vectors from input images."""
with torch.no_grad():
features = self.resnet(images)
features = features.reshape(features.size(0), -1)