【七班】MMPretrain代码课与作业

目录

写在前面

对应理论课程

对应理论笔记

Github作业提交链接

MMPretrain环境搭建与配置 

安装指定分支的 MMEngine MMEngine new_config 环境搭建

算法库适配

 源码编译 MMCV

测试环境

测试模型

Error:

解决方案:更换mmpretrain版本

config介绍

为什么需要config?

config变量介绍

实验

下载解压数据集查看数据集

自动分数据集脚本 参考自  https://bbs.csdn.net/topics/615807222

config文件

resnet18_fintune.py

resnet18_fintuneM.py

resnet18_fintuneM2.py  继承机制,简单明了

修改要点

checkpoint model weight 链接寻找链接和截图

命令行工具

训练日志

测试日志

Analyse文件夹

 混淆矩阵打印

问题:中文显示:标签方框&analysis图片中中文显示

解决方案

 测试val数据集并可视化

Success

Fail

自己的图片测试

网上下载数据如下

执行脚本代码

输出结果

往期笔记


写在前面

对应理论课程

【课程名称】目标检测与MMDetection
【课程链接】https://www.bilibili.com/video/BV1Ak4y1p7W9/
【讲师介绍】王若晖  OpenMMLab青年研究员

对应理论笔记

深度学习预训练与MMPretrain - 知乎

Github作业提交链接

题目:基于 ResNet50 的水果分类

背景:使用基于卷积的深度神经网络 ResNet50 对 30 种水果进行分类

任务

  1. 划分训练集和验证集
  2. 按照 MMPreTrain CustomDataset 格式组织训练集和验证集
  3. 使用 MMPreTrain 算法库,编写配置文件,正确加载预训练模型
  4. 在水果数据集上进行微调训练
  5. 使用 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值