时间:2025-07-18 作者:游乐小编
本文介绍了使用PaddleClas进行图像分类的流程。先查看飞桨版本,安装PaddleClas环境,了解其功能与全局配置。接着以flowers102数据集为例,演示下载、配置文件修改、训练及预测过程。还讲解了自定义蝴蝶数据集的处理、训练、中断续训、预测、评估和批处理预测等操作。
import paddleprint(paddle.__version__)登录后复制
2.1.2登录后复制
参考文档: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登录后复制
最新文档:https://github.com/PaddlePaddle/PaddleClas
拥有
图像识别
图像分类
特征学习
等内容
注: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]登录后复制
训练集中有:
train_list.txt:训练集,1020张图
val_list.txt: 验证集,1020张图
train_extra_list.txt:大的训练集,7169张图
图片展示:
数据写入情况:
In [ ]相对路径 标签
# 修改当前路径# %cd ./PaddleClas/dataset/flowers102# 下载数据集# !wget https://paddle-imagenet-models-name.bj.bcebos.com/data/flowers102.zip# 解压数据# !unzip flowers102.zip登录后复制
我们要首先对配置文件进行修改。 AI Studio由于没有共享内存,所以需要修改num_workers: 0,其他的可以不修改。
查看自己的环境是否为CPU或者是GPU然后对device:进行修改
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登录后复制登录后复制
训练结果查看:
-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登录后复制
[{'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为最后结果。
这里使用的是蝴蝶分类数据目录位置:data/data63004
# 把数据解压到/home/aistudio/# !unzip -d /home/aistudio/ /home/aistudio/data/data63004/Butterfly20.zip登录后复制
要准备训练集和验证集还有标签映射表
相对路径/绝对路径 (空格) 标签
标签映射表内容:
标签 空格 对应值
这里在/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数据写入完毕!登录后复制
修改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登录后复制登录后复制
添加-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登录后复制
!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,验证无误。
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
# 把数据解压到/home/aistudio/!unzip -d /home/aistudio/ /home/aistudio/data/data63004/Butterfly20_test.zip登录后复制
设置PaddleClas/ppcls/engine/trainer.py文件
在infer函数中添加logger.info(result)添加输出日志地址在设置输出的模型文件中
在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以后手动删除无效日志(训练内容)
In [17]!cp output1/ResNet50_vd/infer.log ../infer.txt登录后复制
%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写入成功登录后复制
2021-11-05 11:52
手游攻略2021-11-19 18:38
手游攻略2021-10-31 23:18
手游攻略2022-06-03 14:46
游戏资讯2025-06-28 12:37
单机攻略