如何构建一个cnn进行微调?

xiaoxingxing pytorch 508

原文标题How to structure a cnn for fine-tuning?

我想微调一个模型,以便我可以尝试各种不同的超参数。例如:

  • 过滤器
  • 正则化
  • 卷积滤波器大小
  • 学习率
  • 优化器

我选择在 PyTorch 中执行此操作并创建了一个基本模型(见下文)。但是,我不确定设置代码以执行此操作的最佳方法。特别是我的 ConvNet 和训练功能。我需要在使用图表时进行比较。任何人都可以就构建我的代码/进行此操作的最佳方式提供任何建议。

class ConvNet(nn.Module):
  def __init__(self, num_classes=10):
    super().__init__()

    self.layer1 = nn.Sequential(
        nn.Conv2d(3, 16, kernel_size=3, stride=1),
        nn.BatchNorm2d(16),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.layer2 = nn.Sequential(
        nn.Conv2d(16, 32, kernel_size=3, stride=1),
        nn.BatchNorm2d(32),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.fcl = nn.Sequential(
        nn.Flatten(),
        nn.Linear(1152, 100)
    )

  def forward(self, x):
    out = self.layer1(x)
    out = self.layer2(out)
    out = self.fcl(out)

    return out

原文链接:https://stackoverflow.com//questions/71527284/how-to-structure-a-cnn-for-fine-tuning

回复

我来回复
  • Joe的头像
    Joe 评论

    如果您正在寻找一个简单的教程,PyTorch 有一个可以很好地解释计算机视觉的教程:https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html

    这是与您的问题最相关的部分,因此您可以看到调整优化器时如何进行微调。

    model_ft = models.resnet18(pretrained=True)
    num_ftrs = model_ft.fc.in_features
    # Here the size of each output sample is set to 2.
    # Alternatively, it can be generalized to nn.Linear(num_ftrs, len(class_names)).
    model_ft.fc = nn.Linear(num_ftrs, 2)
    
    model_ft = model_ft.to(device)
    
    criterion = nn.CrossEntropyLoss()
    
    # Observe that all parameters are being optimized
    optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
    
    # Decay LR by a factor of 0.1 every 7 epochs
    exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
    

    你必须先完全训练你的模型。然后你可以参考这个帖子:https://discuss.pytorch.org/t/how-to-perform-finetuning-in-pytorch/419/8?u=nullpointer

    ignored_params = list(map(id, model.fc.parameters()))
    base_params = filter(lambda p: id(p) not in ignored_params,
                         model.parameters())
    
    optimizer = torch.optim.SGD([
                {'params': base_params},
                {'params': model.fc.parameters(), 'lr': opt.lr}
            ], lr=opt.lr*0.1, momentum=0.9)
    

    如果您想在微调时更改层的权重而不更改网络的权重,您可以执行以下操作:

        model = models.vgg16(pretrained=True)
        print list(list(model.classifier.children())[1].parameters())
        mod = list(model.classifier.children())
        mod.pop()
        mod.append(torch.nn.Linear(4096, 2))
        new_classifier = torch.nn.Sequential(*mod)
        print list(list(new_classifier.children())[1].parameters())
        model.classifier = new_classifier
    

    如果您要向当前模型添加层或过滤器:

    class MyModel(nn.Module):
        def __init__(self, pretrained_model):
            self.pretrained_model = pretrained_model
            self.last_layer = ... # create layer
    
        def forward(self, x):
            return self.last_layer(self.pretrained_model(x))
    
    2年前 0条评论