基于 PaddleHub 的图像分类实战:使用 resnet50_vd_imagenet_ssld 完成微调、预测与服务化部署
2026/9/23 1:54:03 网站建设 项目流程
  • 人工智能
  • 预训练
  • 微调
  • 模型推理服务

【免费下载链接】PaddleFormers

PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleFormers
点击查看免费下载

本指南以demo/image_classification为实战入口,系统讲解如何在 PaddleHub 框架下使用预训练图像分类模型resnet50_vd_imagenet_ssld完成「命令行/脚本预测 → 数据集微调(Fine-tune)→ checkpoint 加载预测 → Serving 在线服务部署」的完整闭环。读者阅读完本文后,将掌握 PaddleHub 图像分类模块的调用范式、Flowers 数据集的使用方式、Trainer训练与评估流程,以及如何将微调产物一键发布为 HTTP 分类服务。

环境与依赖

运行本文示例前,需要先安装以下依赖(与仓库demo/image_classification/README.mdmodules/image/classification/resnet50_vd_imagenet_ssld/README.md声明一致):

  • paddlepaddle >= 2.0.0rc(模块侧要求>= 2.0.0
  • paddlehub >= 2.0.0

安装 PaddlePaddle 与 PaddleHub 后,可先通过hub install显式安装分类模块:

$ hub install resnet50_vd_imagenet_ssld

hub install会将模块下载到本地 hub 目录,后续hub.Modulehub run均可直接按名称加载。

命令行预测:一条命令完成推理

加载预训练模型的最快方式是使用hub run命令行工具:

$ hub run resnet50_vd_imagenet_ssld --input_path "/PATH/TO/IMAGE" --top_k 5
  • --input_path:待预测图片的路径;
  • --top_k:返回概率最高的前 K 个类别(示例为 5)。

命令执行后,模型会输出每张图片 Top-K 的类别名称与对应置信度。该方式适合快速验证模块可用性或做单张图片的即席推理。

脚本预测:在 Python 中调用模块

在代码中调用同样简洁,核心就是hub.Modulemodel.predict

import paddle import paddlehub as hub if __name__ == '__main__': model = hub.Module(name='resnet50_vd_imagenet_ssld',) result = model.predict([PATH/TO/IMAGE])

未指定label_list时,模块会使用模型自带的 ImageNet-2012 类别作为输出标签(见下文 Step3)。predict返回每个输入图片的 Top-1(默认top_k=1)分类结果字典列表。

Fine-tune 全流程:四步走

在完成 PaddlePaddle 与 PaddleHub 安装后,进入demo/image_classification目录直接执行python train.py即可开始使用resnet50_vd_imagenet_ssld对 Flowers 数据集 等数据进行微调。仓库中的 train.py 即为可直接运行的完整脚本,其逻辑可拆分为 4 个步骤。

Step1:定义数据预处理方式

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_rgb=True)

transforms是数据增强/预处理管线,用户可按需替换。各算子定义位于 paddlehub/vision/transforms.py:

  • T.Resize((256, 256)):将图片缩放到目标尺寸。target_size支持 int 或 (h, w) 二元组,interpolation默认'LINEAR',可选NEAREST / LINEAR / CUBIC / AREA / LANCZOS4 / RANDOM六种模式(源码见transforms.pyResize类);
  • T.CenterCrop(224):从图片中心裁剪出224 x 224区域,与 ResNet 系列标准的输入尺寸保持一致;
  • T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):使用 ImageNet 数据集的均值/方差做通道归一化;
  • to_rgb=True:统一转换为 RGB 通道顺序,避免 BGR/RGB 混用导致预测异常。

这里使用的预处理参数与模块内部module.pytransforms方法(modules/image/classification/resnet50_vd_imagenet_ssld/module.pyResize((256, 256)) + CenterCrop(224) + Normalize同一组配置)完全一致,保证训练与推理阶段输入分布对齐。

Step2:下载数据集并使用

from paddlehub.datasets import Flowers flowers = Flowers(transforms) flowers_validate = Flowers(transforms, mode='val')
  • transforms:数据预处理方式;
  • mode:数据模式,可选traintestval,默认为train

Flowers数据集的实现见 paddlehub/datasets/flowers.py:

  • 类装饰器@download_data(url='https://bj.bcebos.com/paddlehub-dataset/flower_photos.tar.gz')会在首次实例化时自动从网络下载数据并解压到hubenv.DATA_HOME(即$HOME/.paddlehub/dataset)目录下,无需手动准备数据;
  • 数据集包含 5 个类别(num_classes = 5),对应train_list.txt / test_list.txt / validate_list.txt三个文件列表,由mode决定加载哪个文件;
  • __getitem__中读取图片路径与标签,并调用self.transforms(img_path)完成预处理,返回(图像, 标签)二元组。

Step3:加载预训练模型

model = hub.Module(name="resnet50_vd_imagenet_ssld", label_list=["roses", "tulips", "daisy", "sunflowers", "dandelion"])
  • name:预训练模型名称;
  • label_list:自定义输出分类类别;不传时默认使用 ImageNet-2012 的 1000 类标签。

从模块源码(module.py)可以看到,label_list直接决定全连接分类头的输出维度:传入时class_dim = len(label_list),否则读取模块目录下的 label_list.txt 构建标签表。因此在微调阶段传入 5 个花类别后,模型最后一层Linear的神经元数会相应变为 5,配合冻结/微调预训练骨干即可适配新任务。

