猫十二分类比赛--PaddleX图片分类

用PaddleX快速实现图像分类训练

比赛的链接:aistudio.baidu.com/aistudio/co…

PaddleX 1.3 版本文档:paddlex.readthedocs.io/zh_CN/relea…

直接使用paddle进行测试

验证飞桨安装

python -c "import paddle;paddle.utils.run_check()"
复制代码

获得下图,则安装成功 image.png

准备工作

用pip install安装paddlex
pip install paddlex==1.3.7 -i https://mirror.baidu.com/pypi/simple
复制代码
用pip install安装pycocotools
pip install pycocotools -i https://mirror.baidu.com/pypi/simple
复制代码
验证PaddleX安装
python -c "import paddlex as pdx;print(pdx.__version__)"
复制代码

获得下图,则安装成功

image.png

飞桨 - PaddleX 是一套更加简明易懂的API,并配套一键下载安装的图形化开发客户端。用PaddleX实现图像分类训练非常快速,代码量也小。

数据的处理

image.png

unzip cat_data_sets_models.zip
复制代码

解压完成

image.png

我们进入data_sets中查看下数据:

image.png

构造需要的数据
labels.txt (主要是类别标签的名称)

image.png

制造train_list.txt和val_list.txt
  • 我们将原本的train_list.txt中的数据进行打乱并以70%作为训练文件,以30%作为验证图片集合
  • 需要一个python脚本来进行分割
import random

rate = 0.7
with open("train_list_origin.txt","r") as f:
    datas = f.readlines()

index = int(len(datas) * rate)
random.shuffle(datas)
train_list = datas[:index]
val_list = datas[index:]
with open("train_list.txt","w") as f:
    for data in train_list:
        f.write(data)

with open("val_list.txt","w") as f:
    for data in val_list:
        f.write(data)
复制代码

image.png

  • train_list.txt (训练图片的路径和标签)

image.png

  • val_list.txt (验证图片的路径和标签)

image.png

构造test_list.txt
  • 需要一个python脚本,来完成
import os

files = os.listdir("cat_12_test")
f = open("test_list.txt","w")
for file in files:
    f.write(os.path.join("cat_12_test",file) + "\n")
f.close()
复制代码
  • test_list.txt

image.png

到此为止,数据已经全部处理完成

PaddleX完成图片分类

  • 程序运行的主路径是data_sets,在此目录下新建一个output的目录

下面是程序的代码

from paddlex.cls import transforms
import paddlex as pdx 

train_transforms = transforms.Compose([
    transforms.RandomCrop(crop_size=224),
    transforms.RandomHorizontalFlip(),
    transforms.Normalize()
])
eval_transforms = transforms.Compose([
    transforms.ResizeByShort(short_size=256),
    transforms.CenterCrop(crop_size=224),
    transforms.Normalize()
])

train_dataset = pdx.datasets.ImageNet(
    data_dir='cat_12',
    file_list='cat_12/train_list.txt',
    label_list='cat_12/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
    data_dir='cat_12',
    file_list='cat_12/val_list.txt',
    label_list='cat_12/labels.txt',
    transforms=eval_transforms)

num_classes = len(train_dataset.labels)
model = pdx.cls.MobileNetV3_small_ssld(num_classes=num_classes)

model.train(num_epochs=30,
            train_dataset=train_dataset,
            train_batch_size=32,
            eval_dataset=eval_dataset,
            lr_decay_epochs=[4, 6, 8],
            save_dir='output/mobilenetv3_small_ssld',
            use_vdl=True)
复制代码

image.png

  • 上面图片的三个注意的点
    • 第一执行程序,程序正常运行
    • 第二我们可以看到输出了epoch、loss、acc、lr的关键的数据
    • 报错了,cv2读取图片出现错误
      • image.png
      • 仔细读过发现,yGcJHV8Uuft6grFs7QWnK5CTAZvYzdDO.jpg图片有问题,在train_list.txt或者val_list.txt中去掉

经过仔细的分析之后,我们发现在训练和验证集中有5张图片有问题,在测试集中,有一张图片有问题

  • 训练和验证集
    • yGcJHV8Uuft6grFs7QWnK5CTAZvYzdDO.jpg
    • tO6cKGH8uPEayzmeZJ51Fdr2Tx3fBYSn.jpg
    • YfsxcFB9D3LvkdQyiXlqnNZ4STwope2r.jpg
    • 5nKsehtjrXCZqbAcSW13gxB8E6z2Luy7.jpg
    • 3yMZzWekKmuoGOF60ICQxldhBEc9Ra15.jpg
  • 测试集
    • Qt29gPjYZwv3B6RJh5yiTWXrVImue1FH.jpg

观察训练过程

第一个epoch

image.png

我们能看到的信息是这是30个epoch中的第一轮,训练完,在训练集上的正确率最低是77.24%,最高是98.9%,然后在要验证集上,的正确率是77.24%,当前轮次是最好参数轮次。

第十五个epoch

image.png

我们能看到的信息是这是30个epoch中的第15轮,训练完,在训练集上的正确率最低是87.92%,最高是99.26%,然后在要验证集上,的正确率是88.54%,第十二轮次是最好参数轮次。除此之外,我们还能看到我们的学习率变成了lr = 2.5e-05,这个和我们设置的学习率的衰减有关。

第三十个epoch

image.png

我们能看到的信息是这是30个epoch中的第30轮,训练完,在训练集上的正确率最低是88.54%,最高是99.07%,然后在要验证集上,的正确率是89.0%,第二十轮次是最好参数轮次。

在测试集进行验证

验证部分的代码如下:

import paddlex as pdx
import os
model = pdx.load_model('output/mobilenetv3_small_ssld/best_model')
cf = open("result.csv","w")
with open("./cat_12/test_list.txt","r") as f:
    test_datas = f.readlines()
    for t_data in test_datas:
        result = model.predict(os.path.join("cat_12",t_data.strip()))
        cf.write(t_data.strip().split("/")[1] + "," + str(result[0]["category_id"]) + "\n")
print("预测完成")
复制代码

image.png

提交result.csv

image.png

将刚才的result.csv从paddle中下载下来,然后上传让官方判定结果,根据提交的结果对自己的构建过程进行修正调整。

image.png

一会就能得到测试结果

image.png

此次的成绩是85.83%,可以作为一个简单的baseline.

改进方法

修改学习率的衰减方式

我们之前的代码中在第8个epoch的时候我们的lr就变成了2.5e-05,变得太小了,所以后面在进行梯度衰减的时候,几乎不能改变什么,所以进行调整

image.png

看下调整后的训练结果

image.png

在第12轮的时候,就比上次30轮训练的结果要好,我们看此时的lr是2.5e-04,证明有效果。

image.png

最后我们的训练在验证集上的准确率是92.57%,提交下,看下效果

image.png

比赛名次

image.png

猜你喜欢

转载自juejin.im/post/7072677440715227173