基于PaddleClas实现猫的十二分类

项目背景介绍

飞桨PaddlePaddle大赛:猫的十二种分类问题。

本场比赛要求参赛选手对十二种猫进行分类,属于CV方向经典的图像分类任务。图像分类任务作为其他图像任务的基石,可以让大家更快上手计算机视觉。

结合深度学习框架Pytorch和AI平台Paddle,使用分类模型,对这十二种猫进行分类。从第二次实验课开始,全部实验课用来完成这个比赛。

比赛地址

环境准备

编程平台:根据要求适用飞桨Paddle提供的平台BML Codelab

深度学习框架:paddlepaddle-gpu与paddleclas

Python版本:3.7.4

介绍paddleclas

飞桨图像识别套件PaddleClas是飞桨为工业界和学术界所准备的一个图像识别和图像分类任务的工具集,助力使用者训练出更好的视觉模型和应用落地。

PaddleClas支持多种前沿图像分类、识别相关算法,发布产业级特色骨干网络PP-HGNet、PP-LCNetv2、 PP-LCNet和SSLD半监督知识蒸馏方案等模型,在此基础上打造PULC超轻量图像分类方案和PP-ShiTu图像识别系统。

关于paddleclas的模型训练可以参考一下以下

『paddle』paddleclas 学习笔记:模型训练

Paddle使用文档

数据集准备

直接选用官方提供的数据集:猫脸识别-12种猫分类数据集

/home/aistudio/data/data10954/train_list.txt

/home/aistudio/data/data10954/cat_12_test.zip

/home/aistudio/data/data10954/cat_12_train.zip

解压数据集与复制训练list

!unzip -q data/data10954/cat_12_test.zip -d /home/aistudio/

!unzip -q data/data10954/cat_12_train.zip -d /home/aistudio/

!cp data/data10954/train_list.txt /home/aistudio/

数据预处理

图片格式应当为RGB三通道,提供的数据集有几张需要进行修改,不然使用paddleclas会报错。

import os

from PIL import Image

for img_path in os.listdir('/home/aistudio/cat_12_train'):

src = os.path.join('/home/aistudio/cat_12_train',img_path)

img = Image.open(src)

if img.mode != 'RGB':

img = img.convert('RGB')

# print("train"+src)

img.save(src)

for img_path in os.listdir('/home/aistudio/cat_12_test'):

src = os.path.join('/home/aistudio/cat_12_test',img_path)

img = Image.open(src)

if img.mode != 'RGB':

img = img.convert('RGB')

# print(src)

img.save(src)

划分数据集并生成标签

#划分数据集

import random

def randrow(file_path, rnd_path):

out = open(rnd_path, 'w')

lines=[]

with open(file_path, 'r') as infile:

for line in infile:

lines.append(line)

for i in range(6):

random.shuffle(lines)

for line in lines:

out.write(line)

print('已打乱数据')

rnd_path = 'train_list_rnd.txt'

randrow('train_list.txt', rnd_path) # 打乱数据

# 按比例随机切割数据集

train = open('train.txt','w')

val = open('val.txt','w')

with open('train_list_rnd.txt','r') as f:

lines = f.readlines()

for (lid, line) in enumerate(lines, start=1):

img, label = line.split('\t')

new_data = img + ' ' + label

if lid % 10 == 0:

val.write(new_data)

else:

train.write(new_data)

train.close()

val.close()

os.remove('train_list_rnd.txt')

print('已生成新的数据集合')

# 生成标签

with open('label.txt','w') as f:

for i in range(12):

f.write(str(i) + '\n')

print('已生成标签')

配置yaml文件

打开PaddleClas/ppcls/configs/quick_start/ResNet50_vd.yaml文件

修改epochs训练迭代次数为80

修改device设备为gpu

修改class_num分类数目为12

修改训练与验证类的image_root与cls_label_path

修改预测的topk为1和class_id_map_file

模型训练

# 切换目录到PaddleClas下

%cd /home/aistudio/PaddleClas-2.2.1

# 开始训练

!python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True

部分结果如下所示:

[2023/04/13 22:32:23] root INFO: Already save model in ./output/ResNet50_vd/epoch_4

[2023/04/13 22:32:23] root INFO: Already save model in ./output/ResNet50_vd/latest

[2023/04/13 22:32:24] root INFO: [Train][Epoch 5/80][Iter: 0/61]lr: 0.01004, CELoss: 0.77114, loss: 0.77114, top1: 0.65625, top5: 1.00000, batch_cost: 0.13495s, reader_cost: 0.04580, ips: 237.12732 images/sec, eta: 0:10:25

[2023/04/13 22:32:25] root INFO: [Train][Epoch 5/80][Iter: 10/61]lr: 0.01045, CELoss: 0.78542, loss: 0.78542, top1: 0.74716, top5: 0.96875, batch_cost: 0.08887s, reader_cost: 0.00022, ips: 360.08646 images/sec, eta: 0:06:51

