mmclassification

mmclassification

一、MMCLS项目

0.下载链接

  • Torch安装方法
- CPU : pip install torch -i https://download.pytorch.org/whl/torch_stable.html  # 指定清华源
- GPU : CUDA和对应的torch版本
- https://download.pytorch.org/whl/torch_stable.html
- https://developer.nvidia.com/cuda-toolkit-archive
  • mmcv
    这里有一个官方出的版本对应表,https://github.com/open-mmlab/mmcv#installation
    1.配置好mmcv后,从GitHub上下载mmclassification的项目。

2.针对configs/resnet/resnet18_8xb16_cifar10.py文件进行说明,8xb16表示8个卡,每个卡的batch_size的大小是16,cifar10表示预训练模型使用的数据集。
configs\resnet\resnet50_8xb32-mixup_in1k.pymixup表示数据增强的策略。
在这里插入图片描述
3.configs/resnet/resnet18_8xb16_cifar10.py配置文件的解释

_base_ = [
    '../_base_/models/resnet18.py', '../_base_/datasets/imagenet_bs32.py',
    '../_base_/schedules/imagenet_bs256.py', '../_base_/default_runtime.py'
]
# 网络结构的定义、数据集的定义、学习的策略(学习率的衰减、学习轮数)、模型保存位置 训练过程的一些

(1)查看../_base_/models/resnet18.py

# model settings
model = dict(
    type='ImageClassifier',                                     # 类名
    backbone=dict(
        type='ResNet',                                          # 选取的backbone,在models/backbones下选择
        depth=18,                                               # 网络层数.
        num_stages=4,                                           # stage的数量
        out_indices=(3, ),                                      # 输出特征层的索引,从0开始
        style='pytorch'),                                       # pytorch和caffee
    neck=dict(type='GlobalAveragePooling'),                     # 对backbone提取到的特征做一些融合策略
    head=dict(                                                  # 输出
        type='LinearClsHead',                                   # FC
        num_classes=1000,                                       # 分类数
        in_channels=512,                                        # 根据backbone和neck来,需要修改
        loss=dict(type='CrossEntropyLoss', loss_weight=1.0),    # 损失函数
        topk=(1, 5),                                            # 评估标准
    ))

type指定源码等会到哪去走,对应一个一个类名,不是瞎写的。比如ImageClassifier去下图中位置寻找在这里插入图片描述
比如ResNet到下图中位置寻找
在这里插入图片描述
之后可以在neck层中进行修改
(2)查看../_base_/datasets/imagenet_bs32.py

# dataset settings
dataset_type = 'ImageNet'                                                           # 后续这里修改成自己的
img_norm_cfg = dict(                                                                # 归一化,均值、标准差
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
    dict(type='LoadImageFromFile'),                                                 # 读图像数据,这些方法在datase_type中有
    dict(type='RandomResizedCrop', size=224),                                       # 随机裁剪
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),                 # 翻转操作
    dict(type='Normalize', **img_norm_cfg),                                         # 归一化
    dict(type='ImageToTensor', keys=['img']),                                       # 转化成Tensor,需要做. keys表示对谁做操作,后面的值在dataset_type 中有
    dict(type='ToTensor', keys=['gt_label']),                                       # 标签转化成Tensor
    dict(type='Collect', keys=['img', 'gt_label'])                                  # 遍历dataloader,返回一个图像和标签
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='Resize', size=(256, -1)),
    dict(type='CenterCrop', crop_size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='Collect', keys=['img'])
]
data = dict(
    samples_per_gpu=32,                                                             # 单卡的batchsize;多卡每张卡的batchsize
    workers_per_gpu=2,
    train=dict(
        type=dataset_type,															# 指定dataset_type,可以自己写之后介绍
        data_prefix='data/imagenet/train',                                          # 读数据。自己数据的路径。不指定标签,拿文件夹的名字当作标签
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        data_prefix='data/imagenet/val',                                            # 读数据
        ann_file='data/imagenet/meta/val.txt',                                      # 读标签
        pipeline=test_pipeline),
    test=dict(
        # replace `data/val` with `data/test` for standard test
        type=dataset_type,
        data_prefix='data/imagenet/val',
        ann_file='data/imagenet/meta/val.txt',
        pipeline=test_pipeline))
evaluation = dict(interval=1, metric='accuracy')                                    # 经过多少epoch,走一遍验证集,metric评估标准

dataset_type = 'ImageNet' 数据的格式,不一定是ImageNet,根据自己的数据选择合适的格式。此处指定ImageNet,就按照mmcls/datasets/imagenet.py中定义的进行读取。
在这里插入图片描述
samples_per_gpu=32, 单卡的batchsize;多卡每张卡的batchsize,如果训练过程中怎么调都会报显存,那就把以下代码中size的值调小。

