如何在PyTorch中向预训练模型添加层?

2024-09-27 00:19:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在AdaptiveAvgPool2d层之后添加layer normalization函数,在fc layer层之后添加L2 normalization。我希望我的fc layer输出为200,所以尝试不包括fc层而不是它,使其成为新的fc layer,但它没有删除fc layers带有预训练模型,我使用googlenet

我的代码:

class GoogleNet(nn.Module):
    def __init__(self):
        super(GoogleNet,self).__init__()
        self.model = googlenet_pytorch.GoogLeNet.from_pretrained('googlenet')
        
        self.fc = nn.Linear(1024,200, bias=False),
        
    def forward(self, x):
        batch_size ,_,_,_ =x.shape
        x = self.model.extract_features(x)
        x = self.model._avg_pooling(x)
        x = F.layer_norm(x,x.size[1:],elementwise_affine=False)
        x = self.fc(x)
        x = F.normalize(x, p=2, dim=1)
        return x

我得到的输出:

      .....  
      .....  
      .....

(aux1): InceptionAux(
      (conv): BasicConv2d(
        (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (fc1): Linear(in_features=2048, out_features=1024, bias=True)
      (fc2): Linear(in_features=1024, out_features=1000, bias=True)
    )
    (aux2): InceptionAux(
      (conv): BasicConv2d(
        (conv): Conv2d(528, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (fc1): Linear(in_features=2048, out_features=1024, bias=True)
      (fc2): Linear(in_features=1024, out_features=1000, bias=True)
    )
    (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
    (dropout): Dropout(p=0.2, inplace=False)
    (fc): Linear(in_features=1024, out_features=1000, bias=True)
  )
)

我想要的输出:

  ......
  ......
  ......

  (aux1): None
  (aux2): None
  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
  ** layer normalization here**
  (dropout): Dropout(p=0.2, inplace=False)
  (fc): Linear(in_features=1024, out_features=200, bias=False)
  **L2 normalization here**
)

如果有人需要知道这个问题的解决方案代码,在iacob的回答的帮助下,我解决了它,我将它添加为an answer


Tags: inselflayerfalsetruesizeoutlinear
3条回答

我认为您可以删除最后一层,然后添加所需的层

因此,在你的情况下:

class GoogleNet(nn.Module):
    def __init__(self):
        super(GoogleNet,self).__init__()

        # load the original google net
        self.model = googlenet_pytorch.GoogLeNet.from_pretrained('googlenet')
        
        # remove the last two layers (fc and dropout)
        self.model = nn.Sequential(*list(self.model.children())[:-2])
        
        # add your dropout layer
        self.dropout = nn.Dropout(0.2, inplace=False)

        # add your dense layer
        self.fc = nn.Linear(1024, 200, bias=False)
        
    def forward(self, x):
        batch_size, _, _, _ = x.shape

        # I dont know what this does but I'll leave it here
        x = self.model.extract_features(x)
        # but I would add x = self.model(x) instead

        # insert your layer normalization
        x = F.layer_norm(x,x.size[1:],elementwise_affine=False)
        
        # put droput layer back on
        x = self.dropout(x)
        
        x = self.fc(x)

        x = F.normalize(x, p=2, dim=1)

        return x

但请注意,打印模型摘要时,它不会显示规范化层。它不会打印您在forward()中使用F.添加的内容,只打印您在__init__()中创建的初始值

在根据@iacob对代码进行更正之后,我解决了这个问题

正确的代码:

class GoogleNet(nn.Module):
    def __init__(self):
        super(GoogleNet,self).__init__()
        self.model = googlenet_pytorch.GoogLeNet.from_pretrained('googlenet')
        self.avgpool = nn.AdaptiveAvgPool2d((1,1))
        self.layernorm = nn.LayerNorm(1024,elementwise_affine=True)
        self._fc = nn.Linear(1024,200, bias=False)
    def forward(self, x):
        batch_size ,_,_,_ =x.shape
        x = self.model.extract_features(x)
        x = self.model.avgpool(x)
        x = x.view(-1, 1024)
        x = self.layernorm(x)
        x = self._fc(x)
        x = F.normalize(x, p=2, dim=1)
        return x

在此之后,我创建了GoogleNet()的一个实例,并将不需要的层转换为Identity()

dep = GoogleNet()
dep.model.aux1 = Identity()
dep.model.aux2 = Identity()
dep.model.avgpool = Identity()
dep.model.dropout = Identity()
dep.model.fc = Identity()

打印模型时,PyTorch将打印每个层,直到它在forward中遇到错误,而不管模型是否运行(在适当格式的输入数据上)

加载主干GoogLeNet模型后,代码中存在许多问题,因此在此之后添加的所有层在打印时都无法显示。显而易见的问题是:

  • 必须删除self.fc = nn.Linear(1024,200, bias=False),之后的,,否则它将被解释为tuple
  • GoogLeNet没有属性_avg_pooling
  • x.size不可下标。使用函数调用x.size()[1:]或使用x.shape[1:]
  • F.layer_norm()没有参数elementwise_affine

为了让模型运行like so,您需要更正这些错误

相关问题 更多 >

    热门问题