[2023/04/13 22:32:26] root INFO: [Train][Epoch 5/80][Iter: 20/61]lr: 0.01086, CELoss: 0.79159, loss: 0.79159, top1: 0.75000, top5: 0.96577, batch_cost: 0.08849s, reader_cost: 0.00014, ips: 361.61824 images/sec, eta: 0:06:48

[2023/04/13 22:32:27] root INFO: [Train][Epoch 5/80][Iter: 30/61]lr: 0.01127, CELoss: 0.86264, loss: 0.86264, top1: 0.73690, top5: 0.96169, batch_cost: 0.08836s, reader_cost: 0.00018, ips: 362.14592 images/sec,

....

模型预测

打开PaddleClas/ppcls/engine/engine.py文件 并在infer下加入一行代码 logger.info(result)

#预测

!python3 tools/infer.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Global.pretrained_model=./output/ResNet50_vd/latest -o Infer.infer_imgs=../cat_12_test/

保存结果

手动删除多余内容,保存有用数据

!cp output/ResNet50_vd/infer.log ../infer.txt

处理保存的结果

%cd /home/aistudio/

import json

import os

result = {}

summary_scores=[]

f = open("infer.txt","r")

lines = f.readlines() #读取全部内容 ,并以列表方式返回

count = 0

for line in lines:

# 先把前面的时间都干掉,然后将单引号换成双引号,就变成了json格式的文本了

#print(line)

txt = line.split(" root INFO: ")[1]

# print(txt)

jsontxt = txt.replace("\'","\"")

# print(jsontxt)

list_txt = json.loads(jsontxt)

# print(list_txt)

for i in range(len(list_txt)):

print(list_txt[i])

name, ids,score = list_txt[i]['file_name'],list_txt[i]['class_ids'],list_txt[i]['scores']

onefilepath = name.split("/")[2]

summary_scores.append(score)

# print(onefilepath)

result[onefilepath] = ids[0]

count += 1

cvs=[]

for k in result.keys() :

csv=k , result[k]

res_data=[]

res_data.append(csv[0])

res_data.append(csv[1])

cvs.append(res_data)

#print(len(cvs))

#print(cvs)

with open('result.csv','w') as f_result:

for i in range(len(cvs)):

f_result.write(cvs[i][0] + ',' + str(cvs[i][1]) + '\n')

部分结果如下所示

/home/aistudio

{'class_ids': [9], 'scores': [0.9876], 'file_name': '../cat_12_test/06yUTYIeaRsE782Ou5dh1NPzm9XpkBoL.jpg', 'label_names': ['']}

{'class_ids': [0], 'scores': [1.0], 'file_name': '../cat_12_test/0inVXMEgaBO4Fcrhdj9bkLvHzN71yTuI.jpg', 'label_names': ['']}

{'class_ids': [4], 'scores': [1.0], 'file_name': '../cat_12_test/0l8jL4ROZqzBYXeGH3fFyxPCJEs2togc.jpg', 'label_names': ['']}

{'class_ids': [10], 'scores': [0.99931], 'file_name': '../cat_12_test/0vqnOQ8N7JfRxYLuHWG5BKiwb3ltMkg1.jpg', 'label_names': ['']}

{'class_ids': [11], 'scores': [1.0], 'file_name': '../cat_12_test/1nvK0pif9zLc74MCeYrOyqx6ZVQ3EGNH.jpg', 'label_names': ['']}

{'class_ids': [3], 'scores': [1.0], 'file_name': '../cat_12_test/1oCwQeU3KzI2bESWZVDvacAxHhg4O0p5.jpg', 'label_names': ['']}

{'class_ids': [9], 'scores': [1.0], 'file_name': '../cat_12_test/1pMk2hNyv4WXfEVlOxd0I7wbUL6ur9cP.jpg', 'label_names': ['']}

{'class_ids': [2], 'scores': [0.98152], 'file_name': '../cat_12_test/1ry0uScsWatxqJ8zAnkVD9j3QRUiZC7h.jpg', 'label_names': ['']}

{'class_ids': [1], 'scores': [0.86432], 'file_name': '../cat_12_test/2Gz5sW0vnPYapF1btMZK6qUQJcA8xyIB.jpg', 'label_names': ['']}

{'class_ids': [5], 'scores': [0.90268], 'file_name': '../cat_12_test/2JpNeS5GmtdOV3B9I8TZRAxUEvPc7i1w.jpg', 'label_names': ['']}

{'class_ids': [7], 'scores': [0.99997], 'file_name': '../cat_12_test/2NbvoGleSIPmdiXLjVwgM40CBZWr7qU9.jpg', 'label_names': ['']}

{'class_ids': [4], 'scores': [0.99991], 'file_name': '../cat_12_test/3ZlItXUDgHEJLPr0bSAzisp8YfvxuGBW.jpg', 'label_names': ['']}

求平均分数

import numpy as np

average_score = np.mean(summary_scores)

print(average_score)

结语

因为作者没有特别多的神经网络和深度学习的内容,只能做调包侠了。

如果对用pytroch建立restnet50网络实现分类感兴趣的话,可以看看这位同学的笔记 CJH’s blog - CJH’s blog (cjh0220.github.io)

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: