MMclassfication 自定义数据集训练及可视化

mmclassification基本介绍这里就不过多阐述了,前期因为工作需要需要实现图片的功能,加上因为一直在使用mmlab相关库,所以就选了mmcls。具体其实和其他的mmlab的使用过程类似,基本上可能数据集结构搞定了就能够运行了。

一、自定义数据集

我采用的是ImageNet的数据格式,一方面是省去了注册机制的那些,直接在原有代码基础之上修改,比较方便,另一方面是因为后续的config我用的也是image1k的,可能要面临的问题少一点。

1.mmcls中imagenet的数据格式

总体树状结构如下:
—data
|----meta
|——|—train.txt
|——|—val.txt
|——|—test.txt
|----train
|——|—class1
|————|—01.jpg
|————|—02.jpg
|————|—…
|——|—class2
|————|—01.jpg
|————|—02.jpg
|————|—…
|----test
|——|—class1
|————|—01.jpg
|————|—02.jpg
|————|—…
|——|—class2
|————|—01.jpg
|————|—02.jpg
|————|—…
|----val
|——|—class1
|————|—01.jpg
|————|—02.jpg
|————|—…
|——|—class2
|————|—01.jpg
|————|—02.jpg
|————|—…
如图所示:
在这里插入图片描述

其中,meta里存放的3个是包含图片标签的地址目录:
在这里插入图片描述
在这里插入图片描述
即:path + 空格 + 标签索引
train、val、test三个文件夹存放的都是图片格式文件,如果本身你已经有对应的train.txt等文件,即已经有标签地址之后,你可以把所有图像混着放,如果没有的话,就每个类别建一个文件夹,再生成对应标签。由于我用的是自定义的数据集,所以我采用第二种方法,具体如下:
在这里插入图片描述
在这里插入图片描述

我总共是两个标签,分别是can和cant
train、val、和test三个文件夹我数据是按照7:2:1划分的。
具体先设定一个总的文件夹,该文件夹下面按照标签类别建立文件夹,存放对应的图片
划分的代码我也附上吧。

import os, random, shutil

##############################################################
## 分割数据集,首先将所有数据放在同一个文件夹下###################
def moveFile(fileDir, val_ratio, test_ration2):
    pathDir1 = os.listdir(fileDir)  # 取图片的原始路径
    filenumber = len(pathDir1)
    val_number = int(filenumber * val_ratio)  # 抽取验证集的数量
    test_number = int(filenumber * test_ratio)  # 抽取测试集的数量
    val_sample = random.sample(pathDir1, val_number)  # 随机选取val图片

    # 先抽取验证集图片
    for name1 in val_sample:
        shutil.move(os.path.join(fileDir, name1), os.path.join(valDir, name1))

    # 从剩余的图片中抽取测试集
    pathDir2 = os.listdir(fileDir)  # 取图片的原始路径
    test_sample = random.sample(pathDir2, test_number)  # 随机选取val图片
    for name2 in test_sample:
        shutil.move(os.path.join(fileDir, name2), os.path.join(testDir, name2))

    return


if __name__ == '__main__':
    ori_path = './data/space_all/train'  # 最开始train的文件夹路径
    test_Dir = './data/space_all/test'  # 移动到新的文件夹路径
    val_Dir = './data/space_all/val'  # 移动到新的文件夹路径
    val_ratio, test_ratio = 0.1, 0.2  # 抽取比例  ******自己改*******
    for firstPath in os.listdir(ori_path):
        fileDir = os.path.join(ori_path, firstPath)  # 原图片文件夹路径
        valDir = os.path.join(val_Dir, firstPath)  # val下子文件夹名字
        testDir = os.path.join(test_Dir, firstPath)  # test下子文件夹名字
        if not os.path.exists(valDir):  # 如果val下没有子文件夹,就创建
            os.makedirs(valDir)
        if not os.path.exists(testDir):  # 如果test下没有子文件夹,就创建
            os.makedirs(testDir)
        moveFile(fileDir, val_ratio, test_ratio)  # 从每个子类别开始逐个划分
    print("Successfully splited!")

接下来就是生成对应的txt文件:

## 制作标签,在此之前需要用上半部分代码划分好数据集

path='./data/space_all/train'


data_path = pathlib.Path(path)
all_images_path = list(data_path.glob('*/*'))
all_images_path = [str(path) for path in all_images_path]  # 所有图片路径名存入列表
random.shuffle(all_images_path)  # 打散

print(len(all_images_path))
# print(all_images_path)  # 打印前五个

# 开始制作标签
label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
print(label_names)  # 打印类别名  注:下一步是制作与类别名对应的标签
label_to_index = dict((name, index) for index, name in enumerate(label_names))

all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_images_path]


for image, label in zip(all_images_path[:5], all_image_labels[:5]):
   print(image, '-----', label)

filename='./data/space_all/train.txt'     # ***这里也要记得改***

print(image + " " + str(label) + "\n")
with open(filename,'w') as f:
   for image,label in zip(all_images_path,all_image_labels):
       f.write(image+" "+str(label)+"\n")
print("\nAll images and labels have been written in  .txt!\n")

完成以后,数据这方面就算准备完毕了。

二、训练

mmcls使用过程也比较简单,和其他mmlab的代码库使用过程相同,就是修改config下面对应的文件。这里我使用的是resnet18_8xb32_in1k.py,这个命名的含义是使用的是resnet18,8卡,batchsize32,数据集是imagenet1k的。可以先打开看一下这个文件。在configs/resnet/resnet18_8xb32_in1k.py
在这里插入图片描述
看着挺多的,实际上只要修改/base/datasets/imagenet_bs32.py那部分,查看该部分文件。在这里插入图片描述
如果你不做其它微调的话,除了数据对应的路径要改以外,其它可以先不用改。
然后就是需要将自己的数据标签添加到ImageNet数据集标签中,当然这边也可以自己新建,我懒,没做。
具体操作如下:
在mmcls/imagenet.py中,把自己的标签加到CLASS中:在这里插入图片描述
其他不做修改。
接下来就可以训练啦。两个方法,一个是直接运行,但是要记得修改运行配置,另外一个就是在terminal里面输指令了。我比较懒,是选第一种,这样不用每次输那么多指令。
在这里插入图片描述
在这里插入图片描述
第一部分是指定config文件,第二个是指定工作存档文件夹。然后就可以run啦。会在指定的文件夹下产生log文件、checkpoints文件,以及config文件,可以在这个config文件里对你的模型训练过程进行微调。
具体参数介绍我其他文章也讲过了,这里不细讲了:在这里插入图片描述
其实这个文件就是系统自动把之前的那个config下的四个文件整合到一起了,下一次运行的时候,可以直接在这里修改,不会影响到其他训练的配置,会比较合理一些。包括路径以及其他基本设置。而后在设置运行配置的时候把这个作为你的config来就好了。

三、验证

训练指标主要是acc-top1和acc-top5,top-1就是分类最好的那一个,top-5分类最好的前五个平局(因该是的吧)。训练结果会存储在log.json文件里。我们可以用最后一次产生的checkpoints文件,即latest.pth来对测试集进行验证。主要使用的是tools/test.py,和train一样,两种运行方式,这边我直接用指令了。

python tools/test.py work_dir/resnet18_8xb32_in1k.py work_dir/latest.pth --metrics accuracy --metric-option topk=1

这里第一部分是config文件地址,第二部分是采用的checkpoint地址,metrics是设定评价标准,选了accuracy,topk=1是采用acc-top1的值。

在这里插入图片描述
也可以把结果输出到json文件的,代码如下:

python tools/test.py work_dir/resnet18_8xb32_in1k.py work_dir/latest.pth --out result.json --out-items all

同样是可以选定输出的关键字,我把所有的都输出了

四、可视化

可以对训练日志进行可视化,直接使用自带的分析工具就好。例如将日志中的top1变化情况可视化出来,代码为:

python tools/analysis_tools/analyze_logs.py plot_curve work_dir/20230214_153510.log.json --keys accuracy_top-1 --legend accuracy --out result.jpg

其中plot_curve是绘制曲线,keys是绘制曲线选取的关键字,可以是多个,legend 是图例, out是保存的文件名。
在这里插入图片描述

五、预测

想要使用训练出来的模型对新的图片进行预测,可以直接调用api,代码比较简单,我是用jupyter lab直接写的。源码大家自己敲吧,我放个照片
在这里插入图片描述

总结

其实这些在docs文档里都写了很清楚了,但是很多人可能懒得去看吧,我也一样,只不过之前发现很多网上找的教程不全,只能自己慢慢看,也许有不全面的地方,可以告诉我,大家一起交流学习。mmlab总体给我感觉就是如果上手了,真的很方便很好用,推荐大家可以用一下试试。

猜你喜欢

转载自blog.csdn.net/onepunch_k/article/details/129041676
今日推荐