目录
安装指定分支的 MMEngine MMEngine new_config 环境搭建
自动分数据集脚本 参考自 https://bbs.csdn.net/topics/615807222
resnet18_fintuneM2.py 继承机制,简单明了
checkpoint model weight 链接寻找链接和截图
写在前面
对应理论课程
【课程名称】目标检测与MMDetection
【课程链接】https://www.bilibili.com/video/BV1Ak4y1p7W9/
【讲师介绍】王若晖 OpenMMLab青年研究员
对应理论笔记
Github作业提交链接
题目:基于 ResNet50 的水果分类
背景:使用基于卷积的深度神经网络 ResNet50 对 30 种水果进行分类
任务
- 划分训练集和验证集
- 按照 MMPreTrain CustomDataset 格式组织训练集和验证集
- 使用 MMPreTrain 算法库,编写配置文件,正确加载预训练模型
- 在水果数据集上进行微调训练
- 使用 MMPreTrain 的 ImageClassificationInferencer 接口,对网络水果图像,或自己拍摄的水果图像,使用训练好的模型进行分类
需提交的验证集评估指标(不能低于 60%)
MMPretrain环境搭建与配置
安装指定分支的 MMEngine MMEngine new_config 环境搭建
git clone -b new_config_type https://github.com/HAOCHENYE/mmengine.git mmengine_new_config
cd mmengine_new_config
# 如果是新环境,没有安装 MMEngine 相关的依赖,需执行
pip install -e .
算法库适配
基于 new_config 分支,源码编译算法库
# mmpretrain
https://github.com/open-mmlab/mmpretrain/tree/new_config
pip install -U openmim -i https://pypi.tuna.tsinghua.edu.cn/simple
git clone https://github.com/open-mmlab/mmpretrain.git -b new_config
cd mmpretrain
mim install -e ".[multimodal]" -i https://pypi.tuna.tsinghua.edu.cn/simple
源码编译 MMCV
git clone https://github.com/open-mmlab/mmcv.git
cd mmcv
MMCV_WITH_OPS=1 pip install -e .
注意:
1. -b new_config 是为了切换支持mmengine的分支
2. 此处的“.[multimodal]”为添加多模态依赖,代表要安装多模态相关的额外依赖,
3. MMCV_WITH_OPS=1 切换到和mmpretrain 配合使用的分支
4. 编译安装mmcv时会很慢,请耐心等待
测试环境
import torch, torchvision
import mmpretrain
import mmcv
import mmengine
from mmcv.ops import get_compiling_cuda_version, get_compiler_version
print('Pytorch 版本', torch.__version__)
print('CUDA 是否可用',torch.cuda.is_available())
print('MMCV版本', mmcv.__version__)
print('CUDA版本', get_compiling_cuda_version())
print('编译器版本', get_compiler_version())
print('mmcv版本',mmcv.__version__)
print('mmengine版本',mmengine.__version__)
print('mmpretrain版本', mmpretrain.__version__)
Pytorch 版本 1.10.1+cu113
CUDA 是否可用 True
MMCV版本 2.0.0
CUDA版本 11.6
编译器版本 GCC 11.3
mmcv版本 2.0.0
mmengine版本 0.7.4
mmpretrain版本 1.0.0rc7
测试模型
from mmpretrain import get_model,list_models,inference_model
list_models(task="Image Classification",pattern="resnet18")
model = get_model("resnet18_8xb16_cifar10") #加载模型
inference_model(model,"demo/bird.JPEG",show=True) #推理
from mmpretrain import get_model,list_models,inference_model
list_models(task="Image Caption",pattern="blip")
model = get_model("blip-base_3rdparty_caption") #加载模型
inference_model(model,"demo/bird.JPEG",show=True) #推理
先贴一下正确的结果,这里因为没加预训练模型权重,所以结果很差
Error:
但是后面做猫狗预测的时候,更换预测器,出问题了
mmpretrain rc7版本,调用ImageClassificationInferencer,会出现 no attribute 'show_progress' 和unexpected keyword argument show 的error
解决方案:更换mmpretrain版本
# mim install -e ".[multimodal]"
mim install "mmpretrain[multimodal]>=1.0.0rc8"
config介绍
这里参考了一位同学的笔记,找不到链接了,晚点加上
为什么需要config?
因为深度学习网络的深度往往比较大,假设我们需要修改某个网络的通道数,涉及到要修改的代码会比较多,比较费时
而是用config,只要我们在config上配置好,让网络去取config上的变量,即可实现更改网络参数,而不用频繁的取修改网络的代码
config变量介绍
__base__:这是openmmlab2.0以后才有的参数,用于继承已有config变量,这样就可以做到将一些通用的config参数放到公共位置,让所有的config去继承,做到参数复用
model:模型结构的配置,字典格式,其中type指定了网络的类型(mmpretrain中的model下的class),而其它参数则是这个网络class的初始化参数。个别网络class可通过backbone变量指定主干网络类,以及head指定网络的任务头
data_preprocessor:原本是模型model的变量,在mmpretrain中可以单独拿出来,主要功能是网络拿到数据之前对数据的一些操作(归一化,bgr转rgb等操作)。
train_pipeline/test_pipeline/val_pipeline:训练/测试/验证流程,将训练/测试/验证前的一些数据处理写道这个列表中,包括读取图像,数据增强的操作
train_dataloader/test_dataloader/val_dataloader:加载训练/测试/验证集以及一些与训练/测试/验证集相关的超参数(例如分类数量)
optim_wrapper:优化器配置,主要是指定学习率,优化器类型
param_scheduler:学习率的参数优化器,会根据需求优化学习率
train_cfg/val_cfg/test_cfg:训练/测试/验证的流程设置,要主要时对epoch大小进行设置,以及规定多少个epoch做一次验证,为空时表示使用默认设置
auto_scaler_lr:在训练当中如果batchsize变了,则根据此处设置自动缩放学习率
default_hook:运行参数,一般都不需要去修改这里的参数,常用的有两个
- logger:设置每多少个epoch打印一次日志
- checkpoint:设置每多少个epoch保存一次checkpoint,也可以通过设置max_keep_ckpts=n,来只保留最后的n个checkpoint,还可以通过save_best='auto' 来根据验证集的验证结果始终保留精度最高的模型
randomness:随机性相关设计,一般不改动,默认时没有随机种子,而是在训练的时候随机一个,如果像复现训练过程,则要在此处指定随机种子seed
值引用修改:如果我们在配置文件里定义了一个dataset_type,并在train_dataloader中引用这个dataset_type,然后在训练过程中修改cfg的dataset_type,train_dataloader中的dataset_type是不会变的,因为在训练的就已经完成了值引用,后续cfg里的dataset_type怎么改变都不会影响train_dataloader中的dataset_type
实验
下载解压数据集查看数据集
水果数据集下载:
百度网盘 提取码:52m9
google drive:
https://drive.google.com/file/d/1mdBfo8tCX0OoIP_h0OI9_FMLiD-2pNg2/
猫狗数据集下载地址:
https://download.openmmlab.com/mmclassification/dataset/cats_dogs_dataset.tar
sudo apt install gthumb
gthumb test_set/cats/ # 浏览图片神器
由于猫狗数据集和水果数据集的配置文件十分类似,这里后续只以水果数据集作为举例书写笔记。
水果蔬菜种类:30
哈密瓜 山竹 柚子 桂圆 椰子 火龙果 石榴 胡萝卜 芒果 草莓 菠萝
葡萄-红 葡萄-白 西红柿 香蕉 圣女果 杨梅 柠檬 梨 榴莲 猕猴桃 砂糖橘 脐橙
苦瓜 苹果-红 苹果-青 荔枝 西瓜 车厘子 黄瓜
自动分数据集脚本 参考自 https://bbs.csdn.net/topics/615807222
如果是需要ann_file,可以参考另一个文件split_data.py (github.com)
import os
# 获取数据集文件夹路径
CustomDatasetPath = r'../../data/fruit'
# 获取数据集文件夹下的所有文件
CustomDatasetFile = os.listdir(CustomDatasetPath)
# 如果文件夹中不存在train、val、test文件夹,则创建
dataset_type = ['train', 'val', 'test']
for type in dataset_type:
if type not in CustomDatasetFile:
os.mkdir(os.path.join(CustomDatasetPath, type))
else:
# 清空文件夹
os.removedirs(os.path.join(CustomDatasetPath, type))
# 遍历所有文件
for fruit_name in CustomDatasetFile:
for type in dataset_type:
os.mkdir(os.path.join(CustomDatasetPath, type, fruit_name))
# 水果文件夹路径
fruit_path = os.path.join(CustomDatasetPath, fruit_name)
# 获取水果文件夹下的所有文件
fruit_file = os.listdir(fruit_path)
# 将水果文件夹下的所有文件分为训练集、验证集、测试集
train_file = fruit_file[:int(len(fruit_file)*0.8)]
val_file = fruit_file[int(len(fruit_file)*0.8):int(len(fruit_file)*0.9)]
test_file = fruit_file[int(len(fruit_file)*0.9):]
# 将训练集、验证集、测试集分别放入对应文件夹
for file in train_file:
os.rename(os.path.join(fruit_path, file), os.path.join(CustomDatasetPath, 'train', fruit_name, file))
for file in val_file:
os.rename(os.path.join(fruit_path, file), os.path.join(CustomDatasetPath, 'val', fruit_name, file))
for file in test_file:
os.rename(os.path.join(fruit_path, file), os.path.join(CustomDatasetPath, 'test', fruit_name, file))
# 删除空文件夹
os.removedirs(fruit_path)
查看数据种类和数据集个数
$ tree ./train/ --filelimit=30
./
├── 哈密瓜 [120 entries exceeds filelimit, not opening dir]
├── 圣女果 [122 entries exceeds filelimit, not opening dir]
├── 山竹 [114 entries exceeds filelimit, not opening dir]
├── 杨梅 [119 entries exceeds filelimit, not opening dir]
├── 柚子 [118 entries exceeds filelimit, not opening dir]
├── 柠檬 [95 entries exceeds filelimit, not opening dir]
├── 桂圆 [122 entries exceeds filelimit, not opening dir]
├── 梨 [120 entries exceeds filelimit, not opening dir]
├── 椰子 [123 entries exceeds filelimit, not opening dir]
├── 榴莲 [118 entries exceeds filelimit, not opening dir]
├── 火龙果 [116 entries exceeds filelimit, not opening dir]
├── 猕猴桃 [120 entries exceeds filelimit, not opening dir]
├── 石榴 [120 entries exceeds filelimit, not opening dir]
├── 砂糖橘 [113 entries exceeds filelimit, not opening dir]
├── 胡萝卜 [116 entries exceeds filelimit, not opening dir]
├── 脐橙 [120 entries exceeds filelimit, not opening dir]
├── 芒果 [105 entries exceeds filelimit, not opening dir]
├── 苦瓜 [115 entries exceeds filelimit, not opening dir]
├── 苹果-红 [113 entries exceeds filelimit, not opening dir]
├── 苹果-青 [120 entries exceeds filelimit, not opening dir]
├── 草莓 [122 entries exceeds filelimit, not opening dir]
├── 荔枝 [124 entries exceeds filelimit, not opening dir]
├── 菠萝 [121 entries exceeds filelimit, not opening dir]
├── 葡萄-白 [99 entries exceeds filelimit, not opening dir]
├── 葡萄-红 [124 entries exceeds filelimit, not opening dir]
├── 西瓜 [119 entries exceeds filelimit, not opening dir]
├── 西红柿 [118 entries exceeds filelimit, not opening dir]
├── 车厘子 [103 entries exceeds filelimit, not opening dir]
├── 香蕉 [116 entries exceeds filelimit, not opening dir]
└── 黄瓜 [112 entries exceeds filelimit, not opening dir]
config文件
resnet18_fintune.py
原始的resnet18_8xb32_in1k.py中__base__中提到的几个文件中的内容复制进去,后面会对这个文件修改或者作为继承文件
# _base_ = [
# '../_base_/models/resnet18.py', '../_base_/datasets/imagenet_bs32.py',
# '../_base_/schedules/imagenet_bs256.py', '../_base_/default_runtime.py'
# ]
# model settings
model = dict(
type='ImageClassifier',
backbone=dict(
type='ResNet',
depth=18,
num_stages=4,
out_indices=(3, ),
style='pytorch'),
neck=dict(type='GlobalAveragePooling'),
head=dict(
type='LinearClsHead',
num_classes=1000,
in_channels=512,
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
topk=(1, 5),
))
# 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
# optimizer
optim_wrapper = dict(
optimizer=dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001))
# learning policy
param_scheduler = dict(
type='MultiStepLR', by_epoch=True, milestones=[30, 60, 90], gamma=0.1)
# train, val, test setting
train_cfg = dict(by_epoch=True, max_epochs=100, val_interval=1)
val_cfg = dict()
test_cfg = dict()
# NOTE: `auto_scale_lr` is for automatically scaling LR,
# based on the actual training batch size.
auto_scale_lr = dict(base_batch_size=256)
# defaults to use registries in mmpretrain
default_scope = 'mmpretrain'
# configure default hooks
default_hooks = dict(
# record the time of every iteration.
timer=dict(type='IterTimerHook'),
# print log every 100 iterations.
logger=dict(type='LoggerHook', interval=100),
# enable the parameter scheduler.
param_scheduler=dict(type='ParamSchedulerHook'),
# save checkpoint per epoch.
checkpoint=dict(type='CheckpointHook', interval=1),
# set sampler seed in distributed evrionment.
sampler_seed=dict(type='DistSamplerSeedHook'),
# validation results visualization, set True to enable it.
visualization=dict(type='VisualizationHook', enable=False),
)
# configure environment
env_cfg = dict(
# whether to enable cudnn benchmark
cudnn_benchmark=False,
# set multi process parameters
mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
# set distributed parameters
dist_cfg=dict(backend='nccl'),
)
# set visualizer
vis_backends = [dict(type='LocalVisBackend')]
visualizer = dict(type='UniversalVisualizer', vis_backends=vis_backends)
# set log level
log_level = 'INFO'
# load from which checkpoint
load_from = None
# whether to resume training from the loaded checkpoint
resume = False
# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=None, deterministic=False)
resnet18_fintuneM.py
修改复制esnet18_fintune.py模板中所需修改的参数
# _base_ = [
# '../_base_/models/resnet18.py', '../_base_/datasets/imagenet_bs32.py',
# '../_base_/schedules/imagenet_bs256.py', '../_base_/default_runtime.py'
# ]
# model settings
model = dict(
type='ImageClassifier',
backbone=dict(
type='ResNet',
depth=18,
num_stages=4,
out_indices=(3, ),
style='pytorch'),
neck=dict(type='GlobalAveragePooling'),
head=dict(
type='LinearClsHead',
num_classes=30,
in_channels=512,
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
topk=(1,5),
),
init_cfg = dict(type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet18_8xb32_in1k_20210831-fbbb1da6.pth')
)
# dataset settings
dataset_type = 'CustomDataset'
data_preprocessor = dict(
num_classes=30,
# 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/fruit/train',
# 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',
data_root='../../data/fruit/val',
# ann_file='meta/val.txt',
# data_prefix='val',
pipeline=test_pipeline),
sampler=dict(type='DefaultSampler', shuffle=False),
)
test_dataloader = dict(
batch_size=64,
num_workers=12,
dataset=dict(
type=dataset_type,
# data_root='data/imagenet',
data_root='../../data/fruit/test',
# ann_file='meta/val.txt',
# data_prefix='val',
pipeline=test_pipeline),
sampler=dict(type='DefaultSampler', shuffle=False),
)
val_evaluator = dict(type='Accuracy', topk=(1,))
# If you want standard test, please manually configure the test dataset
test_dataloader = val_dataloader
test_evaluator = val_evaluator
# optimizer
optim_wrapper = dict(
optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001))
# learning policy
param_scheduler = dict(
type='MultiStepLR', by_epoch=True, milestones=[3, 6, 9], gamma=0.5)
# train, val, test setting
train_cfg = dict(by_epoch=True, max_epochs=10, val_interval=2)
val_cfg = dict()
test_cfg = dict()
# # NOTE: `auto_scale_lr` is for automatically scaling LR,
# # based on the actual training batch size.
# auto_scale_lr = dict(base_batch_size=256)
# defaults to use registries in mmpretrain
default_scope = 'mmpretrain'
# configure default hooks
default_hooks = dict(
# record the time of every iteration.
timer=dict(type='IterTimerHook'),
# print log every 100 iterations.
logger=dict(type='LoggerHook', interval=2),
# enable the parameter scheduler.
param_scheduler=dict(type='ParamSchedulerHook'),
# save checkpoint per epoch.
checkpoint=dict(type='CheckpointHook', interval=1, max_keep_ckpts=2, save_best='auto'),
# set sampler seed in distributed evrionment.
sampler_seed=dict(type='DistSamplerSeedHook'),
# validation results visualization, set True to enable it.
visualization=dict(type='VisualizationHook', enable=False),
)
# configure environment
env_cfg = dict(
# whether to enable cudnn benchmark
cudnn_benchmark=False,
# set multi process parameters
mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
# set distributed parameters
dist_cfg=dict(backend='nccl'),
)
# set visualizer
vis_backends = [dict(type='LocalVisBackend')]
visualizer = dict(type='UniversalVisualizer', vis_backends=vis_backends)
# set log level
log_level = 'INFO'
# load from which checkpoint
load_from = None
# whether to resume training from the loaded checkpoint
resume = False
# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=23, deterministic=False)
resnet18_fintuneM2.py 继承机制,简单明了
基于继承机制,继承修改自resnet18_fintune.py
注意:resnet18_fintuneM2.py 与resnet18_fintuneM.py 等价
resnet18_fintuneM.py采用了完整的模板修改,
而resnet18_fintuneM2.py使用继承机制,只呈现了修改的关键参数,更加简单明了
修改要点
- num_class=2 #对应数据集种类个数
- init_cfg = dict(type='Pretrained', checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet18_8xb32_in1k_20210831-fbbb1da6.pth')
checkpoint model weight 链接寻找链接和截图
欢迎来到 MMPretrain 中文教程! — MMPretrain 1.0.0rc8 文档
ResNet — MMPretrain 1.0.0rc8 文档
# _base_ = [
# '../_base_/models/resnet18.py', '../_base_/datasets/imagenet_bs32.py',
# '../_base_/schedules/imagenet_bs256.py', '../_base_/default_runtime.py'
# ]
_base_ = ['./resnet18_fintune.py']
model = dict(
head=dict(
num_classes=2,
),
init_cfg = dict(type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet18_8xb32_in1k_20210831-fbbb1da6.pth')
)
# dataset settings
dataset_type = 'CustomDataset'
data_preprocessor = dict(
num_classes=2
)
train_dataloader = dict(
dataset=dict(
type=dataset_type,
# ann_file=None,
# data_prefix=None,
data_root='../../data/fruit/train',),
)
val_dataloader = dict(
dataset=dict(
type=dataset_type,
# ann_file=None,
# data_prefix=None,
data_root='../../data/fruit/val',),
)
optim_wrapper = dict(
optimizer=dict(lr=0.01,))
train_cfg = dict(by_epoch=True, max_epochs=5, val_interval=2)
# configure default hooks
default_hooks = dict(
# save checkpoint per epoch.
checkpoint=dict(type='CheckpointHook', interval=1, max_keep_ckpts=2, save_best='auto'),
)
# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=23, deterministic=False)
命令行工具
工作目录:~/Documents/GitHub/mmpretrain/projects/cats_dogs$
# 训练
mim train mmpretrain resnet18_fintuneM.py --work-dir=./exp
# 以指定训练权重测试并结果日志保存为pkl备用
mim test mmpretrain resnet18_fintuneM.py --checkpoint exp/epoch_5.pth --out result.pkl
# 对测试集进行分析,生成success和fail文件夹分别存储成功的和不成功的预测结果
mim run mmpretrain analyze_results resnet18_fintuneM.py result.pkl --out-dir analyze
# 生成混淆矩阵,可视化分析预测结果
mim run mmpretrain confusion_matrix resnet18_fintuneM.py result.pkl --show --include-values
训练日志
2023/06/08 17:06:36 - mmengine - INFO - Checkpoints will be saved to /home/cine/Documents/GitHub/mmpretrain/projects/fruits/exp3_resnet50.
2023/06/08 17:06:54 - mmengine - INFO - Epoch(train) [1][100/109] lr: 1.0000e-02 eta: 0:03:01 time: 0.1751 data_time: 0.0004 memory: 2965 loss: 1.2929
2023/06/08 17:06:56 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:06:56 - mmengine - INFO - Saving checkpoint at 1 epochs
2023/06/08 17:07:15 - mmengine - INFO - Epoch(train) [2][100/109] lr: 1.0000e-02 eta: 0:02:38 time: 0.1759 data_time: 0.0004 memory: 2965 loss: 1.0736
2023/06/08 17:07:16 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:07:16 - mmengine - INFO - Saving checkpoint at 2 epochs
2023/06/08 17:07:19 - mmengine - INFO - Epoch(val) [2][7/7] accuracy/top1: 71.3303 accuracy/top5: 93.3486 data_time: 0.0976 time: 0.1949
2023/06/08 17:07:19 - mmengine - INFO - The best checkpoint with 71.3303 accuracy/top1 at 2 epoch is saved to best_accuracy_top1_epoch_2.pth.
2023/06/08 17:07:39 - mmengine - INFO - Epoch(train) [3][100/109] lr: 1.0000e-02 eta: 0:02:18 time: 0.1766 data_time: 0.0004 memory: 2965 loss: 0.7937
.............
2023/06/08 17:09:29 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:09:29 - mmengine - INFO - Saving checkpoint at 8 epochs
2023/06/08 17:09:31 - mmengine - INFO - Epoch(val) [8][7/7] accuracy/top1: 91.5138 accuracy/top5: 98.3945 data_time: 0.0275 time: 0.1280
2023/06/08 17:09:31 - mmengine - INFO - The previous best checkpoint /home/cine/Documents/GitHub/mmpretrain/projects/fruits/exp3_resnet50/best_accuracy_top1_epoch_6.pth is removed
2023/06/08 17:09:32 - mmengine - INFO - The best checkpoint with 91.5138 accuracy/top1 at 8 epoch is saved to best_accuracy_top1_epoch_8.pth.
2023/06/08 17:09:51 - mmengine - INFO - Epoch(train) [9][100/109] lr: 1.0000e-04 eta: 0:00:21 time: 0.1805 data_time: 0.0004 memory: 2965 loss: 0.3272
2023/06/08 17:09:53 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:09:53 - mmengine - INFO - Saving checkpoint at 9 epochs
2023/06/08 17:09:57 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:10:12 - mmengine - INFO - Epoch(train) [10][100/109] lr: 1.0000e-05 eta: 0:00:01 time: 0.1826 data_time: 0.0004 memory: 2965 loss: 0.2552
2023/06/08 17:10:13 - mmengine - INFO - Exp name: resnet50_fintuneM2_20230608_170620
2023/06/08 17:10:13 - mmengine - INFO - Saving checkpoint at 10 epochs
2023/06/08 17:10:15 - mmengine - INFO - Epoch(val) [10][7/7] accuracy/top1: 90.8257 accuracy/top5: 98.8532 data_time: 0.0329 time: 0.1310
测试日志
2023/06/08 17:11:45 - mmengine - WARNING - The prefix is not set in metric class DumpResults.
2023/06/08 17:11:46 - mmengine - INFO - Load checkpoint from exp3_resnet50/best_accuracy_top1_epoch_8.pth
2023/06/08 17:11:47 - mmengine - INFO - Results has been saved to result_resnet50.pkl.
2023/06/08 17:11:47 - mmengine - INFO - Epoch(test) [7/7] accuracy/top1: 91.5138 accuracy/top5: 98.3945 data_time: 0.0964 time: 0.2016
Analyse文件夹
混淆矩阵打印
问题:中文显示:标签方框&analysis图片中中文显示
问题呈现
解决方案
参考 linux服务器上的matplotlib中文字体设置问题
如果本来就没有中文字体,必须先安装并配置字体,保证有中文字体ttf的文件
配置:修改matplotlibrc配置字体
1. 首先定位matplotlib的字体库路径(我使用python进行定位)
import matplotlib
matplotlib.matplotlib_fname()
'~/miniconda3/envs/openmmlab-pose/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc'
2. 将中文字体文件**.ttf,拷贝到该目录的fonts/ttf下
3. 删除 matplotlib 缓存
cd ~/.cache/matplotlib
rm * -r
4. 修改matplotlibrc文件:修改font.sans-serif 加入中文字体
font.sans-serif : SimHei (刚加的字体名字 or , Microsoft YaHei )
5. 重启程序或在 jupyter中restart the kernel
修改之后,就可以出含有中文字符的图了
测试val数据集并可视化
Success
Fail
自己的图片测试
网上下载数据如下
执行脚本代码
from mmpretrain import ImageClassificationInferencer
inferencer = ImageClassificationInferencer('./projects/fruits/resnet18_fintuneM.py',
pretrained='./projects/fruits/exp/epoch_10.pth')
image_list = ['data/apple.jpeg', 'data/banana.jpeg', 'data/fruit.jpeg', 'data/grapes.jpg']
# # 单独对每张图片预测
# for i in range(len(image_list)):
# # result0 = inferencer(image_list[i], show=True)
# result0 = inferencer(image_list[i])
# print(f"file name: {image_list[i]}")
# print(result0[0][list(result0[0].keys())[1]])
# print(result0[0][list(result0[0].keys())[3]])
# print()
# 批量预测
results = inferencer(image_list, batch_size=4)
print_keys = list(results[0].keys())
for i in range(len(image_list)):
print(f"file name: {image_list[i]}")
print(results[i][print_keys[1]])
print(results[i][print_keys[3]])
print()
输出结果
Loads checkpoint by local backend from path: ./projects/fruits/exp/epoch_10.pth
file name: data/apple.jpeg
18
苹果-红
file name: data/banana.jpeg
28
香蕉
file name: data/fruit.jpeg
5
柠檬
file name: data/grapes.jpg
24
葡萄-红
往期笔记
OpenMMLab 开源项目介绍 【OpenMMLab AI实战营 第二期 Day1】 - 知乎
https://zhuanlan.zhihu.com/p/633893792
人体姿态估计概论笔记【OpenMMLab AI实战营第二期Day2】 - 知乎
https://zhuanlan.zhihu.com/p/634214371
MMPose代码实践与耳朵穴位数据集实战【OpenMMLab AI实战营第二期Day3+作业1】 - 知乎
https://zhuanlan.zhihu.com/p/634511756
深度学习预训练与MMPretrain - 知乎
https://zhuanlan.zhihu.com/p/634874025