train_pipeline = [
    dict(type='LoadImageFromFile'),                                                 # 读图像数据,这些方法在datase_type中有
    dict(type='RandomResizedCrop', size=224), 

(3)查看../_base_/schedules/imagenet_bs256.py

# optimizer
optimizer = dict(type='SGD', lr=0.1, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)						# 这个值不改
# learning policy 学习率衰减
lr_config = dict(policy='step', step=[30, 60, 90])          # 迭代多少次(step指定)之后开始衰减
runner = dict(type='EpochBasedRunner', max_epochs=100)      # 迭代epoch的次数

(4)查看../_base_/default_runtime.py

# checkpoint saving
checkpoint_config = dict(interval=1)            # 修改,此处是1个epoch进行保存
# yapf:disable
log_config = dict(
    interval=100,                               # 迭代多少次数,保存日志的信息
    hooks=[
        dict(type='TextLoggerHook'),
        # dict(type='TensorboardLoggerHook')
    ])
# yapf:enable

dist_params = dict(backend='nccl')
log_level = 'INFO'
load_from = None                                # 从哪加载模型
resume_from = None                              # 从上一个epoch中保存的checkpoint继续训练
workflow = [('train', 1)]                       # 默认值,单卡

二、生成完整的配置文件

指定所选模型的路径,在mmclassification的目录下,如D:\E\mmlab\mmclassification-master\tools\train.py,指定train.py中参数的路径,比如D:\E\mmlab\mmclassification-master\configs\resnet\resnet18_8xb32_in1k.py,运行一下train.py,执行之后会在此处D:\E\mmlab\mmclassification-master\tools\work_dirs\resnet18_b32x8_imagenet\resnet18_b32x8_imagenet.py生成配置文件。复制到D:\E\mmlab\mmclassification-master\configs\resnet路径下,并将其命名为my_resnet18_b32x8_imagenet.py

三、根据文件夹定义数据集

方法一:根据文件夹定义数据集,此方法适用于flower_data这类型的数据
(1)首先,修改上面生成的配置文件中的num_classes,此处以flower_data数据集进行说明,一共有102个种类,所以num_classes=102。并把mmcls/datasets/imagenet.pyCLASSES =[]进行修改。
(2)修改data中data_prefix字段,读数据的路径,如果省略掉ann_file,就直接把文件夹的名字当作标签的类别
(3)修改checkpoint_config的值,checkpoint_config = dict(interval=50) , 隔50个保存一次
方法二:构建自己的数据集
(1)所有的训练数据集都在一个文件夹下,训练集在train文件夹下。
(2)mmcls/datasets下自己写一个文件,仿照imagenet进行写,看人家怎么写,自己怎么写。

import numpy as np

from .builder import DATASETS
from .base_dataset import BaseDataset


@DATASETS.register_module()
class MyFilelist(BaseDataset):              # 继承BaseDataset,所以下面用到的self.ann_file和self.data_prefix就是从这来的
    CLASSES = [
        '我懒得写名字了,有102个。。。',
        '我懒得写名字了,有102个。。。',
        ………,
        '我懒得写名字了,有102个。。。',
        '我懒得写名字了,有102个。。。'
    ]

    def load_annotations(self):
        assert isinstance(self.ann_file, str)

        data_infos = []
        with open(self.ann_file) as f:
            samples = [x.strip().split(' ') for x in f.readlines()]
            for filename, gt_label in samples:
                info = {'img_prefix': self.data_prefix}
                info['img_info'] = {'filename': filename}
                info['gt_label'] = np.array(gt_label, dtype=np.int64)
                data_infos.append(info)
            return data_infos

(3)在mmcls/datasets\__init__中把自己定义的数据集处理进行加载,操作如下。
在这里插入图片描述
(4)在生成的完整配置文件中进行修改,数据部分要修改成以下格式,train、valid、test

type='MyFilelist',
data_prefix='D:\\eclipse-workspace\\PyTorch4\\mmclassification-master\\mmcls\\data\\flower_data\\train_filelist',
ann_file='D:\\eclipse-workspace\\PyTorch4\\mmclassification-master\\mmcls\\data\\flower_data\\train.txt',

四、测试demo的效果

(1)demo/image_demo.py下进行简单的测试

image_05094.jpg ../configs/resnet/today_resnet18_8xb32_in1k.py ../tools/work_dirs/resnet18_8xb32_in1k/epoch_100.pth

通过命令行分别指定img、config、checkpoint,通过这样进行单张图片的测试。

(2)测试评估模型效果:在tools/test.py文件下进行

#../configs/resnet/today_resnet18_8xb32_in1k.py ../tools/work_dirs/resnet18_8xb32_in1k/epoch_100.pth --show
#--show-dir ../tools/work_dirs/resnet18_8xb32_in1k/val_result
#--metrics accuracy recall

通过指定以上参数,进行批量数据的测试。

五、MMCLS中增加一个新的模块

在生成的完整配置文件中进行修改。
backbone一般是替换。
1.修改Neck层
有哪些可以换呢?在mmcls/models/necks地方寻找。
2.head层中的损失函数
如果自己想加一个损失函数,示例如下:
在这里插入图片描述
然后在__init__中添加
最后在配置文件中进行修改
3.添加数据增强
mmcls/datasets/pipelines/transforms.py中有一些数据增强的操作。添加一个数据处理的操作,如下:
在这里插入图片描述
4.可以指定预训练模型,通过load_from参数
5.添加mixup操作
configs/resnet/resnet50_b32x8_mixup_imagenet.py 文件中看到

_base_ = 'resnet50_8xb32-mixup_in1k.py'

_deprecation_ = dict(
    expected='resnet50_8xb32-mixup_in1k.py',
    reference='https://github.com/open-mmlab/mmclassification/pull/508',
)

然后去_base_指定的文件中,把train_cfg复制到自己的配置文件中head层中,并修改num_classes参数
在这里插入图片描述
在这里插入图片描述

六、数据增强流程可视化展示

tools/visualizations文件夹下,有一个可视化的模块。有3个文件,vis_cam.pyvis_lr.pyvis_pipeline.pyvis_cam.py是哪里是图像中关注的区域、vis_lr.py学习率的可视化变化、vis_pipeline.py图像由输入经过旋转、平移、缩放操作,最终放到模型当中,可视化这一系列操作是怎么做的,经历哪些阶段。(在输入模型之前都经历了哪些操作)
(1)vis_pipeline.py的介绍
常用参数的介绍:
config:配置文件的指定
--output-dir:输出图像的设置路径
--phase:选择可视化的数据集train、test、val
--number:选择可视化图像的数量
--mode:展示的模式,展示原始图像original,……

"original" means show images load from disk'
'; "transformed" means to show images after transformed; "concat" '
'means show images stitched by "original" and "output" images. '
'"pipeline" means show all the intermediate images. Default concat.'

--show:whether to display images in pop-up window. Default False.
--mode指定pipeline结果示例:
在这里插入图片描述
--mode指定transformed结果示例:转化完之后的结果示例
在这里插入图片描述
--mode指定concat结果示例:
在这里插入图片描述

(2)vis_cam.py的介绍,Grad-Cam可视化方法,可视化细节与效果分析

  • 首先需要安装pip install "grad-cam>=1.3.6"
  • 指定参数imgconfigcheckpoint--target-category表示The target category to get CAM、--target-layers可以指定查看哪一层特征图的CAM,默认是最后一层–the norm layer in the last block、--preview-model添加这个参数,会打印出模型的结构,其余参数不起作用了
  • 指定参数的示例
cat-dog.png ../../configs/resnet/resnet18_8xb32_in1k.py D:\\E\\mmlab\\mmclassification-master\\mmcls\\data\\resnet18_8xb32_in1k_20210831-fbbb1da6.pth
--target-category 238 --target-category 281

cat-dog.png ../../configs/resnet/resnet18_8xb32_in1k.py D:\\E\\mmlab\\mmclassification-master\\mmcls\\data\\resnet18_8xb32_in1k_20210831-fbbb1da6.pth
--target-layers backbone.layer2.1.conv2

七、模型分析脚本使用

tools/analysis_tools中绘制的图还不是很好看:analysis_logslog中有一些指标,打印出的,可以画出来get_flops.py所需的参数量和计算量
1.绘制评估结果,loss的结果图。
此目录下有日志文件
在这里插入图片描述
参数设置示例:

plot_curve ../work_dirs/resnet18_b32x8_imagenet/20220601_112055.log.json --keys loss accuracy_top-1

2.计算迭代时间
参数设置示例

cal_train_time ../work_dirs/resnet18_b32x8_imagenet/20220601_112055.log.json

平均一次迭代所需花的时间
在这里插入图片描述
3.get_flops.py所需的参数量和计算量
参数设置示例:

../../configs/resnet/today_resnet18_b32x8_imagenet.py --shape 224 224

在这里插入图片描述
参数量和训不训练没关系。和模型以及输入图像的大小有关。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值