PaddleHub 图像分类实战指南:基于 PaddleFormers 完成预训练模型 Fine-tune 与 Serving 部署
PaddleHub 图像分类实战指南基于 PaddleFormers 完成预训练模型 Fine-tune 与 Serving 部署【免费下载链接】PaddleFormersPaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers本指南以 PaddleFormers 仓库PaddlePaddle 预训练模型库的镜像实践仓库中的docs/docs_en/finetune/image_classification.md为核心骨架完整讲解如何基于 PaddleHub 2.0 生态使用resnet50_vd_imagenet_ssld预训练模型对 Flowers 花卉数据集进行图像分类 Fine-tune并依次完成命令行预测、脚本预测与 Serving 服务化部署。读完本文你将掌握 PaddleHub 数据预处理Transforms组装、数据集加载、预训练 Module 装载、Trainer 训练配置以及 HTTP 在线推理的完整链路并可通过仓库源码深入理解每一步的底层实现。一、环境与依赖准备进行本教程的全部操作前需要先完成 PaddlePaddle 与 PaddleHub 的安装。根据原文档及仓库 requirements.txt 的约束版本要求如下paddlepaddle 2.0.0rcpaddlehub 2.0.0安装完成后即可在仓库的 demo/image_classification 目录下直接执行python train.py启动 Fine-tune 训练。该目录提供了与本教程一一对应的可运行脚本train.py完整训练脚本predict.py基于微调产物的预测脚本。二、命令行预测零代码体验预训练模型在编写任何代码之前可以先用 PaddleHub 的hub run命令对单张图片做一次开箱即用的分类预测快速验证模型与运行环境是否就绪$ hub run resnet50_vd_imagenet_ssld --input_path /PATH/TO/IMAGE --top_k 5参数含义--input_path待分类图片的本地路径--top_k返回概率最高的前 K 个类别及其置信度默认为 1。从源码看hub run的底层入口位于 paddlehub/module/cv_module.py 的ImageClassifierModule.run_cmd它通过 argparse 解析--input_path与--top_k两个参数随后调用self.predict(images[args.input_path], top_kargs.top_k)完成推理--top_k的默认值在add_module_config_arg中定义为1。这也解释了为什么命令行可以直接使用--top_k而不需要额外配置。三、四步 Fine-tune 完整流程使用 PaddleHub Fine-tune API 进行图像分类微调可以拆解为 4 个清晰的步骤定义数据预处理、加载数据集、加载预训练模型、配置优化器与训练器。下面逐一展开。Step 1定义数据预处理方式数据预处理含数据增强通过paddlehub.vision.transforms组装import paddlehub.vision.transforms as T transforms T.Compose([T.Resize((256, 256)), T.CenterCrop(224), T.Normalize(mean[0.485, 0.456, 0.406], std [0.229, 0.224, 0.225])], to_rgbTrue)transforms数据增强模块定义了丰富的数据预处理方式用户可按照需求替换自己需要的数据预处理方式。上述管线依次完成Resize((256, 256))将图片缩放至 256×256CenterCrop(224)从中心裁剪出 224×224 区域与 ImageNet 分类模型的标准输入尺寸一致Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225])使用 ImageNet 统计均值与标准差做归一化to_rgbTrue将 OpenCV 读取的 BGR 图像转为 RGB。源码级说明Compose的实现位于 paddlehub/vision/transforms.py其构造函数要求transforms必须是非空列表否则抛出TypeError/ValueError。在__call__中若输入是字符串路径则先通过cv2.imread读图若设置了to_rgbTrue则执行cv2.COLOR_BGR2RGB通道转换随后按顺序执行每个算子并默认通过channel_firstTrue将图像从[H, W, C]调整为[C, H, W]即F.permute从而满足 Paddle 模型的 NCHW 输入约定。同文件还提供了丰富的其他算子可供替换例如RandomHorizontalFlip(prob0.5)、RandomVerticalFlip、ResizeByLong、ResizeRangeScaling、ResizeStepScaling等。其中Resize支持interpolation参数可取NEAREST、LINEAR、CUBIC、AREA、LANCZOS4以及随机插值RANDOM默认为LINEARNormalize支持自定义mean/std列表并会校验std不允许出现 0 值。Step 2下载数据集并使用from paddlehub.datasets import Flowers flowers Flowers(transforms) flowers_validate Flowers(transforms, modeval)参数说明transformsStep 1 中定义的数据预处理方式mode选择数据模式可选项有train、test、val默认为train。数据集实现细节数据集的准备代码可以参考 paddlehub/datasets/flowers.py。该文件通过装饰器download_data(urlhttps://bj.bcebos.com/paddlehub-dataset/flower_photos.tar.gz)标注下载地址hub.datasets.Flowers()实例化时会自动从网络下载数据集并解压到用户目录下$HOME/.paddlehub/dataset目录对应仓库 paddlehub/env.py 中定义的DATA_HOME环境常量日志输出也提示该目录为 Store the automatically downloaded datasets。Flowers继承自paddle.io.Dataset内部按mode选择不同的索引文件train→train_list.txttest→test_list.txtval→validate_list.txt。__getitem__从索引文件中按行解析图片路径 标签然后交给transforms完成预处理并返回(图像, 标签)元组num_classes 5对应玫瑰、郁金香、雏菊、向日葵、蒲公英五类花卉。Step 3加载预训练模型model hub.Module(nameresnet50_vd_imagenet_ssld, label_list[roses, tulips, daisy, sunflowers, dandelion])参数说明name选择预训练模型的名字label_list设置输出分类类别默认为 Imagenet2012 类别1000 类。Module 装载机制hub.Module的底层逻辑位于 paddlehub/module/module.py。当指定name时Module.__new__会调用init_with_name首先通过LocalModuleManager在本地查找已安装的 Module若本地不存在或版本不满足version约束则会自动从服务器下载安装最后实例化对应类并透传kwargs。对于resnet50_vd_imagenet_ssld这类 V2 版 Module实例化即调用其__init__完成模型结构与权重加载。模型本体定义在 modules/image/classification/resnet50_vd_imagenet_ssld/module.py通过moduleinfo(nameresnet50_vd_imagenet_ssld, typeCV/classification, version1.1.0, metaImageClassifierModule)装饰器注册为 PaddleHub 可识别模块。其__init__逻辑值得注意若传入label_list则以len(label_list)作为分类头输出维度并将标签列表赋给self.labels若未传入则从 Module 目录下的label_list.txt读取 ImageNet 2012 类别load_checkpoint为None时自动加载同目录下的预训练权重resnet50_vd_ssld.pdparams否则加载用户指定的微调权重。模型无缝切换PaddleHub 提供许多图像分类预训练模型如 xception、mobilenet、efficientnet 等。如果想尝试 efficientnet 模型只需要更换 Module 中的name参数即可# 更换name参数即可无缝切换efficientnet模型, 代码示例如下 model hub.Module(nameefficientnetb7_imagenet)NOTE目前部分模型还没有完全升级到 2.0 版本敬请期待。Step 4选择优化策略和运行配置optimizer paddle.optimizer.Adam(learning_rate0.001, parametersmodel.parameters()) trainer Trainer(model, optimizer, checkpoint_dirimg_classification_ckpt) trainer.train(flowers, epochs100, batch_size32, eval_datasetflowers_validate, save_interval1)优化策略Paddle 2.0 提供了多种优化器选择如SGD、Adam、Adamax等其中Adam常用参数learning_rate全局学习率默认为 1e-3parameters待优化模型参数即model.parameters()。运行配置Trainer主要控制 Fine-tune 的训练流程其实现位于 paddlehub/finetune/trainer.py构造函数支持以下可控制参数参数作用默认值model被优化模型须为paddle.nn.Layer必填optimizer优化器选择必填use_gpu是否使用 GPU 运行自动执行paddle.set_device(gpu/cpu)Falseuse_vdl是否使用 VisualDL 可视化训练过程开启后在checkpoint_dir/visualization目录写入日志Truecheckpoint_dir保存模型参数的地址未指定时自动生成ckpt_{time}Nonecompare_metrics保存最优模型的衡量指标比较函数默认取验证指标第一个键、值越大越好Nonetrainer.train主要控制具体的训练过程实现见 trainer.py包含以下可控制参数参数作用默认值train_dataset训练时所用的数据集必填epochs训练轮数1batch_size训练的批大小如果使用 GPU请根据实际情况调整1num_workersDataLoader 子进程数量0eval_dataset验证集若设置则每个save_interval轮次执行一次评估Nonelog_interval打印日志的间隔单位为执行批训练的次数10save_interval保存模型的间隔频次单位为执行训练的轮数10collate_fn自定义 batch 合并函数None源码级训练细节Trainer.__init__中会检查model是否为paddle.nn.Layer否则抛出TypeError同时若nranks 1会自动执行paddle.distributed.init_parallel_env()并包裹paddle.DataParallel说明 Trainer 天然支持多卡分布式训练。训练循环内部使用paddle.io.DistributedBatchSamplershuffleTrue构建 DataLoader每个log_interval步打印一次Epoch/Step/loss/metrics/lr/step/sec/ETA信息并同步写入 VisualDL 的TRAIN/loss、TRAIN/{metric}标量每个save_interval轮次末且为最后一个 batch执行一次验证若验证指标优于历史最优则将模型保存到${checkpoint_dir}/best_model同时每轮结束都会保存epoch_{n}检查点含model.pdparams与model.pdopt。训练中要求模型实现training_step/validation_step方法——分类模型在 cv_module.py 中已内置使用softmax_with_cross_entropy计算损失、paddle.metric.accuracy计算acc指标。四、脚本预测使用微调产物推理当完成 Fine-tune 后训练过程中在验证集上表现最优的模型会被保存在${CHECKPOINT_DIR}/best_model目录下其中${CHECKPOINT_DIR}目录为 Fine-tune 时所选择的保存 checkpoint 的目录即checkpoint_dirimg_classification_ckpt。此时可以使用该最优模型进行预测predict.py脚本如下import paddle import paddlehub as hub if __name__ __main__: model hub.Module(nameresnet50_vd_imagenet_ssld, label_list[roses, tulips, daisy, sunflowers, dandelion], load_checkpoint/PATH/TO/CHECKPOINT) result model.predict([flower.jpg])预测链路剖析从 cv_module.py 的ImageClassifierModule.predict实现可以看到完整推理逻辑模型切换为eval()模式并关闭梯度按batch_size默认 1分批对每张图先执行self.transformsResNet50_vd 内部内置了与 Step 1 相同的 ResizeCenterCropNormalize 管线见 module.py预处理前向得到 logits 后做softmax按概率降序取top_k默认 1个类别返回形如[{类别名: 置信度}, ...]的字典列表。参数配置正确后请执行脚本python predict.py。NOTE进行预测时所选择的 module、checkpoint_dir、dataset 必须和 Fine-tune 所用的一样尤其label_list必须与训练时一致否则分类头输出维度会对不上。五、服务部署PaddleHub Serving 在线分类服务PaddleHub Serving 可以部署一个在线分类任务服务将微调后的模型封装为 HTTP API。Step 1启动 PaddleHub Serving运行启动命令$ hub serving start -m resnet50_vd_imagenet_ssld这样就完成了一个分类任务服务化 API 的部署默认端口号为 8866。NOTE如使用 GPU 预测则需要在启动服务之前设置CUDA_VISIBLE_DEVICES环境变量否则不用设置。服务化机制hub serving之所以能识别分类模型的推理入口是因为 cv_module.py 中ImageClassifierModule.serving_method被serving装饰器标记并在 module.py 中注册到模块级服务函数字典Serving 框架启动后会自动定位该函数。serving_method接收 base64 编码的图片列表与top_k参数解码后调用predict最终返回{data: [{类别: 置信度}, ...]}结构。服务端实现位于 paddlehub/serving/app_compat.py。Step 2发送预测请求配置好服务端以下数行代码即可实现发送预测请求获取预测结果import requests import json import cv2 import base64 import numpy as np def cv2_to_base64(image): data cv2.imencode(.jpg, image)[1] return base64.b64encode(data.tostring()).decode(utf8) def base64_to_cv2(b64str): data base64.b64decode(b64str.encode(utf8)) data np.fromstring(data, np.uint8) data cv2.imdecode(data, cv2.IMREAD_COLOR) return data # 发送HTTP请求 org_im cv2.imread(/PATH/TO/IMAGE) data {images:[cv2_to_base64(org_im)], top_k:2} headers {Content-type: application/json} url http://127.0.0.1:8866/predict/resnet50_vd_imagenet_ssld r requests.post(urlurl, headersheaders, datajson.dumps(data)) data r.json()[results][data]要点说明请求体采用 JSON 格式images为 base64 编码的图片字符串列表top_k控制返回 Top-K 结果请求 URL 形如http://127.0.0.1:8866/predict/{module_name}module_name与hub serving start -m指定的模型名保持一致响应结构为r.json()[results][data]即每个输入图片的{类别: 置信度}字典列表。六、完整可运行示例速览仓库 demo/image_classification 下提供了与本教程完全对应的端到端脚本可直接参考运行训练train.py组装T.Compose([T.Resize((256, 256)), T.CenterCrop(224), T.Normalize(...)], to_rgbTrue)→ 构建Flowers训练集与验证集 →hub.Module(nameresnet50_vd_imagenet_ssld, label_list[五类花卉])→Adam(learning_rate0.001)→Trainer(..., checkpoint_dirimg_classification_ckpt, use_gpuTrue)→trainer.train(flowers, epochs100, batch_size32, eval_datasetflowers_validate, save_interval10)预测predict.py通过load_checkpoint加载微调最优模型对flower.jpg执行model.predict。仓库中同类的 Fine-tune 指南还包括 docs/docs_en/finetune/image_colorization.md、docs/docs_en/finetune/semantic_segmentation.md、docs/docs_en/finetune/style_transfer.md 等读者可对比学习 PaddleHub 在不同视觉任务上的统一 Fine-tune API 用法。七、总结从命令行零代码预测到四步 Fine-tune 微调再到 Serving 服务化部署PaddleHub 2.0 为图像分类任务提供了一条完整、低门槛的落地链路。结合 PaddleFormers 仓库源码可以看到paddlehub.vision.transforms负责可组合的数据预处理、paddlehub.datasets负责数据集自动下载与解析、hub.Module负责预训练模型的一键加载与标签替换、Trainer负责训练/评估/检查点保存与 VisualDL 可视化、serving装饰器则将模型自动暴露为 HTTP 服务。理解这些底层实现有助于在更换模型如切换 efficientnet、更换数据集或扩展新任务时快速定位并复用 PaddleHub 的能力。【免费下载链接】PaddleFormersPaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考