当前位置: 首页 > AI > 文章内容页

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践

时间:2025-07-18    作者:游乐小编    

本文介绍了使用PaddleClas进行图像分类的流程。先查看飞桨版本,安装PaddleClas环境,了解其功能与全局配置。接着以flowers102数据集为例,演示下载、配置文件修改、训练及预测过程。还讲解了自定义蝴蝶数据集的处理、训练、中断续训、预测、评估和批处理预测等操作。

『抽丝剥茧』深度解析paddleclas—分类,一篇带你学会分类实践 - 游乐网

0.查看飞桨版本

In [ ]
import paddleprint(paddle.__version__)
登录后复制
2.1.2
登录后复制

1.安装PaddleClas环境

参考文档:https://github.com/PaddlePaddle/PaddleClas/blob/release/2.2/docs/en/tutorials/install_en.md

In [ ]
# !git clone https://github.com/PaddlePaddle/PaddleClas.git# !git clone https://gitee.com/PaddlePaddle/PaddleClas.git# %cd ./PaddleClas/# !pip install --upgrade pip# !pip3 install --upgrade -r requirements.txt -i https://mirror.baidu.com/pypi/simple
登录后复制

2.0了解PaddleClas

最新文档:https://github.com/PaddlePaddle/PaddleClas

拥有

图像识别

图像分类

特征学习

等内容

2.1PaddleClas全局配置

注:image_shape值除了默认还可以选择list, shape: (3,)

eval_mode除了默认值还可以选择"retrieval"

参考文档:https://github.com/PaddlePaddle/PaddleClas/blob/release/2.2/docs/en/tutorials/config_description_en.md

配置文件具体说明:

# global configs  全局配置Global:checkpoints: null    # 断点模型路径,用于恢复训练pretrained_model: null   # 预训练模型路径output_dir: ./output/  # 保存模型路径device: gpu        # 每隔多少个epoch保存模型class_num: 102   # 分类数量save_interval: 1  # 每隔多少个epoch保存模型eval_during_train: True  # 是否在训练时进行评估eval_interval: 1  # 每隔多少个epoch进行模型评估epochs: 20     # 训练总epoch数print_batch_step: 10  # 每隔多少个mini-batch打印输出use_visualdl: False  # 是否是用visualdl可视化训练过程# 同于静态图导出image_shape: [3, 224, 224]  # 图片大小save_inference_dir: ./inference  # inference模型的保存路径# model architecture  模型架构Arch:name: ResNet50_vd  # 模型名称# loss function config for traing/eval process 培训/评估过程的损失功能配置Loss:Train:   # 训练集  - CELoss:      weight: 1.0  # 交叉熵损失函数在整个Loss中的权重Eval:  # 测试集  - CELoss:      weight: 1.0Optimizer:  # 优化器name: Momentummomentum: 0.9lr:  name: Cosine  # 学习率下降方式  learning_rate: 0.0125  # 学习率初始值  warmup_epoch: 5  # warmup轮数regularizer:  name: 'L2'  # 正则化方法名  coeff: 0.00001  # 正则化系数# data loader for train and eval  数据读取DataLoader:Train:  dataset:    name: ImageNetDataset  # 名称    image_root: ./dataset/flowers102/  # 数据存放路径    cls_label_path: ./dataset/flowers102/train_list.txt  # 数据集标签    transform_ops:  # 数据预处理      - DecodeImage:          to_rgb: True  # 转换成RGB          channel_first: False  # 安装CHW排列      - RandCropImage:          size: 224  # 随机裁剪      - RandFlipImage:          flip_code: 1  # 随机翻转      - NormalizeImage:          scale: 1.0/255.0  # RGB值归一化          mean: [0.485, 0.456, 0.406]  # 归一化均值          std: [0.229, 0.224, 0.225]  # 归一化方差          order: ''  sampler:  # 采样器    name: DistributedBatchSampler  # 采样器类型    batch_size: 32  # 批处理大小    drop_last: False  # 舍弃不足的数据    shuffle: True  # 是否乱序  loader:    num_workers: 0  # 数据读取线程    use_shared_memory: True  # 是否用共享内存Eval:  # 测试集的数据  dataset:     name: ImageNetDataset  # 类名    image_root: ./dataset/flowers102/  # 数据集存放路径    cls_label_path: ./dataset/flowers102/val_list.txt  # 数据标签存放位置    transform_ops:       - DecodeImage:          to_rgb: True  # 转换RGB          channel_first: False  # 按照CHW排序      - ResizeImage:          resize_short: 256  # 按照短边调整大小      - CropImage:          size: 224  # 随机裁剪大小      - NormalizeImage:          scale: 1.0/255.0  # RGB值归一化          mean: [0.485, 0.456, 0.406]  # 归一化均值          std: [0.229, 0.224, 0.225]  # 归一化均值          order: ''  sampler:    name: DistributedBatchSampler  # 采样器名称    batch_size: 64  # 批处理大小    drop_last: False  # 放弃最后的多余数据    shuffle: False  # 乱序  loader:    num_workers: 0  # 读取线程    use_shared_memory: True  # 内存共享Infer:infer_imgs: docs/images/whl/demo.jpg  # 预测的图像地址batch_size: 10  # 批处理大小transforms:  - DecodeImage:      to_rgb: True  # 转RGB      channel_first: False  # 按CHW排序  - ResizeImage:      resize_short: 256  # 按短边调整大小  - CropImage:      size: 224  # 随机裁剪  - NormalizeImage:      scale: 1.0/255.0  # RGB值归一化      mean: [0.485, 0.456, 0.406]  # 归一化均值      std: [0.229, 0.224, 0.225]  # 归一化方差      order: ''  - ToCHWImage:PostProcess:  name: Topk  # 后处理名字  topk: 5  class_id_map_file: ppcls/utils/imagenet1k_label_list.txt  # 标签和值的映射文件Metric:  # 评估Train:  - TopkAcc:      topk: [1, 5]Eval:  - TopkAcc:      topk: [1, 5]
登录后复制

