• 微调(linear probing和 full finetune)技巧


    应用场景:图像分类 (使用CIFAR10作为测试数据集,ResNet18作为Backbone网络)

    数据预处理 (resize_val = 224, n_holes = 1, length在原有的size=32时候为16)

    1. # Image Preprocessing
    2. normalize = transforms.Normalize(mean=[x / 255.0 for x in [125.3, 123.0, 113.9]],
    3. std = [x / 255.0 for x in [63.0, 62.1, 66.7]])
    4. train_transform = transforms.Compose([])
    5. if args.resize_val != -1:
    6. train_transform.transforms.append(transforms.Resize((args.resize_val,args.resize_val)))
    7. train_transform.transforms.append(transforms.RandomCrop(args.resize_val, padding=4))
    8. train_transform.transforms.append(transforms.RandomHorizontalFlip())
    9. train_transform.transforms.append(transforms.ToTensor())
    10. train_transform.transforms.append(normalize)
    11. train_transform.transforms.append(Cutout(n_holes=args.n_holes, length=args.length))
    12. test_transform = transforms.Compose([
    13. transforms.Resize((args.resize_val,args.resize_val)),
    14. transforms.ToTensor(),
    15. normalize])

    训练优化器和 lr decay方式 (lr =0.01,wd = 5e-4)

    1. criterion = nn.CrossEntropyLoss()
    2. cnn_optimizer = torch.optim.SGD(cnn.parameters(), lr=args.learning_rate,
    3. momentum=0.9, nesterov=True, weight_decay=args.wd)
    4. scheduler = MultiStepLR(cnn_optimizer, milestones=[60, 120, 160], gamma=0.2)

    (1)从头训练 (from scratch): 直接按照上面的代码进行训练即可

    (2)finetune all (没有冻结任何层)

    1. cnn.load_state_dict(torch.load(path))
    2. inchannel = cnn.fc.in_features
    3. cnn.fc = nn.Linear(inchannel, args.num_class)

    注意:

    a) 在load_state_dict时候,应该使用默认的 1000 类(因为我用的imagenet1k的预训练参数),加载完后才改变成指定的 args.num_class

    b) path指的是预训练的参数的地址:可以使用torchvision上提供好的(为了方便我也粘贴一下)

    Resnet18: https://download.pytorch.org/models/resnet18-f37072fd.pth

    Resnet34: https://download.pytorch.org/models/resnet34-b627a593.pth

    Resnet50: https://download.pytorch.org/models/resnet50-0676ba61.pth

     (3) linear probing (冻结了浅层)

    1. cnn.load_state_dict(torch.load(path))
    2. inchannel = cnn.fc.in_features
    3. cnn.fc = nn.Linear(inchannel, args.num_class)
    4. for k, v in cnn.named_parameters():
    5. if k.split('.')[0] != 'fc':
    6. v.requires_grad = False

    但是linear层的微调性能远不如全部finetune,因为可变的层太少了,对于linear层而言,搞不定。

    此外,需要注意的一点,我们若不加 .eval() 那么BN和Dropout是默认开的,训练时候如果浅层不参与训练但开着这些层,会让 fc 层更难。 所以我们可以:

    1. cnn.eval()
    2. cnn.fc.train()

  • 相关阅读:
    2.5 注释
    YYGH-8-预约挂号
    Python后端Flask学习项目实践---搭建一个问答网站
    Ubuntu 系统使用 Visual Studio Code(vs code) 跑 C++项目(工具环境)
    网络编程详细介绍()
    vue navbar tabbar导航条根据位置移动实现定位、颜色过渡动画效果
    Docker入门学习:基本概念、安装、命令、简单使用
    浅谈我国产业园区未来的发展方向
    软考备考-程序员-备考笔记
    前端面试题总结
  • 原文地址:https://blog.csdn.net/zjs975584714/article/details/127551752