如何使用VGG19迁移学习预训练

How to use VGG19 transfer learning pretraining

我正在研究 VQA 模型,我需要一些帮助,因为我是新手。

我想在 运行训练之前使用 VGG19 网络的迁移学习,所以当我开始训练时,我将拥有前面的图像特征(试图解决性能问题)。

可以吗?如果是这样,有人可以用 pytorch 分享一个例子吗?

下面是相关代码:

class img_CNN(nn.Module):
  def __init__(self, img_size):

        super(img_CNN, self).__init__()
        self.model = models.vgg19(pretrained=True)
        self.in_features = self.model.classifier[-1].in_features
        self.model.classifier = nn.Sequential(*list(self.model.classifier.children())[:-1]) # remove vgg19 last layer
        self.fc = nn.Linear(in_features, img_size)

  def forward(self, image):
    #with torch.no_grad():
    img_feature = self.model(image) # (batch, channel, height, width)
    img_feature = self.fc(img_feature)   
    return img_feature

class vqamodel(nn.Module):
  def __init__(self, output_dim,input_dim, emb_dim, hid_dim, n_layers, dropout, answer_len, que_size, img_size,model_vgg,in_features):
    super(vqamodel,self).__init__()
    self.image=img_CNN(img_size)
    self.question=question_lstm(input_dim, emb_dim, hid_dim, n_layers, dropout,output_dim,que_size)
    self.tanh=nn.Tanh()
    self.relu=nn.ReLU()
    self.dropout=nn.Dropout(dropout)
    self.fc1=nn.Linear(que_size,answer_len) #the input to the linear network is equal to the combain vector
    self.softmax=nn.Softmax(dim=1)


  def forward(self, image, question):
    image_emb=self.image(image)
    question_emb=self.question(question) 
    combine =question_emb*image_emb
    out_feature=self.fc1(combine)
    out_feature=self.relu(out_feature)
      
    return (out_feature)

如何在训练图像数据加载器之前取出 models.vgg19(pretrained=True),运行 并将图像表示保存在 NumPy 数组中?

谢谢!

是的,您可以使用预训练的 VGG 模型从图像中提取嵌入向量。这是一个可能的实现,使用 torchvision.models.vgg*.

  1. 首先检索预训练模型

    model = torchvision.models.vgg19(pretrained=True)
    

    它的分类器是:

    >>> model.classifier
    (classifier): Sequential(
        (0): Linear(in_features=25088, out_features=4096, bias=True)
        (1): ReLU(inplace=True)
        (2): Dropout(p=0.5, inplace=False)
        (3): Linear(in_features=4096, out_features=4096, bias=True)
        (4): ReLU(inplace=True)
        (5): Dropout(p=0.5, inplace=False)
        (6): Linear(in_features=4096, out_features=1000, bias=True)
    )
    
  2. 根据您的微调策略,您可以截断它以保留一些经过训练的密集层:

    model.classifier = nn.Sequential(*[model.classifier[i] for i in range(4)])
    

    或者用包裹在 nn.Sequential:

    中的一组不同的致密层将其完全替换
    model.classifier = nn.Sequential(
        nn.Linear(25088, 4096),
        nn.ReLU(True),
        nn.Dropout(0.5),
        nn.Linear(4096, 2048))
    
  3. 此外,您可以冻结模型的整个头部(特征提取器):

    for param in model.features.parameters():
        param.requires_grad = False
    
  4. 然后您将能够使用该模型提取图像嵌入并执行反向传播以微调您的分类器:

    >>> model(img) # shape (batchs_size, 2048)