3.0最新分类尝试

3.1下载并解压flowers102数据集

训练集中有:

train_list.txt:训练集,1020张图

val_list.txt: 验证集,1020张图

train_extra_list.txt:大的训练集,7169张图

图片展示:

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

数据写入情况:

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

相对路径 标签

In [ ]
# 修改当前路径# %cd ./PaddleClas/dataset/flowers102# 下载数据集# !wget https://paddle-imagenet-models-name.bj.bcebos.com/data/flowers102.zip# 解压数据# !unzip flowers102.zip
登录后复制

3.2 配置文件

我们要首先对配置文件进行修改。 AI Studio由于没有共享内存,所以需要修改num_workers: 0,其他的可以不修改。

查看自己的环境是否为CPU或者是GPU然后对device:进行修改

3.3 进行训练

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

运行tools文件夹下的train.py文件

-c指的是训练使用的配置文件的路径为./ppcls/configs/quick_start/ResNet50_vd.yaml

-o表示的是是否使用预训练模型,可以是选择为True或False,也可以使用预训练模型存放路径。

In [ ]
# 切换目录到PaddleClas下%cd /home/aistudio/PaddleClas# 开始训练!python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True
登录后复制登录后复制

训练结果查看:

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

3.4 模型预测

-c为训练配置文件

-o Infer.infer_imgs=为预测的图片

-o Global.pretrained_model=为用于预测的模型

In [ ]
!python tools/infer.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml\                     -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg \                     -o Global.pretrained_model=output/ResNet50_vd/latest
登录后复制

3.5结果解析

