如何将一个模型的输出加载为另一个模型参数并进行端到端优化



这里我们有这个问题的摘要:

假设我们有两个模型:ResNet和EfficienNet。

第一个模型如下(ResNet(:

def __init__(self, in_channels, out_channels, num_classes):
super().__init__()
self.conv1_0 = _conv3x3(3, 32, stride=2)
self.bn1_0 = _bn(32)
self.conv1_1 = _conv3x3(32, 32, stride=1)
self.bn1_1 = _bn(32)
self.conv1_2 = _conv3x3(32, 64, stride=1)
self.relu = nn.ReLU()
self.pad = torch.nn.ReplicationPad2d(padding=(0, 0, 1, 1))
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2)
self.end_point = _fc(225, num_classes) 
def forward(self, x):
x = self.conv1(x)
#and so on...     
out = self.end_point(x)
return out

而第二个模型已下载如下(高效(

efficientNet = models.efficientnet_b5().to(device)

因此,我们有两个模型,但第一个是从头开始开发的,第二个是由torchvisi.models库导入的。

现在,我们希望EfficientNet获取ResNet的输出,然后从EfficientNet的输出到ResNet的第一层进行端到端优化。

我知道一种更简单的方法,那就是更改代码,并直接使用ResNet的结果作为Efficient.forward((的输入。然而,Efficient模型太复杂了,很难进行这样的更改。

出于数学原因,假设我们在ResNet和EfficientNet之间有另一个简单的模型,它被称为gumbel_mode

因此,总之,我们有3个模型,但我们只得到了关于最后一个模型的一个目标标签,那么我们只能计算最后一个模式(效率网(的损失。

当我们计算最后一个模型的损失时,我们实际上把三行写如下:

optimizer.zero_grad()
loss.backforward()
optimizer.step()

优化器如下:

optimizer = optim.SGD([dict(params=efficientNet.parameters(), lr=LR)])

我们只对最后一个模型进行反向分析是正确的吗要反向传播端到端模型,是否需要像optim的第一个参数一样添加ResNet的参数。SGD?如果是,我们如何通过ResNet获取参数?(见上文(

我曾尝试在一个时期使用一些代码,如下所示:

efficientNet = get_efficient_trained(device, out_features=1, in_features=3,path_model)
predictor = ResNet(ResidualBlockBase, layer_config, num_classes=num_cl)        
for i, imgs in enumerate(dataloader):
inputs, labels = imgs
inputs, labels = inputs.to(device), labels.to(device)  
predictor_output = predictor(inputs)
predictor_gumbel_output = gumbel(predictor_output)
optimizer.zero_grad()
outputs = efficientnet(predictor_gumbel_output).torch.squeeze(outputs, 1)     
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()    
return model

但从结果来看,我担心只有EfficientNet才刚刚得到训练。

有什么方法可以让反向优化到达ResNet吗我该如何解决这类问题*

正在等待响应。我真的提前感谢大家。

优化器的params参数指定要优化的所有参数。在这里,由于您只传递EfficientNet的参数,因此只有那些参数会得到优化,正如您所怀疑的那样。

要对所有参数进行端到端优化,只需在初始化优化器时将它们全部传递即可。可以这样做:

optimizer = optim.SGD(list(efficientNet.parameters()) + list(gumbel.parameters()) + list(predictor.parameters()), lr=LR)

最新更新