diff --git a/docs/zh_CN/models/ImageNet1k/GhostNetV3.md b/docs/zh_CN/models/ImageNet1k/GhostNetV3.md new file mode 100644 index 0000000000..98dc68f71c --- /dev/null +++ b/docs/zh_CN/models/ImageNet1k/GhostNetV3.md @@ -0,0 +1,169 @@ +# GhostNetV3 系列 +----- + +## 目录 + +- [1. 模型介绍](#1) + - [1.1 模型简介](#1.1) + - [1.2 当前支持的模型](#1.2) +- [2. 模型快速体验](#2) +- [3. 模型训练、评估和预测](#3) +- [4. 模型推理部署](#4) + - [4.1 推理模型准备](#4.1) + - [4.2 基于 Python 预测引擎推理](#4.2) + - [4.3 基于 C++ 预测引擎推理](#4.3) + - [4.4 服务化部署](#4.4) + - [4.5 端侧部署](#4.5) + - [4.6 Paddle2ONNX 模型转换与预测](#4.6) + + + +## 1. 模型介绍 + + + +### 1.1 模型简介 + +GhostNetV3 是华为在 GhostNet / GhostNetV2 基础上进一步提出的轻量级分类网络。 + +随机初始化权重前向对齐结果如下: + +| Models | 对齐节点 | max abs diff | mean abs diff | +|:--:|:--:|:--:|:--:| +| GhostNetV3_x0_5 | `forward_features` | `1.60e-07` | `1.00e-08` | +| GhostNetV3_x0_5 | `out` | `1.00e-08` | `0.00e+00` | +| GhostNetV3_x1_3 | `forward_features` | `5.10e-07` | `4.00e-08` | +| GhostNetV3_x1_3 | `out` | `5.00e-08` | `1.00e-08` | +| GhostNetV3_x1_6 | `forward_features` | `5.10e-07` | `4.00e-08` | +| GhostNetV3_x1_6 | `out` | `5.00e-08` | `1.00e-08` | + +对 `GhostNetV3_x1_0`,进一步完成了预训练权重对齐。使用 `timm/ghostnetv3_100.in1k` 权重转换到 Paddle 后,前向误差如下: + +| Models | 权重来源 | 对齐节点 | max abs diff | mean abs diff | +|:--:|:--:|:--:|:--:|:--:| +| GhostNetV3_x1_0 | `timm/ghostnetv3_100.in1k` | `forward_features` | `2.16e-05` | `3.20e-07` | +| GhostNetV3_x1_0 | `timm/ghostnetv3_100.in1k` | `out` | `7.63e-06` | `2.66e-06` | + +在完整 ImageNet1k val 上,使用同一份 `timm` 预训练权重分别在 `timm` 与 PaddleClas 中评测,结果如下: + +| Models | Eval Framework | Top1 | Top5 | +|:--:|:--:|:--:|:--:| +| GhostNetV3_x1_0 | timm | `0.76930` | `0.93132` | +| GhostNetV3_x1_0 | PaddleClas | `0.76896` | `0.93132` | + +进一步地,使用官方仓库 release 中提供的 `ghostnetv3-1.0.pth.tar`,分别评测其中的普通参数 `state_dict` 与指数滑动平均参数 `state_dict_ema`,结果如下: + +| Models | 权重来源 | Eval Framework | Top1 | Top5 | +|:--:|:--:|:--:|:--:|:--:| +| GhostNetV3_x1_0 | official release `state_dict` | PyTorch | `0.76930` | `0.93132` | +| GhostNetV3_x1_0 | official release `state_dict_ema` | PyTorch | `0.77134` | `0.93236` | +| GhostNetV3_x1_0 | official release `state_dict_ema` | PaddleClas | `0.77080` | `0.93228` | + +此外,基于 TIPC 自动准备的 lite ImageNet 数据,对 `GhostNetV3_x0_5 / x1_0 / x1_3 / x1_6` 做了 8 epoch 的快速收敛性验证。该实验仅用于验证训练链路、反向传播与优化过程是否正常,不作为全量 ImageNet 最终精度结论。训练使用统一设置: + +- 数据集:`dataset/whole_chain_little_train` +- 优化器:`Momentum` +- 学习率:`0.02` +- 调度器:`Cosine` +- warmup epoch:`0` +- batch size:`8` + +四个模型在训练过程中均未出现 `NaN/Inf`,训练集平均 loss 如下: + +| Models | Epoch1 | Epoch2 | Epoch3 | Epoch4 | Epoch5 | Epoch6 | Epoch7 | Epoch8 | +|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:| +| GhostNetV3_x0_5 | `7.09630` | `6.30080` | `5.05172` | `4.55270` | `4.34154` | `4.01807` | `3.92502` | `3.71694` | +| GhostNetV3_x1_0 | `7.03280` | `6.07542` | `5.30271` | `4.51359` | `4.12840` | `3.79940` | `3.57494` | `3.39662` | +| GhostNetV3_x1_3 | `7.01563` | `5.74808` | `4.94816` | `4.15918` | `3.70600` | `3.73494` | `3.48128` | `3.28373` | +| GhostNetV3_x1_6 | `7.06830` | `5.93590` | `5.54609` | `4.65743` | `3.91060` | `3.77108` | `3.40826` | `3.37555` | + +从上述结果可以看到,四个宽度变体的训练集平均 loss 都整体明显下降,说明当前 Paddle 实现已经具备正常的训练与收敛行为。 + + + +### 1.2 当前支持的模型 + +| Models | 权重状态 | 前向对齐 | ImageNet eval | lite ImageNet 训练链路 | +|:--:|:--:|:--:|:--:|:--:| +| GhostNetV3_x0_5 | 随机初始化 | 已验证 | 未提供预训练权重 | 已验证 | +| GhostNetV3_x1_0 | `timm` 预训练权重 | 已验证 | 已验证 | 已验证 | +| GhostNetV3_x1_3 | 随机初始化 | 已验证 | 未提供预训练权重 | 已验证 | +| GhostNetV3_x1_6 | 随机初始化 | 已验证 | 未提供预训练权重 | 已验证 | + +训练配置位于: + +- `ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml` + +TIPC 配置位于: + +- `test_tipc/configs/GhostNetV3/GhostNetV3_x1_0_train_infer_python.txt` + + + +## 2. 模型快速体验 + +安装 paddlepaddle 和 paddleclas 即可快速对图片进行预测,体验方法可以参考 [ResNet50 模型快速体验](./ResNet.md#2-模型快速体验)。 + +当前推荐使用的分类模型入口为: + +- `GhostNetV3_x1_0` + +其余宽度变体当前已完成前向对齐,但默认不提供 Paddle 侧预训练模型链接。 + + + +## 3. 模型训练、评估和预测 + +此部分内容包括训练环境配置、ImageNet 数据的准备、该模型在 ImageNet 上的训练、评估、预测等内容。`ppcls/configs/ImageNet/GhostNetV3/` 中提供了当前模型的训练与评估配置,启动方法可以参考:[ResNet50 模型训练、评估和预测](./ResNet.md#3-模型训练评估和预测)。 + +当前推荐优先使用: + +- `GhostNetV3_x1_0.yaml` + + + +## 4. 模型推理部署 + + + +### 4.1 推理模型准备 + +Paddle Inference 是飞桨的原生推理库,作用于服务器端和云端,提供高性能的推理能力。相比于直接基于预训练模型进行预测,Paddle Inference 可使用 MKLDNN、CUDNN、TensorRT 进行预测加速,从而实现更优的推理性能。更多关于 Paddle Inference 推理引擎的介绍,可以参考 [Paddle Inference 官网教程](https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/infer/inference/inference_cn.html)。 + +Inference 的获取可以参考 [ResNet50 推理模型准备](./ResNet.md#41-推理模型准备)。 + + + +### 4.2 基于 Python 预测引擎推理 + +PaddleClas 提供了基于 Python 预测引擎推理的示例。您可以参考 [ResNet50 基于 Python 预测引擎推理](./ResNet.md#42-基于-python-预测引擎推理)。 + + + +### 4.3 基于 C++ 预测引擎推理 + +PaddleClas 提供了基于 C++ 预测引擎推理的示例,您可以参考 [服务器端 C++ 预测](../../deployment/image_classification/cpp/linux.md) 来完成相应的推理部署。如果您使用的是 Windows 平台,可以参考 [基于 Visual Studio 2019 Community CMake 编译指南](../../deployment/image_classification/cpp/windows.md) 完成相应的预测库编译和模型预测工作。 + + + +### 4.4 服务化部署 + +Paddle Serving 提供高性能、灵活易用的工业级在线推理服务。Paddle Serving 支持 RESTful、gRPC、bRPC 等多种协议,提供多种异构硬件和多种操作系统环境下推理解决方案。更多关于 Paddle Serving 的介绍,可以参考 [Paddle Serving 代码仓库](https://github.com/PaddlePaddle/Serving)。 + +PaddleClas 提供了基于 Paddle Serving 来完成模型服务化部署的示例,您可以参考 [模型服务化部署](../../deployment/image_classification/paddle_serving.md) 来完成相应的部署工作。 + + + +### 4.5 端侧部署 + +Paddle Lite 是一个高性能、轻量级、灵活性强且易于扩展的深度学习推理框架,定位于支持包括移动端、嵌入式以及服务器端在内的多硬件平台。更多关于 Paddle Lite 的介绍,可以参考 [Paddle Lite 代码仓库](https://github.com/PaddlePaddle/Paddle-Lite)。 + +PaddleClas 提供了基于 Paddle Lite 来完成模型端侧部署的示例,您可以参考 [端侧部署](../../deployment/image_classification/paddle_lite.md) 来完成相应的部署工作。 + + + +### 4.6 Paddle2ONNX 模型转换与预测 + +Paddle2ONNX 支持将 PaddlePaddle 模型格式转化到 ONNX 模型格式。通过 ONNX 可以完成将 Paddle 模型到多种推理引擎的部署,包括 TensorRT、OpenVINO、MNN、TNN、NCNN,以及其它对 ONNX 开源格式进行支持的推理引擎或硬件。更多关于 Paddle2ONNX 的介绍,可以参考 [Paddle2ONNX 代码仓库](https://github.com/PaddlePaddle/Paddle2ONNX)。 + +PaddleClas 提供了基于 Paddle2ONNX 来完成 inference 模型转换 ONNX 模型并作推理预测的示例,您可以参考 [Paddle2ONNX 模型转换与预测](../../deployment/image_classification/paddle2onnx.md) 来完成相应的部署工作。 diff --git a/ppcls/arch/backbone/__init__.py b/ppcls/arch/backbone/__init__.py index f79dccdfea..c18a62fb4c 100644 --- a/ppcls/arch/backbone/__init__.py +++ b/ppcls/arch/backbone/__init__.py @@ -49,6 +49,12 @@ from .model_zoo.mobilefacenet import MobileFaceNet from .model_zoo.shufflenet_v2 import ShuffleNetV2_x0_25, ShuffleNetV2_x0_33, ShuffleNetV2_x0_5, ShuffleNetV2_x1_0, ShuffleNetV2_x1_5, ShuffleNetV2_x2_0, ShuffleNetV2_swish from .model_zoo.ghostnet import GhostNet_x0_5, GhostNet_x1_0, GhostNet_x1_3 +from .model_zoo.ghostnet_v3 import ( + GhostNetV3_x0_5, + GhostNetV3_x1_0, + GhostNetV3_x1_3, + GhostNetV3_x1_6, +) from .model_zoo.alexnet import AlexNet from .model_zoo.inception_v4 import InceptionV4 from .model_zoo.xception import Xception41, Xception65, Xception71 diff --git a/ppcls/arch/backbone/model_zoo/ghostnet_v3.py b/ppcls/arch/backbone/model_zoo/ghostnet_v3.py new file mode 100644 index 0000000000..519759522d --- /dev/null +++ b/ppcls/arch/backbone/model_zoo/ghostnet_v3.py @@ -0,0 +1,442 @@ +# copyright (c) 2026 PaddlePaddle Authors. All Rights Reserve. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# reference: +# https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/ghostnet.py + +from __future__ import absolute_import, division, print_function + +import math + +import paddle +import paddle.nn as nn +import paddle.nn.functional as F + +from ..base.theseus_layer import Identity +from ....utils.save_load import load_dygraph_pretrain + +MODEL_URLS = { + "GhostNetV3_x0_5": "", + "GhostNetV3_x1_0": "", + "GhostNetV3_x1_3": "", + "GhostNetV3_x1_6": "", +} + +__all__ = list(MODEL_URLS.keys()) + + +def make_divisible(v, divisor=4, min_value=None): + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + if new_v < 0.9 * v: + new_v += divisor + return int(new_v) + + +def _load_pretrained(pretrained, model, model_url): + if pretrained is False: + return + if pretrained is True: + load_dygraph_pretrain(model, model_url) + elif isinstance(pretrained, str): + load_dygraph_pretrain(model, pretrained) + else: + raise RuntimeError( + "pretrained type is not available. Please use `string` or `boolean` type." + ) + + +class SqueezeExcite(nn.Layer): + def __init__(self, in_chs, rd_ratio=0.25): + super().__init__() + rd_channels = make_divisible(in_chs * rd_ratio, divisor=4) + self.conv_reduce = nn.Conv2D(in_chs, rd_channels, kernel_size=1, bias_attr=True) + self.act1 = nn.ReLU() + self.conv_expand = nn.Conv2D(rd_channels, in_chs, kernel_size=1, bias_attr=True) + self.gate = nn.Hardsigmoid() + + def forward(self, x): + x_se = x.mean(axis=(2, 3), keepdim=True) + x_se = self.conv_reduce(x_se) + x_se = self.act1(x_se) + x_se = self.conv_expand(x_se) + return x * self.gate(x_se) + + +class ConvBnAct(nn.Layer): + def __init__( + self, + in_chs, + out_chs, + kernel_size, + stride=1, + pad_type=0, + group_size=0, + act_layer=nn.ReLU, + ): + super().__init__() + groups = 1 if not group_size else in_chs // group_size + self.conv = nn.Conv2D( + in_chs, + out_chs, + kernel_size=kernel_size, + stride=stride, + padding=pad_type, + groups=groups, + bias_attr=False, + ) + self.bn1 = nn.BatchNorm2D(out_chs) + self.act = act_layer() if act_layer is not None else Identity() + + def forward(self, x): + x = self.conv(x) + x = self.bn1(x) + x = self.act(x) + return x + + +class GhostModuleV3(nn.Layer): + def __init__( + self, + in_chs, + out_chs, + kernel_size=1, + ratio=2, + dw_size=3, + stride=1, + act_layer=nn.ReLU, + mode="original", + ): + super().__init__() + self.gate_fn = nn.Sigmoid() + self.out_chs = out_chs + init_chs = int(math.ceil(out_chs / ratio)) + new_chs = init_chs * (ratio - 1) + self.mode = mode + + self.primary_rpr_conv = nn.LayerList( + [ + ConvBnAct( + in_chs, + init_chs, + kernel_size, + stride, + pad_type=kernel_size // 2, + act_layer=None, + ) + for _ in range(3) + ] + ) + self.primary_activation = act_layer() + + self.cheap_rpr_skip = nn.BatchNorm2D(init_chs) + self.cheap_rpr_conv = nn.LayerList( + [ + ConvBnAct( + init_chs, + new_chs, + dw_size, + 1, + pad_type=dw_size // 2, + group_size=1, + act_layer=None, + ) + for _ in range(3) + ] + ) + self.cheap_rpr_scale = ConvBnAct( + init_chs, + new_chs, + 1, + 1, + pad_type=0, + group_size=1, + act_layer=None, + ) + self.cheap_activation = act_layer() + + if self.mode == "shortcut": + self.short_conv = nn.Sequential( + nn.Conv2D( + in_chs, + out_chs, + kernel_size=kernel_size, + stride=stride, + padding=kernel_size // 2, + bias_attr=False, + ), + nn.BatchNorm2D(out_chs), + nn.Conv2D( + out_chs, + out_chs, + kernel_size=(1, 5), + stride=1, + padding=(0, 2), + groups=out_chs, + bias_attr=False, + ), + nn.BatchNorm2D(out_chs), + nn.Conv2D( + out_chs, + out_chs, + kernel_size=(5, 1), + stride=1, + padding=(2, 0), + groups=out_chs, + bias_attr=False, + ), + nn.BatchNorm2D(out_chs), + ) + else: + self.short_conv = Identity() + + def forward(self, x): + x1 = 0 + for branch in self.primary_rpr_conv: + x1 = x1 + branch(x) + x1 = self.primary_activation(x1) + + x2 = self.cheap_rpr_scale(x1) + self.cheap_rpr_skip(x1) + for branch in self.cheap_rpr_conv: + x2 = x2 + branch(x1) + x2 = self.cheap_activation(x2) + + out = paddle.concat([x1, x2], axis=1) + if self.mode != "shortcut": + return out + + res = self.short_conv(F.avg_pool2d(x, kernel_size=2, stride=2)) + gate = F.interpolate(self.gate_fn(res), size=out.shape[-2:], mode="nearest") + return out[:, : self.out_chs, :, :] * gate + + +class GhostBottleneckV3(nn.Layer): + def __init__( + self, + in_chs, + mid_chs, + out_chs, + dw_kernel_size=3, + stride=1, + act_layer=nn.ReLU, + se_ratio=0.0, + mode="original", + ): + super().__init__() + self.stride = stride + self.ghost1 = GhostModuleV3( + in_chs, + mid_chs, + act_layer=act_layer, + mode=mode, + ) + + if self.stride > 1: + self.dw_rpr_conv = nn.LayerList( + [ + ConvBnAct( + mid_chs, + mid_chs, + dw_kernel_size, + stride, + pad_type=(dw_kernel_size - 1) // 2, + group_size=1, + act_layer=None, + ) + for _ in range(3) + ] + ) + self.dw_rpr_scale = ConvBnAct( + mid_chs, + mid_chs, + 1, + 2, + pad_type=0, + group_size=1, + act_layer=None, + ) + else: + self.dw_rpr_conv = nn.LayerList() + self.dw_rpr_scale = Identity() + + self.se = ( + SqueezeExcite(mid_chs, rd_ratio=se_ratio) if se_ratio > 0 else Identity() + ) + self.ghost2 = GhostModuleV3( + mid_chs, + out_chs, + act_layer=Identity, + mode="original", + ) + + if in_chs == out_chs and self.stride == 1: + self.shortcut = Identity() + else: + self.shortcut = nn.Sequential( + nn.Conv2D( + in_chs, + in_chs, + dw_kernel_size, + stride=stride, + padding=(dw_kernel_size - 1) // 2, + groups=in_chs, + bias_attr=False, + ), + nn.BatchNorm2D(in_chs), + nn.Conv2D( + in_chs, + out_chs, + kernel_size=1, + stride=1, + padding=0, + bias_attr=False, + ), + nn.BatchNorm2D(out_chs), + ) + + def forward(self, x): + shortcut = x + x = self.ghost1(x) + + if self.stride > 1: + x1 = self.dw_rpr_scale(x) + for branch in self.dw_rpr_conv: + x1 = x1 + branch(x) + x = x1 + + x = self.se(x) + x = self.ghost2(x) + x = x + self.shortcut(shortcut) + return x + + +class GhostNetV3(nn.Layer): + def __init__(self, width=1.0, class_num=1000, in_chans=3, drop_rate=0.2): + super().__init__() + self.cfgs = [ + [[3, 16, 16, 0, 1]], + [[3, 48, 24, 0, 2]], + [[3, 72, 24, 0, 1]], + [[5, 72, 40, 0.25, 2]], + [[5, 120, 40, 0.25, 1]], + [[3, 240, 80, 0, 2]], + [ + [3, 200, 80, 0, 1], + [3, 184, 80, 0, 1], + [3, 184, 80, 0, 1], + [3, 480, 112, 0.25, 1], + [3, 672, 112, 0.25, 1], + ], + [[5, 672, 160, 0.25, 2]], + [ + [5, 960, 160, 0, 1], + [5, 960, 160, 0.25, 1], + [5, 960, 160, 0, 1], + [5, 960, 160, 0.25, 1], + ], + ] + self.drop_rate = drop_rate + stem_chs = make_divisible(16 * width, 4) + self.conv_stem = nn.Conv2D( + in_chans, stem_chs, 3, stride=2, padding=1, bias_attr=False + ) + self.bn1 = nn.BatchNorm2D(stem_chs) + self.act1 = nn.ReLU() + + prev_chs = stem_chs + stages = [] + layer_idx = 0 + exp_size = 0 + for cfg in self.cfgs: + layers = [] + for k, exp_size, c, se_ratio, s in cfg: + out_chs = make_divisible(c * width, 4) + mid_chs = make_divisible(exp_size * width, 4) + mode = "shortcut" if layer_idx > 1 else "original" + layers.append( + GhostBottleneckV3( + prev_chs, + mid_chs, + out_chs, + dw_kernel_size=k, + stride=s, + act_layer=nn.ReLU, + se_ratio=se_ratio, + mode=mode, + ) + ) + prev_chs = out_chs + layer_idx += 1 + stages.append(nn.Sequential(*layers)) + + out_chs = make_divisible(exp_size * width, 4) + stages.append(nn.Sequential(ConvBnAct(prev_chs, out_chs, 1))) + self.num_features = out_chs + self.blocks = nn.Sequential(*stages) + + self.global_pool = nn.AdaptiveAvgPool2D(1) + self.conv_head = nn.Conv2D( + out_chs, 1280, 1, stride=1, padding=0, bias_attr=True + ) + self.act2 = nn.ReLU() + self.flatten = nn.Flatten(start_axis=1, stop_axis=-1) + self.classifier = nn.Linear(1280, class_num) if class_num > 0 else Identity() + + def forward_features(self, x): + x = self.conv_stem(x) + x = self.bn1(x) + x = self.act1(x) + x = self.blocks(x) + return x + + def forward_head(self, x, pre_logits=False): + x = self.global_pool(x) + x = self.conv_head(x) + x = self.act2(x) + x = self.flatten(x) + if self.drop_rate > 0.0: + x = F.dropout(x, p=self.drop_rate, training=self.training) + if pre_logits: + return x + return self.classifier(x) + + def forward(self, x): + x = self.forward_features(x) + x = self.forward_head(x) + return x + + +def GhostNetV3_x0_5(pretrained=False, **kwargs): + model = GhostNetV3(width=0.5, **kwargs) + _load_pretrained(pretrained, model, MODEL_URLS["GhostNetV3_x0_5"]) + return model + + +def GhostNetV3_x1_0(pretrained=False, **kwargs): + model = GhostNetV3(width=1.0, **kwargs) + _load_pretrained(pretrained, model, MODEL_URLS["GhostNetV3_x1_0"]) + return model + + +def GhostNetV3_x1_3(pretrained=False, **kwargs): + model = GhostNetV3(width=1.3, **kwargs) + _load_pretrained(pretrained, model, MODEL_URLS["GhostNetV3_x1_3"]) + return model + + +def GhostNetV3_x1_6(pretrained=False, **kwargs): + model = GhostNetV3(width=1.6, **kwargs) + _load_pretrained(pretrained, model, MODEL_URLS["GhostNetV3_x1_6"]) + return model diff --git a/ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml b/ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml new file mode 100644 index 0000000000..d3f7525ed8 --- /dev/null +++ b/ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml @@ -0,0 +1,144 @@ +# global configs +Global: + checkpoints: null + pretrained_model: null + output_dir: ./output/ + device: gpu + save_interval: 1 + eval_during_train: True + eval_interval: 1 + epochs: 360 + print_batch_step: 10 + use_visualdl: False + image_shape: [3, 224, 224] + save_inference_dir: ./inference + + +AMP: + use_amp: False + use_fp16_test: False + scale_loss: 128.0 + use_dynamic_loss_scaling: True + use_promote: False + level: O1 + + +Arch: + name: GhostNetV3_x1_0 + class_num: 1000 + + +Loss: + Train: + - CELoss: + weight: 1.0 + epsilon: 0.1 + Eval: + - CELoss: + weight: 1.0 + + +Optimizer: + name: Momentum + momentum: 0.9 + lr: + name: Cosine + learning_rate: 0.8 + warmup_epoch: 5 + regularizer: + name: 'L2' + coeff: 0.00004 + + +DataLoader: + Train: + dataset: + name: ImageNetDataset + image_root: ./dataset/ILSVRC2012/ + cls_label_path: ./dataset/ILSVRC2012/train_list.txt + transform_ops: + - DecodeImage: + to_rgb: True + channel_first: False + - RandCropImage: + size: 224 + interpolation: bicubic + backend: pil + - RandFlipImage: + flip_code: 1 + - NormalizeImage: + scale: 1.0/255.0 + mean: [0.485, 0.456, 0.406] + std: [0.229, 0.224, 0.225] + order: '' + sampler: + name: DistributedBatchSampler + batch_size: 512 + drop_last: False + shuffle: True + loader: + num_workers: 4 + use_shared_memory: True + + Eval: + dataset: + name: ImageNetDataset + image_root: ./dataset/ILSVRC2012/ + cls_label_path: ./dataset/ILSVRC2012/val_list.txt + transform_ops: + - DecodeImage: + to_rgb: True + channel_first: False + - ResizeImage: + resize_short: 256 + interpolation: bicubic + backend: pil + - CropImage: + size: 224 + - NormalizeImage: + scale: 1.0/255.0 + 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: 4 + use_shared_memory: True + + +Infer: + infer_imgs: docs/images/inference_deployment/whl_demo.jpg + batch_size: 10 + transforms: + - DecodeImage: + to_rgb: True + channel_first: False + - ResizeImage: + resize_short: 256 + interpolation: bicubic + backend: pil + - CropImage: + size: 224 + - NormalizeImage: + scale: 1.0/255.0 + 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] diff --git a/test_tipc/configs/GhostNetV3/GhostNetV3_x1_0_train_infer_python.txt b/test_tipc/configs/GhostNetV3/GhostNetV3_x1_0_train_infer_python.txt new file mode 100644 index 0000000000..ef73542fb6 --- /dev/null +++ b/test_tipc/configs/GhostNetV3/GhostNetV3_x1_0_train_infer_python.txt @@ -0,0 +1,54 @@ +===========================train_params=========================== +model_name:GhostNetV3_x1_0 +python:python3.7 +gpu_list:0|0,1 +-o Global.device:gpu +-o Global.auto_cast:null +-o Global.epochs:lite_train_lite_infer=2|whole_train_whole_infer=120 +-o Global.output_dir:./output/ +-o DataLoader.Train.sampler.batch_size:8 +-o Global.pretrained_model:null +train_model_name:latest +train_infer_img_dir:./dataset/ILSVRC2012/val +null:null +## +trainer:norm_train +norm_train:tools/train.py -c ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml -o Global.seed=1234 -o DataLoader.Train.sampler.shuffle=False -o DataLoader.Train.loader.num_workers=0 -o DataLoader.Train.loader.use_shared_memory=False -o Global.eval_during_train=False -o Global.save_interval=2 +pact_train:null +fpgm_train:null +distill_train:null +null:null +null:null +## +===========================eval_params=========================== +eval:tools/eval.py -c ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml +null:null +## +===========================infer_params========================== +-o Global.save_inference_dir:./inference +-o Global.pretrained_model: +norm_export:tools/export_model.py -c ppcls/configs/ImageNet/GhostNetV3/GhostNetV3_x1_0.yaml +quant_export:null +fpgm_export:null +distill_export:null +kl_quant:null +export2:null +pretrained_model_url: +infer_model:../inference/ +infer_export:True +infer_quant:Fasle +inference:python/predict_cls.py -c configs/inference_cls.yaml +-o Global.use_gpu:True|False +-o Global.enable_mkldnn:False +-o Global.cpu_num_threads:1 +-o Global.batch_size:1 +-o Global.use_tensorrt:False +-o Global.use_fp16:False +-o Global.inference_model_dir:../inference +-o Global.infer_imgs:../dataset/ILSVRC2012/val/ILSVRC2012_val_00000001.JPEG +-o Global.save_log_path:null +-o Global.benchmark:False +null:null +null:null +===========================infer_benchmark_params========================== +random_infer_input:[{float32,[3,224,224]}]