利用MMPreTrain微调图像分类模型
利用MMPreTrain微调图像分类模型
羽星_s
前言
MMPreTrain是一款基于PyTorch的开源深度学习预工具箱,是OpenMMLab项目的成员之一
MMPreTrain的主要特性有:
支持多元化的主干网络与预训练模型
支持多种训练策略(有监督学习,无监督学习,多模态学习等)
提供多种训练技巧
大量的训练配置文件
高效率和高可扩展性
功能强大的工具箱,有助于模型分析和实验
支持多个开箱即用的推理任务
图片分类
图片描述(图片说明)
视觉问答(Visual Question Answering)
视觉定位(Visual Grounding)
搜索(图搜图,图搜文,文搜图)
本文主要演示如何使用MMPreTrain,对图像分类任务,微调vision_transformer模型
分类数据使用kaggle平台中的Animal Faces数据集,(https://www.kaggle.com/datasets/andrewmvd/animal-faces)运行环境为kaggle GPU P100
环境安装
因为需要对模型进行可解释分析,需要安装grad-cam包,mmcv的安装方式在我前面的mmdetection和mmsegmentation教程中都有写到。这里不再提
mmpretrain安装方法最好是使用git,如果没有git工具,可以使用mim install mmpretrain
最后在项目文件夹下新建checkpoint、outputs、data文件夹,分别用来存放模型预训练权重、模型输出结果、训练数据
from IPython import display
在上面的安装工作完成后,我们检查一下环境,以及核对一下安装版本
import mmcv
输出:
MMCV版本 2.0.1
因为mmpretrain适用于很多种任务,因此在进行图像分类模型微调时先查看一下支持该任务的模型有哪些,可以调用list_models函数查看,因为我们想要微调vision_transformer模型,可以加上限制条件vit进行更精准的筛选
from mmpretrain import list_models, inference_model
这里以候选列表中的vit-base-p32_in21k-pre_3rdparty_in1k-384px模型为例
模型推理
进入项目文件夹configs/vision_transformer,查看模型型号对应预训练权重及config文件
下载预训练权重,对示例图片进行推理
from mmpretrain import ImageClassificationInferencer
查看推理结果
result[0].keys()
输出:
dict_keys(['pred_scores', 'pred_label', 'pred_score', 'pred_class'])
打印分类置信度最高类别的名称,以及置信度
# 置信度最高类别的名称
house finch, linnet, Carpodacus mexicanus
微调模型
将数据集移到data目录下,准备训练
# animal数据集移动
配置文件解析
MMPreTrain配置文件和mmdetection、mmsegmentation有点不太一样,当你打开vit-base-p32_in21k-pre_3rdparty_in1k-384px的配置文件vit-base-p32_64xb64_in1k-384px.py时,会发现配置文件中只显式的定义了数据管道及处理方式
但实际上数据处理和优化器参数都被隐形定义在_base_下了,详细情况可以看下面的代码注释
_base_ = [
打开../_base_/models/vit-base-p32.py文件,查看模型配置
model = dict(
打开../_base_/datasets/imagenet_bs64_pil_resize.py文件,查看数据配置
dataset_type = 'ImageNet' # 预处理配置
打开../_base_/schedules/imagenet_bs4096_AdamW.py文件,查看训练策略配置
optim_wrapper = dict(
打开../_base_/default_runtime.py文件,查看默认运行设置
# 默认所有注册器使用的域
修改配置文件
根据上述说明,这里提供两种修改配置文件的方法。
第1种是将共5个配置文件的信息写在一个新的配置文件vit-base-p32_1xb64_in1k-384px_animal.py中,然后修改其中的内容。
首先将配置文件vit-base-p32_64xb64_in1k-384px.py中的内容更新到继承的键值对中,比如model中的img_size=384,train_pipeline和test_pipeline也都需要改
然后更改num_classes、dataset_type、train_dataloader、val_dataloader、val_evaluator、lr、param_scheduler、default_hooks、randomness
需要注意的是dataset_type要改成'CustomDataset',而'CustomDataset'中是没有split键的,所以要删掉train_dataloader、val_dataloader中的split键
因为分类数量较少,不足5类,所以将val_evaluator中的topk由(1, 5)改成5
lr要与原batch的lr进行等比例缩放,缩放率为32/(64 * 64)(由配置文件名64xb64可知,原batch_size为64 * 64)
因为只训练100个epoch,所以LinearLR scheduler中的end键也进行等比例缩放,即除以3。则CosineAnnealingLR scheduler中的T_max、begin、end相应变化
因为模型在前20个epoch可能没有学习成果,所以没有验证的必要,这里加入val_begin键,表示从第20个epoch开始在验证集上计算指标,验证的频率也不需要1个epoch一次,这里改成5个epoch验证一次
我们想要模型没10个epoch自动保存一次权重,并且最多同时保留两个训练权重,同时根据指标自动保留精度最高的训练权重checkpoint = dict(type='CheckpointHook', interval=10, max_keep_ckpts=2, save_best='auto')
记录频率100(单位:iter)有点太低,我们改成10
最后固定随机数种子randomness
custom_config = """
第2种方法是先将默认配置文件读取,然后再通过python的字典特性进行更改,优点是,只改动需要改动的地方,逻辑清晰
缺点是有些在配置文件中的中间变量无效了,比如在配置文件中可以只用定义dataset_type,后面train_dataloader、val_dataloader可以直接使用,但是用字典特性要改两遍
参数的改变和上面的一样,但是代码少很多
# 读取配置文件
max_epochs = 100
启动训练
!python tools/train.py {animal_config}
由于输出日志太长,这里就不全部展示了,打印一下精度最高的模型权重
07/30 13:33:50 - mmengine - INFO - Epoch(val) [55][24/24] accuracy/top1: 99.9333 data_time: 0.2443 time: 0.5068
可以看到模型在验证集上的精度为99.93%,可以说非常不错
模型推理
加载精度最高的模型,并对图片进行推理
import glob
输出:
[{'pred_scores': array([9.9998045e-01, 1.3512783e-05, 6.0256166e-06], dtype=float32),
绘制混淆矩阵
我们可以绘制混淆矩阵进一步检查模型精度
python tools/analysis_tools/confusion_matrix.py \
类别激活图(CAM)可视化
使用类别激活图(CAM)对分类图像进行解释,更多参数设置请参照官方文档(https://mmpretrain.readthedocs.io/zh_CN/latest/useful_tools/cam_visualization.html)
!python tools/visualization/vis_cam.py \
from PIL import Image
T-SNE可视化
通过降维可视化可以进一步观察模型对类别分界线是否明显,还可以找到模型容易误判的类别
python tools/visualization/vis_tsne.py \