1、利用resnet提取特征
根据ResNet的网络结构,fc充当分类器的角色,那么特征就是fc前一层的输出(fc层的输入)
作为分类器,fc的输入是512(这个由Resnet的层数决定,resnet18=512,resnet50=2048),fc的输出为nb-classes(由数据集决定):
输出特征,就把输出也改为512,那么输出的就是大小为[batch-size, 512]的特征。
for i, (images, target) in enumberate(train_loader):
# ……
resnet50_feature_extractor = models.resnet18(pretrained=True)
resnet50_feature_extractor.fc = nn.Linear(512, 512)
# y_features是特征:
y_features = resnet50_feature_extractor(images)
2、引用模型中指定层
如果加载model和更改model参数不在一起执行,那么直接用resnet50_feature_extractor.fc
形式引用fc层可能不准确(程序找不到你想更改的fc层)
因为model在pytorch是存成DataParallel格式的,此时要用:
resnet50_feature_extractor.module.fc
3、边训练边输出特征
有时候,我们可能需要边训练边输出features。但我们希望还是针对分类模型进行优化,不针对features进行优化。
也就是说,我不打算改变优化函数(optimizer、loss,etc.)但我希望能同步输出当前的features。
for i, (images, target) in enumberate(train_loader):
# ……
resnet50_feature_extractor = copy.deepcopy(model)
resnet50_feature_extractor.fc = nn.Linear(512, 512)
# ---以下几行必须要有:---
torch.nn.init.eye_(resnet50_feature_extractor.module.fc.weight)
torch.nn.init.zeros_(resnet50_feature_extractor.module.fc.bias)
for param in resnet50_feature_extractor.parameters():
param.requires_grad = False
# ---------------------
# y_features是特征:
resnet50_feature_extractor = resnet50_feature_extractor.cuda()
y_features = resnet50_feature_extractor(images)
# 这两个output是一样的:
output_from_features = model.module.fc(y_features )
output_from_Img = model(images)
4、复制模型
需要deepcopy,否则还是修改原模型:
resnet50_feature_extractor = copy.deepcopy(model)