系列文章目录
第一课:【OpenMMLab】OpenMMLab概述
第二课:【OpenMMLab】人体姿态估计、关键点检测与MMPose
第三课:【openMMLab】MMPose 代码教程
第四课:【OpenMMLab】深度学习预训练与 MMPreTrain
前言
MMPretrain 是一个全新升级的预训练开源算法框架,旨在提供各种强大的预训练主干网络,并支持不同的预训练策略。
MMPretrain 源自 MMClassification 和MMSelfSup,并开发了许多新功能。预训练阶段对于视觉识别至关重要,凭借丰富而强大的预训练模型,能够用于改进各种下游视觉任务。 代码库旨在成为一个易于使用和用户友好的代码库,并简化学术研究活动和工程任务。
博客视频:https://www.bilibili.com/video/BV1PN411y7C1
代码仓库:https://github.com/open-mmlab/mmpretrain
文档教程:https://mmpretrain.readthedocs.io/en/latest
一、环境安装
关于创建虚拟环境,安装pyorch,安装mmcv环境可以参考 【openMMLab】MMPose 代码教程。本次代码教程主要基于ipython进行讲解。
安装ipython
ipython 调用的是 虚拟环境中的库,所以要在配置好的虚拟环境中安装ipython
# 激活 conda 虚拟环境
conda activate your_env_name
# 安装
pip install ipython
# 打开 ipython
# 简单验证 ipython 的安装
ipython
In [1]: import torch
In [2]: torch.__version__
Out[2]: '2.0.1+cu118'
In [3]: torch.cuda.is_available()
Out[3]: True
In [4]: exit()
下载和安装mmpretrain
# 下载 mmpretrain
git clone https://github.com/open-mmlab/mmpretrain
# 安装 mmpretrain
cd mmpretrain
pip install -e .
mmpretrain API
详细介绍在代码的注释中
# 打开 ipython
ipython
In [1]: import mmpretrain
# 查看 mmpretrain 的版本
In [2]: mmpretrain.__version__
Out[2]: '1.0.0rc8'
# 从mmpretrain中引入一些高阶的api,
# 如get_model, list_models, inference_model 分别用于模型的获取,列举和推理
In[3]: from mmpretrain import get_model, list_models, inference_model
# 获取 图像分类 Image Classification 相关的,含有 resnet18 的模型
In [4]: list_models(task='Image Classification', pattern='resnet18')
out[4]: ['resnet18_8xb16_cifar10', 'resnet18_8xb32_in1k']
# 获取 图像描述 Image Caption 相关的,含有clip的模型
In [5]: list_models(task='Image Caption', pattern='blip')
Out[5]: ['blip-base_3rdparty_caption', 'blip2-opt2.7b_3rdparty-zeroshot_caption']
# list_models 返回的名称是 mmpretrain 中统一使用的模型名称标识
# 可以直接使用这些名称获取对应模型
# 如 ‘resnet18_8xb16_cifar10’ 是 resnet18 在 cifar10 上训练好的模型
# !!!!get_model 得到的模型是没有与训练权重的模型!!!!!!
In [6]: model = get_model('resnet18_8xb16_cifar10')
# 模型的类型是 ImageClassifier, 模型主干为 ResNet_CIFAR
In [7]: type(model)
Out[7]: mmpretrain.models.classifiers.image.ImageClassifier
In [8]: type(model.backbone)
Out[8]: mmpretrain.models.backbones.resnet_cifar.ResNet_CIFAR
# 使用 inference_model 进行模型推理
# get_model 获得的模型并没有加载模型权重,得到的结果是混乱的,我们需要加载对应的模型在对应数据集上的权重
# 可以使用统一的名称,直接推理,会自动加载对应的预训练权重
# show=True 会展示推理结果,如下图所示
In [9]: inference('blip-base_3rdparty_caption', 'demo/cat-dog.png', show=True)
In [10]: exit()
MMPretrain 微调实验
基于MMPretrain,在分类数据集上进行ResNet18的微调实验
准备数据集
这是一个标准的分类数据集,不需要编写额外的数据集加载逻辑;如果需要支持一些特殊格式的数据集,可以在MMPretrain的基础上开发一个新的数据集类。
配置文件
下面介绍 MMPretrain 的配置文件,这也是openmmlab算法库通用的配置文件格式。这是因为MMPretrain中已经集成了很多算法和数据集的支持,对于本次博客使用的微调任务,基本上不需要编写各个组件的代码,直接修改配置文件,配置各个环节的参数即可。
configs文件夹集成了各类算法,包括有监督、无监督及多模态算法的预设。
openmmlab算法库支持进行各种实验,如保存模型参数,分布式训练,训练中断的恢复等等。MMPretrain中已经提供了一整套的训练代码,用户只需修改config文件配置参数,进行各种实验。
本次实验是对ResNet50分类模型进行微调,所以可以参考MMPretrain预设的ResNet50的配置文件
# 查看resnet相关的配置文件
ls configs/resnet
metafile.yml resnet18_8xb16_cifar10.py resnet50_32xb64-warmup-lbs_in1k.py resnet50_8xb256-rsb-a2-300e_in1k.py resnet50_8xb32-fp16_in1k.py resnetv1c152_8xb32_in1k.py
README.md resnet18_8xb32_in1k.py resnet50_8xb128_coslr-90e_in21k.py resnet50_8xb256-rsb-a3-100e_in1k.py resnet50_8xb32_in1k.py resnetv1c50_8xb32_in1k.py
resnet101_8xb16_cifar10.py resnet34_8xb16_cifar10.py resnet50_8xb16_cifar100.py resnet50_8xb32-coslr_in1k.py resnet50_8xb32-lbs_in1k.py resnetv1d101_8xb32_in1k.py
resnet101_8xb32_in1k.py resnet34_8xb32_in1k.py resnet50_8xb16_cifar10.py resnet50_8xb32-coslr-preciseBN_in1k.py resnet50_8xb32-mixup_in1k.py resnetv1d152_8xb32_in1k.py
resnet152_8xb16_cifar10.py resnet50_32xb64-warmup-coslr_in1k.py resnet50_8xb16-mixup_cifar10.py resnet50_8xb32-cutmix_in1k.py resnet50_8xb8_cub.py resnetv1d50_8xb32_in1k.py
resnet152_8xb32_in1k.py resnet50_32xb64-warmup_in1k.py resnet50_8xb256-rsb-a1-600e_in1k.py resnet50_8xb32-fp16-dynamic_in1k.py resnetv1c101_8xb32_in1k.py
# 选择在imagenet1k上预训练的resnet50
# _base_ 中的文件为继承的父文件
cat resnet50_8xb32_in1k.py
_base_ = [
'../_base_/models/resnet50.py', '../_base_/datasets/imagenet_bs32.py',
'../_base_/schedules/imagenet_bs256.py', '../_base_/default_runtime.py'
]
model 配置文件
# 打印 ../_base_/models/resnet50.py
cat ../_base_/models/resnet50.py
# model settings
model = dict(
type='ImageClassifier',
backbone=dict(
type='ResNet',
depth=50,
num_stages=4,
out_indices=(3, ),
style='pytorch'),
neck=dict(type='GlobalAveragePooling'),
head=dict(
type='LinearClsHead',
num_classes=1000,
in_channels=2048,
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
topk=(1, 5),
))
由于只需要修改分类的数量,我们可以加载现有的ResNet50配置后,再修改字典信息即可。
from mmengine import Config
# 加载配置文件
cfg = Config.fromfile('configs/resnet/resnet50_8xb32_in1k.py')
# 查看模型的当前配置
print(cfg.model)
# 修改字典信息 即分类数量
cfg.model.head.num_classes=2
print(cfg.model)
dataset 配置文件
# dataset settings
dataset_type = 'ImageNet'
data_preprocessor = dict(
num_classes=1000,
# RGB format normalization parameters
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
# convert image from BGR to RGB
to_rgb=True,
)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='RandomResizedCrop', scale=224),
dict(type='RandomFlip', prob=0.5, direction='horizontal'),
dict(type='PackInputs'),
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='ResizeEdge', scale=256, edge='short'),
dict(type='CenterCrop', crop_size=224),
dict(type='PackInputs'),
]
train_dataloader = dict(
batch_size=32,
num_workers=5,
dataset=dict(
type=dataset_type,
data_root='data/imagenet',
ann_file='meta/train.txt',
data_prefix='train',
pipeline=train_pipeline),
sampler=dict(type='DefaultSampler', shuffle=True),
)
val_dataloader = dict(
batch_size=32,
num_workers=5,
dataset=dict(
type=dataset_type,
data_root='data/imagenet',
ann_file='meta/val.txt',
data_prefix='val',
pipeline=test_pipeline),
sampler=dict(type='DefaultSampler', shuffle=False),
)
val_evaluator = dict(type='Accuracy', topk=(1, 5))
# If you want standard test, please manually configure the test dataset
test_dataloader = val_dataloader
test_evaluator = val_evaluator
~~ 待更新