[{'class_ids': [75, 45, 43, 18, 58], 'scores': [1.0, 0.0, 0.0, 0.0, 0.0], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': []}]

这里对75,45,43,18,58的比例进行了分析,最后以75为最后结果。

4. 自定义数据集

这里使用的是蝴蝶分类数据目录位置:data/data63004

4.1 数据解压

In [ ]
# 把数据解压到/home/aistudio/# !unzip -d /home/aistudio/ /home/aistudio/data/data63004/Butterfly20.zip
登录后复制

4.2 数据处理(训练集和验证集处理)

要准备训练集和验证集还有标签映射表

相对路径/绝对路径 (空格) 标签

标签映射表内容:

标签 空格 对应值

这里在/home/aistudio/species.txt 中已经处在

In [ ]
%cd /home/aistudio/import osimport random
登录后复制
/home/aistudio
登录后复制In [ ]
data_path = '/home/aistudio/Butterfly20'  # 设置初始文件地址character_folders = os.listdir(data_path)  # 查看地址下文件夹character_folders
登录后复制
['004.Byasa_dasarada', '010.Lamproptera_curius', '001.Atrophaneura_horishanus', '020.Papilio_hermosanus', '012.Losaria_coon', '016.Papilio_alcmenor', '002.Atrophaneura_varuna', '013.Meandrusa_payeni', '011.Lamproptera_meges', '005.Byasa_polyeuctes', '017.Papilio_arcturus', '003.Byasa_alcinous', '019.Papilio_dialis', '014.Meandrusa_sciron', '008.Graphium_sarpedon', '009.Iphiclides_podalirius', '018.Papilio_bianor', '006.Graphium_agamemnon', '.DS_Store', '007.Graphium_cloanthus', '015.Pachliopta_aristolochiae']
登录后复制In [ ]
namelist = '/home/aistudio/species.txt'  # 文件地址labledcoun = {}with open(namelist)as f:    '''    读取文件后处理成字典    '''    while True:        line = f.readline().strip().split(' ')        if line[0] == '':            break        if line[1] == '\ufeff0':            labledcoun[1] = line[0]        else:            labledcoun[line[1]] = line[0]    print(labledcoun)
登录后复制
{'001.Atrophaneura_horishanus': '1', '002.Atrophaneura_varuna': '2', '003.Byasa_alcinous': '3', '004.Byasa_dasarada': '4', '005.Byasa_polyeuctes': '5', '006.Graphium_agamemnon': '6', '007.Graphium_cloanthus': '7', '008.Graphium_sarpedon': '8', '009.Iphiclides_podalirius': '9', '010.Lamproptera_curius': '10', '011.Lamproptera_meges': '11', '012.Losaria_coon': '12', '013.Meandrusa_payeni': '13', '014.Meandrusa_sciron': '14', '015.Pachliopta_aristolochiae': '15', '016.Papilio_alcmenor': '16', '017.Papilio_arcturus': '17', '018.Papilio_bianor': '18', '019.Papilio_dialis': '19', '020.Papilio_hermosanus': '20'}
登录后复制In [ ]
# 新建标签列表if(os.path.exists('./train.txt')):  # 判断有误文件    os.remove('./train.txt')  # 删除文件if(os.path.exists('./val.txt')):    os.remove('./val.txt')data_list = []for character_folder in character_folders:  #  循环文件夹列表    # print(character_folder)    if character_folder not in '.DS_Store':        character_imgs = os.listdir(os.path.join(data_path,character_folder))  # 读取文件夹下面的内容        for character_img in character_imgs:            data = os.path.join(data_path, character_folder, character_img) + ' ' + labledcoun[character_folder] + '\n'            data_list.append(data)random.shuffle(data_list)print(data_list[0])count = len(data_list)print(count)for data in data_list:    if count >= (len(data_list) * 0.2):   # 20%数据写入验证集        with open('./train.txt', 'a')as f:            f.write(data)    else:        with open('./val.txt', 'a')as tf:  # 80%写入训练集            tf.write(data)    count -= 1print("数据写入完毕!")
登录后复制
/home/aistudio/Butterfly20/009.Iphiclides_podalirius/170.jpg 91866数据写入完毕!
登录后复制

4.3 配置文件修改

修改output_dir: ./output1/这里可以不修改(这里是为了与上面的内容进行区分)

修改image_root: ../ 和 cls_label_path: ../train.txt 问实际地址(这里使用了相对路径,也可以使用绝对路径。val的也一样修改)

修改class_id_map_file: ../species.txt 修改标签映射文件

In [ ]
# 切换目录到PaddleClas下%cd /home/aistudio/PaddleClas# 开始训练!python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True
登录后复制登录后复制

4.4意外中断,重新训练

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

添加-o Global.checkpoints参数,后面跟上继续的模型地址(不添加后缀名)

既可以实现继续训练

In [ ]
!python tools/train.py \            -c ./ppcls/configs/quick_start/ResNet50_vd.yaml \            -o Global.checkpoints='./output1/ResNet50_vd/epoch_21' \            -o Arch.pretrained=True
登录后复制

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

4.5 进行预测

In [ ]
!python tools/infer.py \    -c ./ppcls/configs/quick_start/ResNet50_vd.yaml\    -o Infer.infer_imgs=../Butterfly20/001.Atrophaneura_horishanus/084.jpg \     -o Global.pretrained_model=./output1/ResNet50_vd/latest
登录后复制

[{'class_ids': [1, 5, 20, 3, 16], 'scores': [1.0, 0.0, 0.0, 0.0, 0.0], 'file_name': '../Butterfly20/001.Atrophaneura_horishanus/084.jpg', 'label_names': ['001.Atrophaneura_horishanus', '005.Byasa_polyeuctes', '020.Papilio_hermosanus', '003.Byasa_alcinous', '016.Papilio_alcmenor']}]

会后的结果是1,验证无误。

4.6模型评估

In [53]
import paddle!python -m paddle.distributed.launch \    tools/eval.py \        -c ./ppcls/configs/quick_start/ResNet50_vd.yaml \        -o Global.pretrained_model=./output1/ResNet50_vd/latest
登录后复制

[Eval][Epoch 0][Avg]CELoss: 0.34251, loss: 0.34251, top1: 0.90885, top5: 0.99464

4.7批处理预测

In [ ]
# 把数据解压到/home/aistudio/!unzip -d /home/aistudio/ /home/aistudio/data/data63004/Butterfly20_test.zip
登录后复制

设置PaddleClas/ppcls/engine/trainer.py文件

在infer函数中添加logger.info(result)添加输出日志地址在设置输出的模型文件中

『抽丝剥茧』深度解析PaddleClas—分类,一篇带你学会分类实践 - 游乐网

在yaml文件中修改参数topk: 1

-o Infer.infer_imgs为需要预测的图片所在的文件夹

In [14]
!python3 tools/infer.py \    -c ./ppcls/configs/quick_start/ResNet50_vd.yaml \    -o Global.pretrained_model=./output1/ResNet50_vd/latest \    -o Infer.infer_imgs=../Butterfly20_test/
登录后复制

copy日志

copy以后手动删除无效日志(训练内容)

In [17]
!cp output1/ResNet50_vd/infer.log ../infer.txt
登录后复制

数据处理并将结果排序写入指定文件

In [50]
%cd /home/aistudio/import jsonimport osif(os.path.exists('result.txt')):  # 判断有误文件    os.remove('result.txt')  # 删除文件result = {}save_path = "infer.csv"f = open("infer.txt","r") lines = f.readlines()      #读取全部内容 ,并以列表方式返回count = 0for line in lines:    # 先把前面的时间都干掉,然后将单引号换成双引号,就变成了json格式的文本了    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)):        name, ids = list_txt[i]['file_name'],list_txt[i]['class_ids']        onefilepath = name.split("/")[2].split(".")[0]        # onefilepath = onefilepath        result[onefilepath] = ids[0]        count += 1# print(result)for i in range(1,count+1):    with open('result.txt', 'a') as ff:        ff.write(str(result[str(i)])+'\n')print('写入成功')
登录后复制
/home/aistudio写入成功
登录后复制

热门推荐

更多

热门文章

更多

首页  返回顶部

本站所有软件都由网友上传,如有侵犯您的版权,请发邮件youleyoucom@outlook.com