# 教程 2:如何微调模型 本教程介绍如何使用预训练模型在其他数据集上进行微调。 - [概要](#%E6%A6%82%E8%A6%81) - [修改 Head](#%E4%BF%AE%E6%94%B9-Head) - [修改数据集](#%E4%BF%AE%E6%94%B9%E6%95%B0%E6%8D%AE%E9%9B%86) - [修改训练策略](#%E4%BF%AE%E6%94%B9%E8%AE%AD%E7%BB%83%E7%AD%96%E7%95%A5) - [使用预训练模型](#%E4%BD%BF%E7%94%A8%E9%A2%84%E8%AE%AD%E7%BB%83%E6%A8%A1%E5%9E%8B) ## 概要 对新数据集上的模型进行微调需要进行两个步骤: 1. 增加对新数据集的支持。详情请见 [教程 3:如何增加新数据集](3_new_dataset.md) 2. 修改配置文件。这部分将在本教程中做具体讨论。 例如,如果用户想要微调 Kinetics-400 数据集的预训练模型到另一个数据集上,如 UCF101,则需要注意 [配置文件](1_config.md) 中 Head、数据集、训练策略、预训练模型四个部分,下面分别介绍。 ## 修改 Head `cls_head` 中的 `num_classes` 参数需改为新数据集中的类别数。 预训练模型中,除了最后一层外的权重都会被重新利用,因此这个改动是安全的。 例如,UCF101 拥有 101 类行为,因此需要把 400 (Kinetics-400 的类别数) 改为 101。 ```python model = dict( type='Recognizer2D', backbone=dict( type='ResNet', pretrained='torchvision://resnet50', depth=50, norm_eval=False), cls_head=dict( type='TSNHead', num_classes=101, # 从 400 改为 101 in_channels=2048, spatial_type='avg', consensus=dict(type='AvgConsensus', dim=1), dropout_ratio=0.4, init_std=0.01), train_cfg=None, test_cfg=dict(average_clips=None)) ``` 其中, `pretrained='torchvision://resnet50'` 表示通过 ImageNet 预训练权重初始化 backbone。 然而,模型微调时的预训练权重一般通过 `load_from`(而不是 `pretrained`)指定。 ## 修改数据集 MMAction2 支持 UCF101, Kinetics-400, Moments in Time, Multi-Moments in Time, THUMOS14, Something-Something V1&V2, ActivityNet 等数据集。 用户可将自建数据集转换已有数据集格式。 对动作识别任务来讲,MMAction2 提供了 `RawframeDataset` 和 `VideoDataset` 等通用的数据集读取类,数据集格式相对简单。 以 `UCF101` 和 `RawframeDataset` 为例, ```python # 数据集设置 dataset_type = 'RawframeDataset' data_root = 'data/ucf101/rawframes_train/' data_root_val = 'data/ucf101/rawframes_val/' ann_file_train = 'data/ucf101/ucf101_train_list.txt' ann_file_val = 'data/ucf101/ucf101_val_list.txt' ann_file_test = 'data/ucf101/ucf101_val_list.txt' ``` ## 修改训练策略 通常情况下,设置较小的学习率,微调模型少量训练批次,即可取得较好效果。 ```python # 优化器 optimizer = dict(type='SGD', lr=0.005, momentum=0.9, weight_decay=0.0001) # 从 0.01 改为 0.005 optimizer_config = dict(grad_clip=dict(max_norm=40, norm_type=2)) # 学习策略 lr_config = dict(policy='step', step=[20, 40]) # step 与 total_epoch 相适应 total_epochs = 50 # 从 100 改为 50 checkpoint_config = dict(interval=5) ``` ## 使用预训练模型 若要将预训练模型用于整个网络(主干网络设置中的 `pretrained`,仅会在主干网络模型上加载预训练参数),可通过 `load_from` 指定模型文件路径或模型链接,实现预训练权重导入。 MMAction2 在 `configs/_base_/default_runtime.py` 文件中将 `load_from=None` 设为默认。由于配置文件的可继承性,用户可直接在下游配置文件中设置 `load_from` 的值来进行更改。 ```python # 将预训练模型用于整个 TSN 网络 load_from = 'https://open-mmlab.s3.ap-northeast-2.amazonaws.com/mmaction/mmaction-v1/recognition/tsn_r50_1x1x3_100e_kinetics400_rgb/tsn_r50_1x1x3_100e_kinetics400_rgb_20200614-e508be42.pth' # 模型路径可以在 model zoo 中找到 ```