PaddleHub 还提供大量图像分类预训练模型(如xceptionmobilenetefficientnet等),本仓库modules/image/classification/目录下即收录了对应模块。想切换模型时,只需更换name参数:

# 更换name参数即可无缝切换efficientnet模型, 代码示例如下 model = hub.Module(name="efficientnetb7_imagenet")

NOTE:目前部分模型尚未完全升级到 Paddle 2.0 动态图版本,切换模型时请以对应模块 README 标注的版本状态为准。

Step4:选择优化策略和运行配置

optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()) trainer = Trainer(model, optimizer, checkpoint_dir='img_classification_ckpt') trainer.train(flowers, epochs=100, batch_size=32, eval_dataset=flowers_validate, save_interval=1)
优化策略

Paddle 2.0 提供了SGDAdamAdamax等多种优化器,示例选用Adam

  • learning_rate:全局学习率,默认 1e-3;
  • parameters:待优化的模型参数,即model.parameters()
运行配置

Trainer(实现在 paddlehub/finetune/trainer.py)负责整体训练流程,可配置参数包括:

  • model:被优化模型;
  • optimizer:优化器;
  • use_gpu:是否使用 GPU 训练;
  • use_vdl:是否使用 VisualDL 可视化训练过程;
  • checkpoint_dir:保存模型参数的目录;
  • compare_metrics:保存最优模型时的衡量指标(默认比较acc)。

trainer.train控制具体训练过程,参数如下:

  • train_dataset:训练数据集;
  • epochs:训练轮数;
  • batch_size:批大小,使用 GPU 时请根据显存实际情况调整;
  • num_workers:数据加载 worker 数量,默认为 0;
  • eval_dataset:验证集;
  • log_interval:打印日志的间隔,单位为执行批训练的次数;
  • save_interval:保存模型的间隔频次,单位为训练轮数。

trainer.pytrain方法实现(约第 255 行起)可以确认训练循环的关键行为:当current_epoch % save_interval == 0且一个 epoch 结束时保存 checkpoint,并会在每个保存节点对验证集执行评估;若当前指标优于历史最优(_compare_metrics),则将模型保存到${checkpoint_dir}/best_model目录。这就是「验证集上表现最优的模型被自动保留」这一机制的源码依据。

模型预测:加载微调产物

完成微调后,验证集表现最优的模型保存在${CHECKPOINT_DIR}/best_model目录下,其中${CHECKPOINT_DIR}即训练时设置的checkpoint_dir。使用该模型预测的 predict.py 脚本如下:

import paddle import paddlehub as hub if __name__ == '__main__': model = hub.Module(name='resnet50_vd_imagenet_ssld', label_list=["roses", "tulips", "daisy", "sunflowers", "dandelion"], load_checkpoint='/PATH/TO/CHECKPOINT') result = model.predict(['flower.jpg'])

关键点在于load_checkpoint='/PATH/TO/CHECKPOINT':指定微调产物的 checkpoint 路径后,模块__init__(见module.py)会通过paddle.load(load_checkpoint)[0]加载自定义权重并覆盖预训练参数(源码中打印load custom checkpoint success);不传该参数时则加载模型自带的resnet50_vd_ssld.pdparams预训练权重。

NOTE:进行预测时,所选择的modulecheckpoint_dirdataset必须与 Fine-tune 时保持一致,否则类别映射与权重维度会对不上。

model.predict的底层实现在 paddlehub/module/cv_module.py(ImageClassifierModule.predict,约第 82 行):模型切换到eval()模式并关闭梯度,对输入图片批量执行预处理 → 前向推理 →F.softmax得到概率分布 →np.argsort降序取 Top-K 索引,最后结合self.labels映射为可读的类别名。

服务部署:Serving 在线分类服务

PaddleHub Serving 可将微调好的模型部署为在线分类任务服务。

Step1:启动 PaddleHub Serving

$ hub serving start -m resnet50_vd_imagenet_ssld

执行后即完成分类任务服务化 API 的部署,默认端口号为8866

NOTE:如使用 GPU 预测,需在启动服务前设置CUDA_VISIBLE_DEVICES环境变量;纯 CPU 环境无需设置。

Step2:发送预测请求

服务端就绪后,用以下代码即可发送图片并获取分类结果:

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(url=url, headers=headers, data=json.dumps(data)) data =r.json()["results"]['data']

请求体采用 JSON 格式:images字段为 base64 编码的图片列表,top_k指定返回的候选类别数;服务端响应中的results['data']即为每张图片的 Top-K 分类结果。这样便完成了一个可直接被业务系统调用的图像分类 HTTP API。

延伸阅读与使用建议

  • 模型细节resnet50_vd_imagenet_ssld是 ResNet-D 结构变体,模型元信息(类别、网络、数据集、版本、是否支持微调等)见 模块 README;网络结构由ConvBNLayerBottleneckBlock堆叠而成,forward返回(logits, feature)二元组,后者可作为图像特征向量用于检索、相似度等下游任务(见 module.py);
  • 自定义数据集:参考 flowers.py 继承paddle.io.Dataset并实现__getitem__/__len__,即可将Flowers替换为业务自己的图像分类数据;
  • 训练可视化:将Traineruse_vdl置为True后,可在 VisualDL 中实时观察 loss 与 acc 曲线,便于调整learning_rateepochs
  • batch_size 调整:GPU 显存受限时可调小batch_size;反之增大batch_size可提升训练吞吐,需同步关注显存占用。
  • 人工智能
  • 预训练
  • 微调
  • 模型推理服务

【免费下载链接】PaddleFormers

PaddleFormers 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询