如何剥离预训练网络并使用pytorch lightning为其添加一些层?
我正在尝试将转移学习用于图像分割任务,我的计划是使用预训练模型(例如VGG16)的前几层作为编码器,然后添加我自己的解码器 因此,我可以加载模型并通过打印查看结构:如何剥离预训练网络并使用pytorch lightning为其添加一些层?,pytorch,transfer-learning,pytorch-lightning,Pytorch,Transfer Learning,Pytorch Lightning,我正在尝试将转移学习用于图像分割任务,我的计划是使用预训练模型(例如VGG16)的前几层作为编码器,然后添加我自己的解码器 因此,我可以加载模型并通过打印查看结构: model = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True) print(model) 我会这样: ResNet( (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), pa
model = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True)
print(model)
我会这样:
ResNet(
(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(1): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
.....
.....
.....
我还可以使用model.layer3
访问特定的层。现在,我正在与某些事情斗争
冻结
仅此剥离部分,并保持新添加的模块可用于培训以下内容适用于
模型的任何子模块
,但我将用模型回答您的问题。第3层
在这里:
model.layer3
将为您提供与模型第3层关联的nn.Module
。您可以像使用model
>>> z = model.layer3(torch.rand(16, 128, 10, 10))
>>> z.shape
torch.Size([16, 256, 5, 5])
- 您可以将层置于评估模式,该模式禁用辍学,并使BN层在训练期间使用统计学习。这是通过
model.layer3.eval()完成的
- 必须通过切换
标志来禁用该层上的培训:requires\u grad
,这将影响所有子参数model.layer3.requires\u grad(False)
可以使用以下方法冻结图层:
pretrained_model.freeze()
对于1):初始化LightningModule中的ResNet,并将其切片,直到找到所需的部分。然后,在这之后添加您自己的头,并按照您需要的顺序定义转发
。请参见此示例,基于:
导入torchvision.models作为模型
类ImagenetTransferLearning(LightningModule):
定义初始化(自):
super()。\uuuu init\uuuuu()
#在预训练的resnet中
主干网\u tmp=models.resnet50(预训练=True)
num_filters=主干网_tmp.fc.in_功能
layers=list(backbone\u tmp.children())[:-1]
self.backbone=nn.Sequential(*层)
#使用预训练模型对cifar-10进行分类(10个图像类)
num_target_classes=10
self.classifier=nn.Linear(num\u过滤器、num\u目标类)
对于2):将BackboneFinetuning
传递给您的培训师
。这要求您的LightningModule
具有包含要冻结的模块的self.backbone
属性,如上面的代码段所示。如果需要不同的冻结-解冻行为,也可以使用basefinetunning
pytorch_lightning导入培训师提供的
从pytorch_lightning.callbacks导入BackboneFinetuning
乘法=λ历元:1.5
主干线微调=主干线微调(200,乘法)
培训师=培训师(回调=[主干线微调])