未验证 提交 22c81686 编写于 作者: C cuicheng01 提交者: GitHub

Merge pull request #1580 from Sibo2rr/dev/doc2

Dev/doc2
......@@ -5,8 +5,10 @@
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
#SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
......
# PaddleClas 社区贡献指南
---
------
## 目录
......@@ -48,10 +48,7 @@ PaddleClas 欢迎大家向 repo 中积极贡献代码,下面给出一些贡献
* 跳转到 [PaddleClas GitHub 首页](https://github.com/PaddlePaddle/PaddleClas),然后单击 Fork 按钮,生成自己目录下的仓库,比如 `https://github.com/USERNAME/PaddleClas`
<div align="center">
<img src="../../images/quick_start/community/001_fork.png" width = "600" />
</div>
![](../../images/quick_start/community/001_fork.png)
* 将远程仓库 clone 到本地
......@@ -63,9 +60,7 @@ cd PaddleClas
clone 的地址可以从下面获取
<div align="center">
<img src="../../images/quick_start/community/002_clone.png" width = "600" />
</div>
![](../../images/quick_start/community/002_clone.png)
<a name="1.2.2"></a>
#### 1.2.2 和远程仓库建立连接
......@@ -150,10 +145,7 @@ pre-commit
重复上述步骤,直到 pre-comit 格式检查不报错。如下所示。
<div align="center">
<img src="../../images/quick_start/community/003_precommit_pass.png" width = "600" />
</div>
![](../../images/quick_start/community/003_precommit_pass.png)
使用下面的命令完成提交。
......@@ -184,10 +176,7 @@ git push origin new_branch
点击 new pull request,选择本地分支和目标分支,如下图所示。在 PR 的描述说明中,填写该 PR 所完成的功能。接下来等待 review,如果有需要修改的地方,参照上述步骤更新 origin 中的对应分支即可。
<div align="center">
<img src="../../images/quick_start/community/004_create_pr.png" width = "600" />
</div>
![](../../images/quick_start/community/004_create_pr.png)
<a name="1.2.9"></a>
#### 1.2.9 签署 CLA 协议和通过单元测试
......
......@@ -31,10 +31,7 @@
深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标 [1]。 PaddleClas 融合已有的蒸馏方法 [2,3],提供了一种简单的半监督标签知识蒸馏方案(SSLD,Simple Semi-supervised Label Distillation),基于 ImageNet1k 分类数据集,在 ResNet_vd 以及 MobileNet 系列上的精度均有超过 3% 的绝对精度提升,具体指标如下图所示。
<div align="center">
<img src="../../images/distillation/distillation_perform_s.jpg" width = "600" />
</div>
![](../../images/distillation/distillation_perform_s.jpg)
<a name="2"></a>
## 2. SSLD 蒸馏策略
......@@ -43,10 +40,7 @@
SSLD 的流程图如下图所示。
<div align="center">
<img src="../../images/distillation/ppcls_distillation.png" width = "600" />
</div>
![](../../images/distillation/ppcls_distillation.png)
首先,我们从 ImageNet22k 中挖掘出了近 400 万张图片,同时与 ImageNet-1k 训练集整合在一起,得到了一个新的包含 500 万张图片的数据集。然后,我们将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,我们将两个模型的 logits 经过 softmax 激活函数转换为 soft label,并将二者的 soft label 做 JS 散度作为损失函数,用于蒸馏模型训练。下面以 MobileNetV3(该模型直接训练,精度为 75.3%)的知识蒸馏为例,介绍该方案的核心关键点(baseline 为 79.12% 的 ResNet50_vd 模型蒸馏 MobileNetV3,训练集为 ImageNet1k 训练集,loss 为 cross entropy loss,迭代轮数为 120epoch,精度指标为 75.6%)。
* 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于 79.12% 的 ResNet50_vd 教师模型,使用 82.4% 的 ResNet50_vd 教师模型可以带来 0.4% 的绝对精度收益(`75.6%->76.0%`)。
......@@ -66,9 +60,7 @@ SSLD 的流程图如下图所示。
* SSLD 蒸馏方案的一大特色就是无需使用图像的真值标签,因此可以任意扩展数据集的大小,考虑到计算资源的限制,我们在这里仅基于 ImageNet22k 数据集对蒸馏任务的训练集进行扩充。在 SSLD 蒸馏任务中,我们使用了 `Top-k per class` 的数据采样方案 [3] 。具体步骤如下。
* 训练集去重。我们首先基于 SIFT 特征相似度匹配的方式对 ImageNet22k 数据集与 ImageNet1k 验证集进行去重,防止添加的 ImageNet22k 训练集中包含 ImageNet1k 验证集图像,最终去除了 4511 张相似图片。部分过滤的相似图片如下所示。
<div align="center">
<img src="../../images/distillation/22k_1k_val_compare_w_sift.png" width = "600" />
</div>
![](../../images/distillation/22k_1k_val_compare_w_sift.png)
* 大数据集 soft label 获取,对于去重后的 ImageNet22k 数据集,我们使用 `ResNeXt101_32x16d_wsl` 模型进行预测,得到每张图片的 soft label 。
* Top-k 数据选择,ImageNet1k 数据共有 1000 类,对于每一类,找出属于该类并且得分最高的 `k` 张图片,最终得到一个数据量不超过 `1000*k` 的数据集(某些类上得到的图片数量可能少于 `k` 张)。
......
......@@ -44,21 +44,15 @@
常见服务器端模型的精度指标与其预测耗时的变化曲线如下图所示。
<div align="center">
<img src="../../images/models/V100_benchmark/v100.fp32.bs1.main_fps_top1_s.png" width="800">
</div>
![](../../images/models/V100_benchmark/v100.fp32.bs1.main_fps_top1_s.png)
常见移动端模型的精度指标与其预测耗时的变化曲线如下图所示。
<div align="center">
<img src="../../images/models/mobile_arm_top1.png" width="800">
</div>
![](../../images/models/mobile_arm_top1.png)
部分VisionTransformer模型的精度指标与其预测耗时的变化曲线如下图所示
部分VisionTransformer模型的精度指标与其预测耗时的变化曲线如下图所示.
<div align="center">
<img src="../../images/models/V100_benchmark/v100.fp32.bs1.visiontransformer.png" width="800">
</div>
![](../../images/models/V100_benchmark/v100.fp32.bs1.visiontransformer.png)
<a name="2"></a>
......
# Image Classification
# 图像分类任务介绍
## 目录
......
......@@ -4,9 +4,9 @@
.. toctree::
:maxdepth: 2
model_prune_quantization.md
ImageNet_models.md
image_classification.md
metric_learning.md
knowledge_distillation.md
image_classification.md
model_prune_quantization.md
ImageNet_models.md
DataAugmentation.md
......@@ -19,26 +19,17 @@
**PACT 量化(PArameterized Clipping acTivation**是一种新的量化方法,该方法通过在量化激活值之前去掉一些离群点,将模型量化带来的精度损失降到最低,甚至比原模型准确率更高。提出方法的背景是作者发现:“在运用权重量化方案来量化 activation 时,激活值的量化结果和全精度结果相差较大”。作者发现,activation 的量化可能引起的误差很大(相较于 weight 基本在 0 到 1 范围内,activation 的值的范围是无限大的,这是 RELU 的结果),所以提出**截断式 RELU** 的激活函数。该截断的上界,即$α$ 是可学习的参数,这保证了每层能够通过训练学习到不一样的量化范围,最大程度降低量化带来的舍入误差。其中量化的示意图如下图所示,**PACT** 解决问题的方法是,不断裁剪激活值范围,使得激活值分布收窄,从而降低量化映射损失。**PACT** 通过对激活数值做裁剪,从而减少激活分布中的离群点,使量化模型能够得到一个更合理的量化 scale,降低量化损失。
<div align="center">
<img src="../../images/algorithm_introduction/quantization.jpg" width = "600" />
</div>
![](../../images/algorithm_introduction/quantization.jpg)
**PACT** 量化公式如下:
<div align="center">
<img src="../../images/algorithm_introduction/quantization_formula.png" width = "800" height="100"/>
</div>
![](../../images/algorithm_introduction/quantization_formula.png)
可以看出 PACT 思想是用上述量化代替 *ReLU* 函数,对大于零的部分进行一个截断操作,截断阈值为$a$。但是在*PaddleSlim*中对上述公式做了进一步的改进,其改进如下:
<div align="center">
<img src="../../images/algorithm_introduction/quantization_formula_slim.png" width = "550" height="120"/>
</div>
![](../../images/algorithm_introduction/quantization_formula_slim.png)
经过如上改进后,在激活值和待量化的 OP(卷积,全连接等)之间插入 *PACT* 预处理,不只对大于 0 的分布进行截断,同时也对小于 0 的部分做同样的限制,从而更好地得到待量化的范围,降低量化损失。同时,截断阈值是一个可训练的参数,在量化训练过程中,模型会自动的找到一个合理的截断阈值,从而进一步降低量化精度损失。
......@@ -54,10 +45,7 @@
基于此,**FPGM**利用层中 filter 的几何中心特性,由于那些靠近中心的 filter 可以被其它的表达,因而可以将其剔除,从而避免了上面提到的两点剪枝条件,从信息的冗余度出发,而不是选择范数少的进行剪枝。下图展示了 **FPGM** 方法与之前方法的不同,具体细节请详看[论文](https://openaccess.thecvf.com/content_CVPR_2019/papers/He_Filter_Pruning_via_Geometric_Median_for_Deep_Convolutional_Neural_Networks_CVPR_2019_paper.pdf)
<div align="center">
<img src="../../images/algorithm_introduction/fpgm.png" width = "600" />
</div>
![](../../images/algorithm_introduction/fpgm.png)
......
......@@ -14,23 +14,13 @@
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import sphinx_rtd_theme
import sphinx_markdown_tables
import recommonmark
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
from recommonmark.parser import CommonMarkParser
#import sphinx-markdown-tables
# -- Project information -----------------------------------------------------
source_parsers = {
'.md': CommonMarkParser,
}
source_suffix = ['.rst', '.md']
extensions = [
'recommonmark',
'sphinx_markdown_tables'
]
project = 'paddleclas'
copyright = '2021, paddleclas'
author = 'paddleclas'
project = 'PaddleClas'
copyright = '2021, PaddleClas'
author = 'PaddleClas'
# The full version, including alpha/beta/rc tags
release = '2.3.0'
......@@ -41,6 +31,14 @@ release = '2.3.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
source_parsers = {
'.md': CommonMarkParser,
}
source_suffix = ['.rst', '.md']
extensions = [
'recommonmark',
'sphinx_markdown_tables'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
......@@ -55,7 +53,7 @@ language = 'zh_CN'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
......@@ -63,7 +61,8 @@ exclude_patterns = []
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
......
......@@ -28,10 +28,7 @@
**A**:
ResNet_va 至 vd 的结构如下图所示,ResNet 最早提出时为 va 结构,在降采样残差模块这个部分,在左边的特征变换通路中(Path A),第一个 1x1 卷积部分就行了降采样,从而导致信息丢失(卷积的 kernel size 为 1,stride 为 2,输入特征图中 有部分特征没有参与卷积的计算);在 vb 结构中,把降采样的步骤从最开始的第一个 1x1 卷积调整到中间的 3x3 卷积中,从而避免了信息丢失的问题,PaddleClas 中的 ResNet 模型默认就是 ResNet_vb;vc 结构则是将最开始这个 7x7 的卷积变成 3 个 3x3 的卷积,在感受野不变的情况下,计算量和存储大小几乎不变,而且实验证明精度相对于 vb 结构有所提升;vd 结构是修改了降采样残差模块右边的特征通路(Path B)。把降采样的过程由平均池化这个操作去替代了,这一系列的改进(va->vd),几乎没有带来新增的预测耗时,结合适当的训练策略,比如说标签平滑以及 mixup 数据增广,精度可以提升高达 2.7%。
<div align="center">
<img src="../../images/faq/ResNet_vabcd_structure.png" width="800">
</div>
![](../../images/faq/ResNet_vabcd_structure.png)
### Q1.4 如果确定使用 ResNet 系列模型,怎么根据实际的场景需求选用不同的模型呢?
**A**:
......@@ -40,22 +37,13 @@ ResNet 系列模型中,相比于其他模型,ResNet_vd 模型在预测速度
* 精度-预测速度变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.png" width="800">
</div>
![](../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.png)
* 精度-params 变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.params.png" width="800">
</div>
![](../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.params.png)
* 精度-flops 变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.flops.png" width="800">
</div>
![](../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.flops.png)
### Q1.5 在网络中的 block 里 conv-bn-relu 是固定的形式吗?
**A**: 在 batch-norm 出现之前,主流的卷积神经网络的固定形式是 conv-relu。在现阶段的卷积神经网络中,conv-bn-relu 是大部分网络中 block 的固定形式,这样的设计是相对鲁棒的结构,此外,DenseNet 中的 block 选用的是 bn-relu-conv 的形式,ResNet-V2 中也使用的是这种组合方式。在 MobileNetV2 中,为了不丢失信息,部分 block 中间的层没有使用 relu 激活函数,选用的是 conv-bn 的形式。
......@@ -130,7 +118,7 @@ ResNet 系列模型中,相比于其他模型,ResNet_vd 模型在预测速度
* 对于一个 batch 图像的增广,可以参考[基于 batch 数据的数据增广脚本](../../../ppcls/data/preprocess/batch_ops),参考 `MixupOperator` 或者 `CutmixOperator` 等数据算子的写法,创建一个新的类,然后在 `__call__` 中,实现对应的增广方法即可。
## Q3.5: 怎么进一步加速模型训练过程呢?
### Q3.5: 怎么进一步加速模型训练过程呢?
**A**
......@@ -164,18 +152,14 @@ AMP:
* 然而 *HRNet* 的作者认为这种逐步降低空间分辨率的设计思想并不适合目标检测(图像区域层次的分类任务)、语义分割(图像像素层次的分类任务)等场景,因为空间分辨率在逐步降低的过程中,会丢失很多信息,最终学习得到的特征难以表达原始图像在高空间分辨率的信息,而区域层次分类任务和像素层次分类任务都对空间精度十分敏感。
* 因此 *HRNet* 的作者提出了并联不同空间分辨率特征图的思想,与此相对,*VGG* 等神经网络则是通过不同的卷积池化层来串联不同空间分辨率的特征图。并且,*HRNet* 通过连接同等深度、不同空间分辨率的特征图,使得不同空间分辨率特征图的信息可以得到充分交换,具体的网络结构如下图所示。
<div align="center">
<img src="../../images/faq/HRNet.png" width="800">
</div>
![](../../images/faq/HRNet.png)
### Q4.3: 在 HRNet 中,对于不同空间分辨率的特征图之间,是如何建立连接的?
**A**:
* 首先,在 *HRNet* 中,对特征图使用 *stride**2**3 × 3* 卷积,可以得到低空间分辨率但是为度更高的特征图;而对低空间分辨率特征图先使用 *1 × 1* 卷积进行通道数匹配,再使用最近邻插值的方式进行上采样,即可得到与高空间分辨率特征图相同空间分辨率、通道数的特征图;而对于相同空间分辨率的特征图,直接进行恒等映射即可。具体如下图所示。
<div align="center">
<img src="../../images/faq/HRNet_block.png" width="800">
</div>
![](../../images/faq/HRNet_block.png)
### Q4.4: 模型中的“SE”表示什么意思?
......@@ -184,10 +168,7 @@ AMP:
### Q4.5: SE 结构具体如何实现的?
<div align="center">
<img src="../../images/faq/SE_structure.png" width="800">
</div>
![](../../images/faq/SE_structure.png)
**A**:
* *SE*结构具体如上图所示,首先,*Ftr* 表示常规的卷积操作,*X**U* 则是 *Ftr* 的输入与输出的特征图,在得到特征图*U*后,使用 *Fsq**Fex* 操作求得 *scale* 向量,*scale* 向量维度为 *C*,与 *U* 通道数相同,因此可以通过乘积的方式作用到 *U* 上,进而得到 *X~*
* 具体地,*Fsq**Global Average Pooling* 操作,*SENet* 作者将其称之为 *Squeeze*,因为该操作可以将 *U**C × H × W* 压缩到 *C × 1 × 1*,对 *Fsq* 的输出再做 *Fex* 操作。
......
......@@ -98,31 +98,23 @@ ACNet 意为“Asymmetric Convolution Block”,即为非对称卷积模块,
在训练中,通过 ACB 结构,模型的网络宽度得到了提高,利用 `1*d``d*1` 的两个非对称卷积核提取得到更多的特征用于丰富 `d*d` 卷积核提取的特征图的信息。而在推理阶段,这种设计思想并没有带来额外的参数与计算开销。如下图所示,分别是用于训练阶段和部署推理阶段的卷积核形式。
<div align="center">
<img src="../../images/faq/TrainingtimeACNet.png" width="400">
</div>
![](../../images/faq/TrainingtimeACNet.png)
<div align="center">
<img src="../../images/faq/DeployedACNet.png" width="400">
</div>
![](../../images/faq/DeployedACNet.png)
文章作者的实验表明,通过在原有网络模型训练中使用 ACNet 结构可以显著提高模型能力,原作者对此有如下解释:
1. 实验表明,对于一个 `d*d` 的卷积核,相对于消除卷积核角落位置(如上图中卷积核的 `corners` 位置)的参数而言,消除骨架位置(如上图中卷积核的 `skeleton` 位置)的参数会给模型精度带来更大的影响,因此卷积核骨架位置的参数要更为重要,而 ACB 结构中的两个非对称卷积核增强了方形卷积核骨架位置参数的权重,使之作用更为显著。这种相加是否会因正负数抵消作用而减弱骨架位置的参数作用,作者通过实验发现,网络的训练总是会向着提高骨架位置参数作用的方向发展,并没有出现正负数抵消而减弱的现象。
2. 非对称卷积核对于翻转的图像具有更强的鲁棒性,如下图所示,水平的非对称卷积核对于上下翻转的图像具有更强的鲁棒性。对于翻转前后图像中语义上的同一位置,非对称卷积核提取的特征图是相同的,这一点要强于方形卷积核。
<div align="center">
<img src="../../images/faq/HorizontalKernel.png" width="400">
</div>
![](../../images/faq/HorizontalKernel.png)
### Q3.3: RepVGG 的创新点主要在哪里?
**A**
通过 Q3.1 与 Q3.2,我们可以大胆想到,是否可以借鉴 ACNet 将训练阶段与推理阶段解耦,并且训练阶段使用多分支结构,推理阶段使用 Plain 结构,这也就是 RepVGG 的创新点。下图为 ResNet、RepVGG 训练和推理阶段网络结构的对比。
<div align="center">
<img src="../../images/faq/RepVGG.png" width="400">
</div>
![](../../images/faq/RepVGG.png)
首先训练阶段的 RepVGG 采用多分支结构,可以看作是在传统 VGG 网络的基础上,增加了 `1*1` 卷积和恒等映射的残差结构,而推理阶段的 RepVGG 则退化为 VGG 结构。训练阶段 RepVGG 到推理阶段 RepVGG 的网络结构转换使用“结构重参数化”技术实现。
......@@ -133,9 +125,7 @@ ACNet 意为“Asymmetric Convolution Block”,即为非对称卷积模块,
**A**
通过上面的了解,可以简单理解 RepVGG 是更为极端的 ACNet。ACNet 中的 re-parameters 操作如下图所示:
<div align="center">
<img src="../../images/faq/ACNetReParams.png" width="400">
</div>
![](../../images/faq/ACNetReParams.png)
观察上图,以其中的 `conv2` 为例,该非对称卷积可以视为 `3*3` 的方形卷积核,只不过该方形卷积核的上下六个参数为 `0``conv3` 同理。并且,`conv1``conv2``conv3` 的结果相加,等同于三个卷积核相加再做卷积,以 `Conv` 表示卷积操作,`+`表示矩阵的加法操作,则:`Conv1(A)+Conv2(A)+Conv3(A) == Convk(A)`,其中 `Conv1``Conv2``Conv3` 的卷积核分别为 `Kernel1``kernel2``kernel3`,而 `Convk` 的卷积核为 `Kernel1 + kernel2 + kernel3`
......@@ -147,9 +137,7 @@ RepVGG 网络与 ACNet 同理,只不过 ACNet 的 `1*d` 非对称卷积变成
影响模型计算速度的因素有很多,参数量只是其中之一。具体来说,在不考虑硬件差异的前提下,模型的计算速度可以参考以下几个方面:
1. 参数量:用于衡量模型的参数数量,模型的参数量越大,模型在计算时对内存(显存)的容量要求一般也更高。但内存(显存)占用大小不完全取决于参数量。如下图中,假设输入特征图内存占用大小为 `1` 个单位,对于左侧的残差结构而言,由于需要记录两个分支的运算结果,然后再相加,因此该结构在计算时的内存峰值占用是右侧 Plain 结构的两倍。
<div align="center">
<img src="../../images/faq/MemoryOccupation.png" width="400">
</div>
![](../../images/faq/MemoryOccupation.png)
2. 浮点运算数量(FLOPs):注意与每秒浮点运算次数(FLOPS)相区分。FLOPs 可以简单理解为计算量,通常用来衡量一个模型的计算复杂度。
以常见的卷积操作为例,在不考虑 batch size、激活函数、stride 操作、bias 的前提下,假设 input future map 尺寸为 `Min*Min`,通道数为 `Cin`,output future map 尺寸为 `Mout*Mout`,通道数为 `Cout`,conv kernel 尺寸为 `K*K`,则进行一次卷积的 FLOPs 可以通过下述方式计算:
......@@ -197,23 +185,17 @@ RepVGG 网络与 ACNet 同理,只不过 ACNet 的 `1*d` 非对称卷积变成
* (1)不定长度的顺序输入,因为它是 RNN 结构,一句话,单词数不一样。如果是 NLP 场景,换词的顺序不太过于影响语义,但是图像换了不同区域的位置,不同区域连接顺序不同,将造成极大理解偏差。
* (2)单个 patch 位置信息通过变换成一个维度固定的向量,Encoder 输入是 patch 像素信息 embedding,与一些固定位置的向量 concate,合成一个维度固定的向量和位置信息在其中。
<div align="center">
<img src="../../images/faq/Transformer_input.png" width="400">
</div>
![](../../images/faq/Transformer_input.png)
3. 考虑以下问题:怎样将一张图片传给 encoder?
* 如下图所示。假设输入图片是[224,224,3],按照顺序从左到右,从上到下,切分成很多个 patch,patch 大小可以为[p,p,3](p 取值可以是 16,32),对其使用 Linear Projection of Flattened Patches 模块转成特征向量,并 concat 一个位置向量,传入 Encoder 中。
<div align="center">
<img src="../../images/faq/ViT_structure.png" width="400">
</div>
![](../../images/faq/ViT_structure.png)
4. 如上图,给定一个 `H×W×C` 的图像以及区块大小 P,可以把图像划分为 `N``P×P×C` 的区块,`N=H×W/(P×P)`。得到区块后要使用线性变换转为 D 维特征向量,再加上位置编码向量即可。和 BERT 类似,ViT 在序列之前也加入了一个分类标志位,记为 `[CLS]`。ViT 输入序列 `z` 如下面的公式所示,其中 `x` 表示一个图像区块。
<div align="center">
<img src="../../images/faq/ViT.png" width="400">
</div>
![](../../images/faq/ViT.png)
5. ViT 模型和 Transformer 基本一样,输入序列传入 ViT,然后利用 `[CLS]` 标志位的最终输出特征进行分类。ViT 主要由 MSA(多头自注意力)和 MLP(两层使用 GELU 激活函数的全连接网络)组成,在 MSA 和 MLP 之前加上 LayerNorm 和残差连接。
......
......@@ -113,9 +113,7 @@ w_t+1 = w_t - v_t+1
```
其中,`m` 即为动量 `momentum`,表示累积动量的加权值,一般取 `0.9`,当取值小于 `1` 时,则越早期的梯度对当前的影响越小,例如,当动量参数 `m``0.9` 时,在 `t` 时刻,`t-5` 的梯度加权值为 `0.9 ^ 5 = 0.59049`,而 `t-2` 时刻的梯度加权值为 `0.9 ^ 2 = 0.81`。因此,太过“久远”的梯度信息对当前的参考意义很小,而“最近”的历史梯度信息对当前影响更大,这也是符合直觉的。
<div align="center">
<img src="../../images/faq/momentum.jpeg" width="400">
</div>
![](../../images/faq/momentum.jpeg)
通过引入动量的概念,在参数更新时考虑了历史更新的影响,因此可以加快收敛速度,也改善了 `SGD` 优化器带来的损失(cost、loss)震荡问题。
......
......@@ -36,6 +36,7 @@
## 3. 通用识别模型
在 PP-Shitu 中, 我们采用 [PP_LCNet_x2_5](../models/PP-LCNet.md) 作为骨干网络 Neck 部分选用 Linear Layer, Head 部分选用 [ArcMargin](../../../ppcls/arch/gears/arcmargin.py),Loss 部分选用 CELoss,详细的配置文件见[通用识别配置文件](../../../ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml)。其中,训练数据为如下 7 个公开数据集的汇总:
| 数据集 | 数据量 | 类别数 | 场景 | 数据集地址 |
| :------------: | :-------------: | :-------: | :-------: | :--------: |
| Aliproduct | 2498771 | 50030 | 商品 | [地址](https://retailvisionworkshop.github.io/recognition_challenge_2020/) |
......@@ -48,9 +49,11 @@
| **Total** | **5M** | **185K** | ---- | ---- |
最终的模型效果如下表所示:
| 模型 | Aliproduct | VeRI-Wild | LogoDet-3K | iCartoonFace | SOP | Inshop | Latency(ms) |
| :----------: | :---------: | :-------: | :-------: | :--------: | :--------: | :--------: | :--------: |
PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
* 采用的评测指标为:`Recall@1`
* 速度评测机器的 CPU 具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`
* 速度指标的评测条件为: 开启 MKLDNN, 线程数设置为 10
......@@ -58,13 +61,13 @@ PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
<a name="4"></a>
# 4. 自定义特征提取
## 4. 自定义特征提取
自定义特征提取,是指依据自己的任务,重新训练特征提取模型。主要包含四个步骤:1)数据准备;2)模型训练;3)模型评估;4)模型推理。
<a name="4.1"></a>
## 4.1 数据准备
### 4.1 数据准备
首先,需要基于任务定制自己的数据集。数据集格式参见[格式说明](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/data_preparation/recognition_dataset.md#%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E)。在启动模型训练之前,需要在配置文件中修改数据配置相关的内容, 主要包括数据集的地址以及类别数量。对应到配置文件中的位置如下所示:
```
......@@ -97,7 +100,7 @@ PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
<a name="4.2"></a>
## 4.2 模型训练
### 4.2 模型训练
- 单机单卡训练
```shell
......@@ -125,7 +128,7 @@ python -m paddle.distributed.launch \
<a name="4.3"></a>
## 4.3 模型评估
### 4.3 模型评估
- 单卡评估
```shell
......@@ -147,13 +150,13 @@ python -m paddle.distributed.launch \
<a name="4.4"></a>
## 4.4 模型推理
### 4.4 模型推理
推理过程包括两个步骤: 1)导出推理模型; 2)获取特征向量
<a name="4.4.1"></a>
### 4.4.1 导出推理模型
#### 4.4.1 导出推理模型
```
python tools/export_model \
......@@ -165,7 +168,7 @@ python tools/export_model \
<a name="4.4.2"></a>
### 4.4.2 获取特征向量
#### 4.4.2 获取特征向量
```
cd deploy
......
......@@ -27,13 +27,13 @@
在 PaddleClas 的识别任务中,训练主体检测模型时主要用到了以下几个数据集。
| 数据集 | 数据量 | 主体检测任务中使用的数据量 | 场景 | 数据集地址 |
| :------------: | :-------------: | :-------: | :-------: | :--------: |
| Objects365 | 170W | 6k | 通用场景 | [地址](https://www.objects365.org/overview.html) |
| COCO2017 | 12W | 5k | 通用场景 | [地址](https://cocodataset.org/) |
| iCartoonFace | 2k | 2k | 动漫人脸检测 | [地址](https://github.com/luxiangju-PersonAI/iCartoonFace) |
| LogoDet-3k | 3k | 2k | Logo 检测 | [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset) |
| RPC | 3k | 3k | 商品检测 | [地址](https://rpc-dataset.github.io/) |
| 数据集 | 数据量 | 主体检测任务中使用的数据量 | 场景 | 数据集地址 |
| ------------ | ------ | -------------------------- | ------------ | ---------------------------------------------------------- |
| Objects365 | 170W | 6k | 通用场景 | [地址](https://www.objects365.org/overview.html) |
| COCO2017 | 12W | 5k | 通用场景 | [地址](https://cocodataset.org/) |
| iCartoonFace | 2k | 2k | 动漫人脸检测 | [地址](https://github.com/luxiangju-PersonAI/iCartoonFace) |
| LogoDet-3k | 3k | 2k | Logo 检测 | [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset) |
| RPC | 3k | 3k | 商品检测 | [地址](https://rpc-dataset.github.io/) |
在实际训练的过程中,将所有数据集混合在一起。由于是主体检测,这里将所有标注出的检测框对应的类别都修改为 `前景` 的类别,最终融合的数据集中只包含 1 个类别,即前景。
......@@ -45,10 +45,10 @@
基于上述研究,PaddleClas 中提供了 2 个通用主体检测模型,为轻量级与服务端主体检测模型,分别适用于端侧场景以及服务端场景。下面的表格中给出了在上述 5 个数据集上的平均 mAP 以及它们的模型大小、预测速度对比信息。
| 模型 | 模型结构 | 预训练模型下载地址 | inference 模型下载地址 | mAP | inference 模型大小(MB) | 单张图片预测耗时(不包含预处理)(ms) |
| :------------: | :-------------: | :------: | :-------: | :--------: | :-------: | :--------: |
| 轻量级主体检测模型 | PicoDet | [地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_pretrained.pdparams) | [tar 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) [zip 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.zip) | 40.1% | 30.1 | 29.8 |
| 服务端主体检测模型 | PP-YOLOv2 | [地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/ppyolov2_r50vd_dcn_mainbody_v1.0_pretrained.pdparams) | [tar 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar) [zip 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.zip) | 42.5% | 210.5 | 466.6 |
| 模型 | 模型结构 | 预训练模型下载地址 | inference 模型下载地址 | mAP | inference 模型大小(MB) | 单张图片预测耗时(不包含预处理)(ms) |
| ------------------ | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ----- | ---------------------- | ---------------------------------- |
| 轻量级主体检测模型 | PicoDet | [地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_pretrained.pdparams) | [tar 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) [zip 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.zip) | 40.1% | 30.1 | 29.8 |
| 服务端主体检测模型 | PP-YOLOv2 | [地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/ppyolov2_r50vd_dcn_mainbody_v1.0_pretrained.pdparams) | [tar 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar) [zip 格式文件地址](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.zip) | 42.5% | 210.5 | 466.6 |
* 注意
* 由于部分解压缩软件在解压上述 `tar` 格式文件时存在问题,建议非命令行用户下载 `zip` 格式文件并解压。`tar` 格式文件建议使用命令 `tar xf xxx.tar` 解压。
......@@ -134,9 +134,7 @@ pip install -r requirements.txt
我们使用 `configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml` 配置进行训练,配置文件摘要如下:
<div align='center'>
<img src='../../images/det/PaddleDetection_config.png' width='400'/>
</div>
![](../../images/det/PaddleDetection_config.png)
从上图看到 `ppyolov2_r50vd_dcn_365e_coco.yml` 配置需要依赖其他的配置文件,这些配置文件的含义如下:
......
......@@ -9,9 +9,7 @@
值得注意的是,为了更好是适配性,目前版本,`PaddleClas` 中暂时**只使用 CPU 进行向量检索**
<div align="center">
<img src="../../images/structure.jpg" width = "800" />
</div>
![](../../images/structure.jpg)
如上图中所示,向量检索部分,在整个 `PP-ShiTu` 系统中有两部分内容
......
......@@ -4,15 +4,15 @@
.. toctree::
:maxdepth: 1
models_training/index
introduction/index
installation/index
quick_start/index
image_recognition_pipeline/index
others/index
faq_series/index
data_preparation/index
installation/index
models_training/index
inference_deployment/index
models/index
advanced_tutorials/index
algorithm_introduction/index
inference_deployment/index
quick_start/index
advanced_tutorials/index
others/index
faq_series/index
......@@ -293,8 +293,6 @@ sh tools/run.sh
* 最终屏幕上会输出结果,如下图所示。
<div align="center">
<img src="../../images/inference_deployment/cpp_infer_result.png" width="600">
</div>
![](../../images/inference_deployment/cpp_infer_result.png)
其中 `class id` 表示置信度最高的类别对应的 id,score 表示图片属于该类别的概率。
......@@ -270,9 +270,7 @@ export LD_LIBRARY_PATH=/data/local/tmp/debug:$LD_LIBRARY_PATH
运行效果如下:
<div align="center">
<img src="../../images/inference_deployment/lite_demo_result.png" width="600">
</div>
![](../../images/inference_deployment/lite_demo_result.png)
<a name="3"></a>
## 3. FAQ
......
# 模型服务化部署
# 模型服务化部署\
----
## 目录
- [1. 简介](#1)
- [2. Serving 安装](#2)
- [3. 图像分类服务部署](#3)
......
......@@ -40,9 +40,7 @@ pip3 install dist/*
## 2. 快速开始
* 使用 `ResNet50` 模型,以下图(`PaddleClas/docs/images/inference_deployment/whl_demo.jpg`)为例进行说明。
<div align="center">
<img src="../../images/inference_deployment/whl_demo.jpg" width = "400" />
</div>
![](../../images/inference_deployment/whl_demo.jpg)
* 在 Python 代码中使用
......
......@@ -15,8 +15,6 @@
- 数据增广:支持 AutoAugment 、 Cutout 、 Cutmix 等 8 种数据增广算法详细介绍、代码复现和在统一实验环境下的效果评估。
<div align="center">
<img src="../../images/recognition.gif" width = "400" />
</div>
![](../../images/recognition.gif)
更多关于图像识别快速体验、算法详解、模型训练评估与预测部署方法,请参考[首页 README 文档教程](../../../README_ch.md)
# 更多关于动漫人物图片识别的效果图请见下
## 动漫人物图片识别效果图
<div align="center"> <img src="https://user-images.githubusercontent.com/12560511/140069080-a821e0b7-8a10-4946-bf05-ff093cc16064.jpeg" width = "400" /> </div>
......
......@@ -9,4 +9,3 @@
more_demo.md
product.md
vehicle.md
# 更多关于商标图片识别的效果图请见下
## 商标图片识别效果图
<div align="center"> <img src="https://user-images.githubusercontent.com/12560511/140096687-5b562e2d-0653-4be6-861d-1936a4440df2.jpeg" width = "400" /> </div>
......
# 更多关于商品图片识别的效果图请见下
## 商品图片识别效果图
<div align="center"> <img src="https://user-images.githubusercontent.com/12560511/140277277-7b29f596-35f6-4f00-8d2b-0ef0be57a090.jpg" width = "400" /> </div>
......
# 更多关于车辆图片识别的效果图请见下
## 车辆图片识别效果图
<div align="center"> <img src="https://user-images.githubusercontent.com/12560511/140243899-c60f0a51-db9b-438a-9f2d-0d2893c200bb.jpeg" width = "400" /> </div>
......
......@@ -7,8 +7,10 @@ REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
......
......@@ -29,14 +29,13 @@
## 2. 介绍
近年来,有很多轻量级的骨干网络问世,尤其最近两年,各种 NAS 搜索出的网络层出不穷,这些网络要么主打 FLOPs 或者 Params 上的优势,要么主打 ARM 设备上的推理速度的优势,很少有网络专门针对 Intel CPU 做特定的优化,导致这些网络在 Intel CPU 端的推理速度并不是很完美。基于此,我们针对 Intel CPU 设备以及其加速库 MKLDNN 设计了特定的骨干网络 PP-LCNet,比起其他的轻量级的 SOTA 模型,该骨干网络可以在不增加推理时间的情况下,进一步提升模型的性能,最终大幅度超越现有的 SOTA 模型。与其他模型的对比图如下。
<div align=center><img src="../../images/PP-LCNet/PP-LCNet-Acc.png" width="500" height="400"/></div>
![](../../images/PP-LCNet/PP-LCNet-Acc.png)
<a name="3"></a>
## 3. 方法
网络结构整体如下图所示。
<div align=center><img src="../../images/PP-LCNet/PP-LCNet.png" width="700" height="400"/></div>
![](../../images/PP-LCNet/PP-LCNet.png)
我们经过大量的实验发现,在基于 Intel CPU 设备上,尤其当启用 MKLDNN 加速库后,很多看似不太耗时的操作反而会增加延时,比如 elementwise-add 操作、split-concat 结构等。所以最终我们选用了结构尽可能精简、速度尽可能快的 block 组成我们的 BaseNet(类似 MobileNetV1)。基于 BaseNet,我们通过实验,总结了四条几乎不增加延时但是可以提升模型精度的方法,融合这四条策略,我们组合成了 PP-LCNet。下面对这四条策略一一介绍:
<a name="3.1"></a>
......
......@@ -6,7 +6,7 @@
* [2. 精度、FLOPS 和参数量](#2)
<a name='1'></a>
## 概述
## 1. 概述
RepVGG(Making VGG-style ConvNets Great Again)系列模型是由清华大学(丁贵广团队)、旷视科技(孙剑等人)、港科大和阿伯里斯特威斯大学在 2021 年提出的一个简单但强大的卷积神经网络架构,该架构具有类似于 VGG 的推理时间主体,该主体仅由 3x3 卷积和 ReLU 的堆栈组成,而训练时间模型具有多分支拓扑。训练时间和推理时间架构的这种解耦是通过结构重新参数化(re-parameterization)技术实现的,因此该模型称为 RepVGG。[论文地址](https://arxiv.org/abs/2101.03697)
......
# 训练技巧
---
## 目录
* [1.优化器的选择](#1)
* [2.学习率以及学习率下降策略的选择](#2)
* [2.1 学习率的概念](#2.1)
* [2.2 学习率下降策略](#2.2)
* [2.3 warmup 策略](#2.3)
* [3.batch_size 的选择](#3)
* [4.weight_decay 的选择](#4)
* [5.label_smoothing 的选择](#5)
* [6.针对小模型更改图片的 crop 面积与拉伸变换程度](#6)
* [7.使用数据增广方式提升精度](#7)
* [8. 通过 train_acc 和 test_acc 确定调优策略](#8)
* [9.通过已有的预训练模型提升自己的数据集的精度](#9)
* [10. 参考文献](#10)
<a name='1'></a>
## 1.优化器的选择
自深度学习发展以来,就有很多关于优化器的研究者工作,优化器的目的是为了让损失函数尽可能的小,从而找到合适的参数来完成某项任务。目前业界主要用到的优化器 有 SGD、RMSProp、Adam、AdaDelt 等,其中由于带 momentum 的 SGD 优化器广泛应用于学术界和工业界,所以我们发布的模型也大都使用该优化器来实现损失函数的梯度下降。带 momentum 的 SGD 优化器有两个劣势,其一是收敛速度慢,其二是初始学习率的设置需要依靠大量的经验,然而如果初始学习率设置得当并且迭代轮数充足,该优化器也会在众多的优化器中脱颖而出,使得其在验证集上获得更高的准确率。一些自适应学习率的优化器如 Adam、RMSProp 等,收敛速度往往比较快,但是最终的收敛精度会稍差一些。如果追求更快的收敛速度,我们推荐使用这些自适应学习率的优化器,如果追求更高的收敛精度,我们推荐使用带 momentum 的 SGD 优化器。
<a name='2'></a>
## 2.学习率以及学习率下降策略的选择
学习率的选择往往和优化器以及数据和任务有关系。这里主要介绍以 momentum+SGD 作为优化器训练 ImageNet-1k 的学习率以及学习率下降的选择。
<a name='2.1'></a>
### 2.1 学习率的概念:
学习率是通过损失函数的梯度调整网络权重的超参数的速度。学习率越低,损失函数的变化速度就越慢。虽然使用低学习率可以确保不会错过任何局部极小值,但也意味着将花费更长的时间来进行收敛,特别是在被困在高原区域的情况下。
<a name='2.2'></a>
### 2.2 学习率下降策略:
在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是 piecewise_decay,即阶梯式下降学习率,如在 ResNet50 标准的训练中,我们设置的初始学习率是 0.1,每 30 epoch 学习率下降到原来的 1/10,一共迭代 120 epoch。除了 piecewise_decay,很多研究者也提出了学习率的其他下降方式,如 polynomial_decay(多项式下降)、exponential_decay(指数下降),cosine_decay(余弦下降)等,其中 cosine_decay 无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay 和 piecewise_decay 的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay 都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较 peicewise_decay 更好一些。
![](../../images/models/lr_decay.jpeg)
另外,从图中我们也可以看到,cosine_decay 里学习率小的轮数较少,这样会影响到最终的精度,所以为了使得 cosine_decay 发挥更好的效果,建议迭代更多的轮数,如 200 轮。
<a name='2.3'></a>
### 2.3 warmup 策略
如果使用较大的 batch_size 训练神经网络时,我们建议您使用 warmup 策略。Warmup 策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。实验表明,在 batch_size 较大时,warmup 可以稳定提升模型的精度。在训练 MobileNetV3 等 batch_size 较大的实验中,我们默认将 warmup 中的 epoch 设置为 5,即先用 5 epoch 将学习率从 0 增加到最大值,再去做相应的学习率衰减。
<a name='3'></a>
## 3.batch_size 的选择
batch_size 是训练神经网络中的一个重要的超参数,该值决定了一次将多少数据送入神经网络参与训练。在论文[1]中,作者通过实验发现,当 batch_size 的值与学习率的值呈线性关系时,收敛精度几乎不受影响。在训练 ImageNet 数据时,大部分的神经网络选择的初始学习率为 0.1,batch_size 是 256,所以根据实际的模型大小和显存情况,可以将学习率设置为 0.1\*k,batch_size 设置为 256\*k。
<a name='4'></a>
## 4.weight_decay 的选择
过拟合是机器学习中常见的一个名词,简单理解即为模型在训练数据上表现很好,但在测试数据上表现较差,在卷积神经网络中,同样存在过拟合的问题,为了避免过拟合,很多正则方式被提出,其中,weight_decay 是其中一个广泛使用的避免过拟合的方式。Weight_decay 等价于在最终的损失函数后添加 L2 正则化,L2 正则化使得网络的权重倾向于选择更小的值,最终整个网络中的参数值更趋向于 0,模型的泛化性能相应提高。在各大深度学习框架的实现中,该值表达的含义是 L2 正则前的系数,在 paddle 框架中,该值的名称是 l2_decay,所以以下都称其为 l2_decay。该系数越大,表示加入的正则越强,模型越趋于欠拟合状态。在训练 ImageNet 的任务中,大多数的网络将该参数值设置为 1e-4,在一些小的网络如 MobileNet 系列网络中,为了避免网络欠拟合,该值设置为 1e-5~4e-5 之间。当然,该值的设置也和具体的数据集有关系,当任务的数据集较大时,网络本身趋向于欠拟合状态,可以将该值适当减小,当任务的数据集较小时,网络本身趋向于过拟合状态,可以将该值适当增大。下表展示了 MobileNetV1_x0_25 在 ImageNet-1k 上使用不同 l2_decay 的精度情况。由于 MobileNetV1_x0_25 是一个比较小的网络,所以 l2_decay 过大会使网络趋向于欠拟合状态,所以在该网络中,相对 1e-4,3e-5 是更好的选择。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV1_x0_25 | 1e-4 | 43.79%/67.61% | 50.41%/74.70% |
| MobileNetV1_x0_25 | 3e-5 | 47.38%/70.83% | 51.45%/75.45% |
另外,该值的设置也和训练过程中是否使用其他正则化有关系。如果训练过程中的数据预处理比较复杂,相当于训练任务变的更难,可以将该值适当减小,下表展示了在 ImageNet-1k 上,ResNet50 在使用 randaugment 预处理方式后使用不同 l2_decay 的精度。容易观察到,在任务变难后,使用更小的 l2_decay 有助于模型精度的提升。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet50 | 1e-4 | 75.13%/90.42% | 77.65%/93.79% |
| ResNet50 | 7e-5 | 75.56%/90.55% | 78.04%/93.74% |
综上所述,l2_decay 可以根据具体的任务和模型去做相应的调整,通常简单的任务或者较大的模型,推荐使用较大的 l2_decay,复杂的任务或者较小的模型,推荐使用较小的 l2_decay。
<a name='5'></a>
## 5.label_smoothing 的选择
Label_smoothing 是深度学习中的一种正则化方法,其全称是 Label Smoothing Regularization(LSR),即标签平滑正则化。在传统的分类任务计算损失函数时,是将真实的 one hot 标签与神经网络的输出做相应的交叉熵计算,而 label_smoothing 是将真实的 one hot 标签做一个标签平滑的处理,使得网络学习的标签不再是一个 hard label,而是一个有概率值的 soft label,其中在类别对应的位置的概率最大,其他位置概率是一个非常小的数。具体的计算方式参见论文[2]。在 label_smoothing 里,有一个 epsilon 的参数值,该值描述了将标签软化的程度,该值越大,经过 label smoothing 后的标签向量的标签概率值越小,标签越平滑,反之,标签越趋向于 hard label,在训练 ImageNet-1k 的实验里通常将该值设置为 0.1。
在训练 ImageNet-1k 的实验中,我们发现,ResNet50 大小级别及其以上的模型在使用 label_smooting 后,精度有稳定的提升。下表展示了 ResNet50_vd 在使用 label_smoothing 前后的精度指标。
| 模型 | Use_label_smoothing | Test acc1 |
|:--:|:--:|:--:|
| ResNet50_vd | 0 | 77.9% |
| ResNet50_vd | 1 | 78.4% |
同时,由于 label_smoohing 相当于一种正则方式,在相对较小的模型上,精度提升不明显甚至会有所下降,下表展示了 ResNet18 在 ImageNet-1k 上使用 label_smoothing 前后的精度指标。可以明显看到,在使用 label_smoothing 后,精度有所下降。
| 模型 | Use_label_smoohing | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet18 | 0 | 69.81%/87.70% | 70.98%/89.92% |
| ResNet18 | 1 | 68.00%/86.56% | 70.81%/89.89% |
综上所述,较大的模型使用 label_smoohing 可以有效提升模型的精度,较小的模型使用 label_smoohing 可能会降低模型的精度,所以在决定是否使用 label_smoohing 前,需要评估模型的大小和任务的难易程度。
<a name='6'></a>
## 6.针对小模型更改图片的 crop 面积与拉伸变换程度
在 ImageNet-1k 数据的标准预处理中,random_crop 函数中定义了 scale 和 ratio 两个值,两个值分别确定了图片 crop 的大小和图片的拉伸程度,其中 scale 的默认取值范围是 0.08-1(lower_scale-upper_scale),ratio 的默认取值范围是 3/4-4/3(lower_ratio-upper_ratio)。在非常小的网络训练中,此类数据增强会使得网络欠拟合,导致精度有所下降。为了提升网络的精度,可以使其数据增强变的更弱,即增大图片的 crop 区域或者减弱图片的拉伸变换程度。我们可以分别通过增大 lower_scale 的值或缩小 lower_ratio 与 upper_scale 的差距来实现更弱的图片变换。下表列出了使用不同 lower_scale 训练 MobileNetV2_x0_25 的精度,可以看到,增大图片的 crop 区域面积后训练精度和验证精度均有提升。
| 模型 | Scale 取值范围 | Train_acc1/acc5 | Test_acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV2_x0_25 | [0.08,1] | 50.36%/72.98% | 52.35%/75.65% |
| MobileNetV2_x0_25 | [0.2,1] | 54.39%/77.08% | 53.18%/76.14% |
<a name='7'></a>
## 7.使用数据增广方式提升精度
一般来说,数据集的规模对性能影响至关重要,但是图片的标注往往比较昂贵,所以有标注的图片数量往往比较稀少,在这种情况下,数据的增广尤为重要。在训练 ImageNet-1k 的标准数据增广中,主要使用了 random_crop 与 random_flip 两种数据增广方式,然而,近些年,越来越多的数据增广方式被提出,如 cutout、mixup、cutmix、AutoAugment 等。实验表明,这些数据的增广方式可以有效提升模型的精度,下表列出了 ResNet50 在 8 种不同的数据增广方式的表现,可以看出,相比 baseline,所有的数据增广方式均有收益,其中 cutmix 是目前最有效的数据增广。更多数据增广的介绍请参考[**数据增广章节**](https://paddleclas.readthedocs.io/zh_CN/latest/advanced_tutorials/image_augmentation/ImageAugment.html)
| 模型 | 数据增广方式 | Test top-1 |
|:--:|:--:|:--:|
| ResNet50 | 标准变换 | 77.31% |
| ResNet50 | Auto-Augment | 77.95% |
| ResNet50 | Mixup | 78.28% |
| ResNet50 | Cutmix | 78.39% |
| ResNet50 | Cutout | 78.01% |
| ResNet50 | Gridmask | 77.85% |
| ResNet50 | Random-Augment | 77.70% |
| ResNet50 | Random-Erasing | 77.91% |
| ResNet50 | Hide-and-Seek | 77.43% |
<a name='8'></a>
## 8. 通过 train_acc 和 test_acc 确定调优策略
在训练网络的过程中,通常会打印每一个 epoch 的训练集准确率和验证集准确率,二者刻画了该模型在两个数据集上的表现。通常来说,训练集的准确率比验证集准确率微高或者二者相当是比较不错的状态。如果发现训练集的准确率比验证集高很多,说明在这个任务上已经过拟合,需要在训练过程中加入更多的正则,如增大 l2_decay 的值,加入更多的数据增广策略,加入 label_smoothing 策略等;如果发现训练集的准确率比验证集低一些,说明在这个任务上可能欠拟合,需要在训练过程中减弱正则效果,如减小 l2_decay 的值,减少数据增广方式,增大图片 crop 区域面积,减弱图片拉伸变换,去除 label_smoothing 等。
<a name='9'></a>
## 9.通过已有的预训练模型提升自己的数据集的精度
在现阶段计算机视觉领域中,加载预训练模型来训练自己的任务已成为普遍的做法,相比从随机初始化开始训练,加载预训练模型往往可以提升特定任务的精度。一般来说,业界广泛使用的预训练模型是通过训练 128 万张图片 1000 类的 ImageNet-1k 数据集得到的,该预训练模型的 fc 层权重是是一个 k\*1000 的矩阵,其中 k 是 fc 层以前的神经元数,在加载预训练权重时,无需加载 fc 层的权重。在学习率方面,如果您的任务训练的数据集特别小(如小于 1 千张),我们建议你使用较小的初始学习率,如 0.001(batch_size:256,下同),以免较大的学习率破坏预训练权重。如果您的训练数据集规模相对较大(大于 10 万),我们建议你尝试更大的初始学习率,如 0.01 或者更大。
> 如果您觉得此文档对您有帮助,欢迎 star 我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
<a name='10'></a>
## 10. 参考文献
[1]P. Goyal, P. Dolla ́r, R. B. Girshick, P. Noordhuis, L. Wesolowski, A. Kyrola, A. Tulloch, Y. Jia, and K. He. Accurate, large minibatch SGD: training imagenet in 1 hour. CoRR, abs/1706.02677, 2017.
[2]C.Szegedy,V.Vanhoucke,S.Ioffe,J.Shlens,andZ.Wojna. Rethinking the inception architecture for computer vision. CoRR, abs/1512.00567, 2015.
......@@ -10,7 +10,6 @@
EfficientNet_and_ResNeXt101_wsl.md
ViT_and_DeiT.md
SwinTransformer.md
Tricks.md
Others.md
SEResNext_and_Res2Net.md
ESNet.md
......
......@@ -20,17 +20,9 @@
* Intel CPU 的评估环境基于 Intel(R) Xeon(R) Gold 6148。
* GPU 评估环境基于 V100 和 TensorRT。
<div align="center">
<img src="../../images/models/V100_benchmark/v100.fp32.bs1.main_fps_top1_s.png" width="800">
</div>
![](../../images/models/V100_benchmark/v100.fp32.bs1.main_fps_top1_s.png)
<div align="center">
<img src="../../images/models/mobile_arm_top1.png" width="800">
</div>
<div align="center">
<img src="../../images/models/V100_benchmark/v100.fp32.bs1.visiontransformer.png" width="800">
</div>
![](../../images/models/V100_benchmark/v100.fp32.bs1.visiontransformer.png)
> 如果您觉得此文档对您有帮助,欢迎 star 我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
......
......@@ -5,6 +5,6 @@
:maxdepth: 2
config_description.md
train_strategy.md
classification.md
recognition.md
train_strategy.md
......@@ -10,9 +10,7 @@
其中特征库,需要利用已经标注好的图像数据集提前建立。完整的图像识别系统,如下图所示
<div align="center">
<img src="../../images/structure.jpg" width = "600" />
</div>
![](../../images/structure.jpg)
体验整体图像识别系统,或查看特征库建立方法,详见[图像识别快速开始文档](../quick_start/quick_start_recognition.md)。其中,图像识别快速开始文档主要讲解整体流程的使用过程。以下内容,主要对上述三个步骤的训练部分进行介绍。
首先,请参考[安装指南](../installation/install_paddleclas.md)配置运行环境。
......
......@@ -51,6 +51,4 @@ python3 tools/train.py -c config.yaml
在启动 VisualDL 后,即可在浏览器中查看训练过程,输入地址 `127.0.0.1:8840`
<div align="center">
<img src="../../images/VisualDL/train_loss.png" width="400">
</div>
![](../../images/VisualDL/train_loss.png)
......@@ -3,8 +3,22 @@
此教程主要针对初级用户,即深度学习相关理论知识处于入门阶段,具有一定的 Python 基础,能够阅读简单代码的用户。此内容主要包括使用 PaddleClas 进行图像分类网络训练及模型预测。
---
## 1. 基础知识
## 目录
* [1. 基础知识](#1)
* [2. 环境安装与配置](#2)
* [3. 数据的准备与处理](#3)
* [4. 模型训练](#4)
* [4.1 使用CPU进行模型训练](#4.1)
* [4.1.1 不使用预训练模型](#4.1.1)
* [4.1.2 使用预训练模型](#4.1.2)
* [4.2 使用GPU进行模型训练](#4.2)
* [4.2.1 不使用预训练模型](#4.2.1)
* [4.2.2 使用预训练模型进行训练](#4.2.2)
* [5. 模型预测](#5)
<a name='1'></a>
## 1. 基础知识
图像分类顾名思义就是一个模式分类问题,是计算机视觉中最基础的任务,它的目标是将不同的图像,划分到不同的类别。以下会对整个模型训练过程中需要了解到的一些概念做简单的解释,希望能够对初次体验 PaddleClas 的你有所帮助:
......@@ -30,11 +44,15 @@
- Top1 Acc:预测结果中概率最大的所在分类正确,则判定为正确;
- Top5 Acc:预测结果中概率排名前 5 中有分类正确,则判定为正确;
## 2. 环境安装与配置
<a name='2'></a>
## 2. 环境安装与配置
具体安装步骤可详看[Paddle 安装文档](../installation/install_paddle.md)[PaddleClas 安装文档](../installation/install_paddleclas.md)
## 3. 数据的准备与处理
<a name='3'></a>
## 3. 数据的准备与处理
进入PaddleClas目录:
......@@ -60,9 +78,7 @@ unzip flowers102.zip
flowers102数据集的图像文件存放在 `dataset/flowers102/jpg` 目录中,图像示例如下:
<div align="center">
<img src="../../images/quick_start/Examples-Flower-102.png" width = "800" />
</div>
![](../../images/quick_start/Examples-Flower-102.png)
返回 `PaddleClas` 根目录:
......@@ -71,16 +87,19 @@ flowers102数据集的图像文件存放在 `dataset/flowers102/jpg` 目录中
cd ../../
# windoes直接打开PaddleClas根目录即可
```
<a name='4'></a>
## 4. 模型训练
## 4. 模型训练
<a name="4.1"></a>
### 4.1 使用CPU进行模型训练
### 4.1 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
#### 4.1.1 不使用预训练模型
<a name='4.1.1'></a>
#### 4.1.1 不使用预训练模型
```shell
# windows在cmd中进入PaddleClas根目录,执行此命令
......@@ -91,7 +110,9 @@ python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25
- `yaml``Global.device` 参数设置为`cpu`,即使用CPU进行训练(若不设置,此参数默认为`True`
- `yaml`文件中`epochs`参数设置为20,说明对整个数据集进行20个epoch迭代,预计训练20分钟左右(不同CPU,训练时间略有不同),此时训练模型不充分。若提高训练模型精度,请将此参数设大,如**40**,训练时间也会相应延长
#### 4.1.2 使用预训练模型
<a name='4.1.2'></a>
#### 4.1.2 使用预训练模型
```shell
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Arch.pretrained=True
......@@ -101,7 +122,9 @@ python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25
可以使用将使用与不使用预训练模型训练进行对比,观察 loss 的下降情况。
### 4.2 使用GPU进行模型训练
<a name='4.2'></a>
### 4.2 使用GPU进行模型训练
由于 GPU 训练速度更快,可以使用更复杂模型,因此以 ResNet50_vd 为例。与 ShuffleNetV2_x0_25 相比,此模型计算量较大,训练好的模型精度也会更高。
......@@ -118,8 +141,9 @@ python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25
```shell
set CUDA_VISIBLE_DEVICES=0
```
<a name='4.2.1'></a>
#### 不使用预训练模型
#### 4.2.1. 不使用预训练模型
```shell
python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
......@@ -127,11 +151,11 @@ python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
训练完成后,验证集的`Top1 Acc`曲线如下所示,最高准确率为0.2735。训练精度曲线下图所示
<div align="center">
<img src="../../images/quick_start/r50_vd_acc.png" width = "800" />
</div>
![](../../images/quick_start/r50_vd_acc.png)
#### 4.2.1 使用预训练模型进行训练
<a name='4.2.2'></a>
#### 4.2.2 使用预训练模型进行训练
基于 ImageNet1k 分类预训练模型进行微调,训练脚本如下所示
......@@ -143,11 +167,11 @@ python tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pr
验证集的 `Top1 Acc` 曲线如下所示,最高准确率为 `0.9402`,加载预训练模型之后,flowers102 数据集精度大幅提升,绝对精度涨幅超过 65%。
<div align="center">
<img src="../../images/quick_start/r50_vd_pretrained_acc.png" width = "800" />
</div>
![](../../images/quick_start/r50_vd_pretrained_acc.png)
<a name='5'></a>
## 5. 模型预测
## 5. 模型预测
训练完成后,可以使用训练好的模型进行预测,以训练的 ResNet50_vd 模型为例,预测代码如下:
......
......@@ -162,9 +162,7 @@ python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.u
待检索图像如下所示。
<div align="center">
<img src="../../images/recognition/drink_data_demo/test_images/nongfu_spring.jpeg" width = "400" />
</div>
![](../../images/recognition/drink_data_demo/test_images/nongfu_spring.jpeg)
最终输出结果如下。
......@@ -177,9 +175,7 @@ python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.u
检测的可视化结果也保存在 `output` 文件夹下,对于本张图像,识别结果可视化如下所示。
<div align="center">
<img src="../../images/recognition/drink_data_demo/output/nongfu_spring.jpeg" width = "400" />
</div>
![](../../images/recognition/drink_data_demo/output/nongfu_spring.jpeg)
<a name="基于文件夹的批量识别"></a>
......@@ -228,9 +224,7 @@ python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.i
待检索图像如下所示。
<div align="center">
<img src="../../images/recognition/drink_data_demo/test_images/mosilian.jpeg" width = "400" />
</div>
![](../../images/recognition/drink_data_demo/test_images/mosilian.jpeg)
输出结果为空。
......@@ -281,9 +275,7 @@ python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.i
最终识别结果为`光明_莫斯利安`,识别正确,识别结果可视化如下所示。
<div align="center">
<img src="../../images/recognition/drink_data_demo/output/mosilian.jpeg" width = "400" />
</div>
![](../../images/recognition/drink_data_demo/output/mosilian.jpeg)
<a name="4"></a>
......
......@@ -8,7 +8,6 @@ def file_name(file_dir):
break
# 删除不需要的子目录
temp.remove('images')
temp.remove('_templates')
temp.remove('_build')
temp.remove('_static')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册