PaddleClas/docs/zh_CN/faq_series/faq_2020_s1.md

195 lines
18 KiB
Markdown
Raw Normal View History

2020-11-04 11:37:19 +08:00
# 图像分类常见问题汇总 - 2020 第1季
## 目录
* [第1期](#第1期)(2020.11.03)
* [第2期](#第2期)(2020.11.11)
2020-11-19 12:37:24 +08:00
* [第3期](#第3期)(2020.11.18)
* [第4期](#第4期)(2020.12.07)
2020-11-04 11:37:19 +08:00
<a name="第1期"></a>
2020-11-04 11:37:19 +08:00
## 第1期
### Q1.1: PaddleClas可以用来做什么?
**A**PaddleClas是飞桨为工业界和学术界所准备的一个图像分类任务的工具集助力使用者训练出更好的视觉模型和应用落地。PaddleClas提供了基于图像分类的模型训练、评估、预测、部署全流程的服务方便大家更加高效地学习图像分类。具体地PaddleClas中包含如下一些特性 。
* PaddleClas提供了24个系列的分类网络结构(ResNet, ResNet_vd, MobileNetV3, Res2Net, HRNet等)和训练配置122个预训练模型和性能评估与预测供大家选择并使用。
* PaddleClas提供了TensorRT预测、python inference、c++ inference、Paddle-Lite预测部署等多种预测部署推理方案在方便在多种环境中进行部署推理。
* PaddleClas提供了一种简单的SSLD知识蒸馏方案基于该方案蒸馏模型的识别准确率普遍提升3%以上。
* PaddleClas支持AutoAugment、Cutout、Cutmix等8种数据增广算法详细介绍、代码复现和在统一实验环境下的效果评估。
* PaddleClas支持在Windows/Linux/MacOS环境中基于CPU/GPU进行使用。
### Q1.2: ResNet系列模型是什么有哪些模型为什么在服务器端如此推荐ResNet系列模型
**A**: ResNet中创新性地引入了残差结构通过堆叠多个残差结构从而构建了ResNet网络。实验表明使用残差块可以有效地提升收敛速度和精度PaddleClas中ResNet从小到达依次有包含18、34、50、101、152、200层的ResNet结构ResNet系列模型于2015年被提出在不同的应用场景中如分类、检测、分割等都已经验证过其有效性业界也早已对其进行了大量优化该系列模型在速度和精度方面都有着非常明显的优势对基于TensorRT以及FP16的预测支持得也很好因而推荐大家使用ResNet系列模型由于其模型所占存储相对较大因此常用于服务器端。更多关于ResNet模型的介绍可以参考论文[Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)。
### Q1.3: ResNet_vd和ResNet、ResNet_vc结构有什么区别呢
**A**:
ResNet_va至vd的结构如下图所示ResNet最早提出时为va结构在降采样残差模块这个部分在左边的特征变换通路中(Path A)第一个1x1卷积部分就行了降采样从而导致信息丢失卷积的kernel size为1stride为2输入特征图中 有部分特征没有参与卷积的计算在vb结构中把降采样的步骤从最开始的第一个1x1卷积调整到中间的3x3卷积中从而避免了信息丢失的问题PaddleClas中的ResNet模型默认就是ResNet_vbvc结构则是将最开始这个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>
### Q1.4 如果确定使用ResNet系列模型怎么根据实际的场景需求选用不同的模型呢
**A**:
ResNet系列模型中相比于其他模型ResNet_vd模型在预测速度几乎不变的情况下精度有非常明显的提升因此推荐大家使用ResNet_vd系列模型。
下面给出了batch size=4的情况下在T4 GPU上不同模型的的预测耗时、flops、params与精度的变化曲线可以根据自己自己的实际部署场景中的需求去选择合适的模型如果希望模型存储大小尽可能小或者预测速度尽可能快则可以使用ResNet18_vd模型如果希望获得尽可能高的精度则建议使用ResNet152_vd或者ResNet200_vd模型。更多关于ResNet系列模型的介绍可以参考文档[ResNet及其vd系列模型文档](../models/ResNet_and_vd.md)。
* 精度-预测速度变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.png" width="800">
</div>
* 精度-params变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.params.png" width="800">
</div>
* 精度-flops变化曲线
<div align="center">
<img src="../../images/models/T4_benchmark/t4.fp32.bs4.ResNet.flops.png" width="800">
</div>
### 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的形式。
### Q1.6 ResNet34与ResNet50的区别
**A**: ResNet系列中有两种不同的block分别是basic-block和bottleneck-block堆叠较多这样的block组成了ResNet网络。basic-block是带有shortcut的两个3x3的卷积核的堆叠bottleneck-block是带有shortcut的1x1卷积核、3x3卷积核、1x1卷积核的堆叠所以basic-block中有两层bottleneck-block有三层。ResNet34和ResNet50中堆叠的block数相同但是堆叠的种类分别是basic-block和bottleneck-block。
### Q1.7 大卷积核一定可以带来正向收益吗?
**A**: 不一定,将网络中的所有卷积核都增大未必会带来性能的提升,甚至会有有损性能,在论文[MixConv: Mixed Depthwise Convolutional Kernels](https://arxiv.org/abs/1907.09595)
中指出,在一定范围内提升卷积核大小对精度的提升有正向作用,但是超出后会有损精度。所以考虑到模型的大小、计算量等问题,一般不选用大的卷积核去设计网络。
<a name="第2期"></a>
## 第2期
### Q2.1: PaddleClas如何训练自己的backbone
**A**:具体流程如下:
* 首先在ppcls/modeling/architectures/文件夹下新建一个自己的模型结构文件即你自己的backbone模型搭建可以参考resnet.py;
* 然后在ppcls/modeling/\_\_init\_\_.py中添加自己设计的backbone的类;
* 其次配置训练的yaml文件此处可以参考configs/ResNet/ResNet50.yaml;
* 最后启动训练即可。
### Q2.2: 如何利用已有的模型和权重对自己的分类任务进行迁移?
**A**: 具体流程如下:
* 首先好的预训练模型往往会有更好的迁移效果所以建议选用精度较高的预训练模型PaddleClas提供了一系列业界领先的预训练模型建议使用
* 其次要根据迁移的数据集的规模来确定训练超参数一般超参数需要调试才可以寻找到一个局部最优值如果没有相关经验建议先从learning rate开始调起一般来说规模较小的数据集使用较小的learning rate如0.001另外建议学习率使用warmup策略避免过大的学习率破坏预训练模型的权重。在迁移过程中也可以设置backbone中不同层的学习率往往从网络的头部到尾补学习率逐渐减小效果较好。在数据集规模较小的时候也可以使用数据增强策略PaddleClas提供了8中强有力的数据增强策略为更高的精度保驾护航。
* 训练结束后,可以反复迭代上述过程,直到寻找到局部最优值。
### Q2.3: PaddleClas中configs下的默认参数适合任何一个数据集吗
**A**: PaddleClas中的configs下的默认参数是ImageNet-1k的训练参数这个参数并不适合所有的数据集具体数据集需要在此基础上进一步调试调试方法会在之后出一个单独的faq敬请期待。
### Q2.4 PaddleClas中的不同的模型使用了不同的分辨率标配的应该是多少呢
**A**: PaddleClas严格遵循了论文作者的使用的分辨率。自2012年AlexNet以来大多数的卷积神经网络在ImageNet上训练的分辨率为224x224Google在设计InceptionV3的时候为了适应网络结构将分辨率调至299x299之后其推出的Xception、InceptionV4也是使用的该分辨率。此外在EfficeintNet中作者分析了不同规模的网络应该使用不同的分辨率所以该系列网络中每个不同大小的网络都使用了不同的分辨率。在实际使用场景中推荐使用默认的分辨率当然层数较深或者宽度较大的网络也可以尝试使用更大的分辨率。
### Q2.5 PaddleClas中提供了很多ssld模型其应用的价值是
**A**: PaddleClas中提供了很多ssld预训练模型其通过半监督知识蒸馏的方法获得了更好的预训练权重在迁移任务或者下游视觉任务中无须替换结构文件、只需要替换精度更高的ssld预训练模型即可提升精度如在PaddleSeg中[HRNet](https://github.com/PaddlePaddle/PaddleSeg/blob/release/v0.7.0/docs/model_zoo.md)使用了ssld预训练模型的权重后精度大幅度超越业界同样的模型的精度在PaddleDetection中[PP-YOLO](https://github.com/PaddlePaddle/PaddleDetection/blob/release/0.4/configs/ppyolo/README_cn.md)使用了ssld预训练权重后在较高的baseline上仍有进一步的提升。使用ssld预训练权重做分类的迁移表现也很抢眼在[SSLD蒸馏策略](https://github.com/PaddlePaddle/PaddleClas/blob/master/docs/zh_CN/advanced_tutorials/distillation/distillation.md)部分介绍了知识蒸馏对于分类任务迁移的收益。
2020-11-19 12:37:24 +08:00
<a name="第3期"></a>
## 第3期
### Q3.1: DenseNet模型相比于ResNet有什么改进呢有哪些特点或者应用场景呢
**A**: DenseNet相比于ResNet设计了一个更激进的密集连接机制通过考虑特征重用和旁路的设置进一步减少了参数量而且从一定程度上缓解了梯度弥散的问题因为引入了更加密集的连接因此模型更容易训练而且具有一定的正则化效果。在数据量不是很多的图像分类场景中DenseNet是一个不错的选择。更多关于DenseNet的介绍与系列模型可以参考[DenseNet模型文档](../models/DPN_DenseNet.md)。
### Q3.2: DPN网络相比于DenseNet有哪些改进呢
**A**DPN的全称是Dual Path Networks即双通道网络。该网络是由DenseNet和ResNeXt结合的一个网络其证明了DenseNet能从靠前的层级中提取到新的特征而ResNeXt本质上是对之前层级中已提取特征的复用。作者进一步分析发现ResNeXt对特征有高复用率但冗余度低DenseNet能创造新特征但冗余度高。结合二者结构的优势作者设计了DPN网络。最终DPN网络在同样FLOPS和参数量下取得了比ResNeXt与DenseNet更好的结果。更多关于DPN的介绍与系列模型可以参考[DPN模型文档](../models/DPN_DenseNet.md)。
### Q3.3: 怎么使用多个模型进行预测融合呢?
**A** 使用多个模型进行预测的时候建议首先将预训练模型导出为inference模型这样可以摆脱对网络结构定义的依赖可以参考[模型导出脚本](../../../tools/export_model.py)进行模型导出,之后再参考[inference模型预测脚本](../../../tools/infer/predict.py)进行预测即可在这里需要根据自己使用模型的数量创建多个predictor。
### Q3.4: PaddleClas中怎么增加自己的数据增广方法呢
**A**
* 对于单张图像的增广,可以参考[基于单张图片的数据增广脚本](../../../ppcls/data/imaug/operators.py),参考`ResizeImage`或者`CropImage`等数据算子的写法,创建一个新的类,然后在`__call__`中,实现对应的增广方法即可。
* 对于一个batch图像的增广可以参考[基于batch数据的数据增广脚本](../../../ppcls/data/imaug/batch_operators.py),参考`MixupOperator`或者`CutmixOperator`等数据算子的写法,创建一个新的类,然后在`__call__`中,实现对应的增广方法即可。
## Q3.5: 怎么进一步加速模型训练过程呢?
**A**
* 可以使用自动混合精度进行训练这在精度几乎无损的情况下可以有比较明显的速度收益以ResNet50为例PaddleClas中使用自动混合精度训练的配置文件可以参考[ResNet50_fp16.yml](../../../configs/ResNet/ResNet50_fp16.yml),主要就是需要在标准的配置文件中添加以下几行
```
use_fp16: True
amp_scale_loss: 128.0
use_dynamic_loss_scaling: True
```
* 可以开启dali将数据预处理方法放在GPU上运行在模型比较小时reader耗时占比更高一些开启dali会带来比较明显的精度收益在训练的时候添加`-o use_dali=True`即可使用dali进行训练更多关于dali 安装与介绍可以参考:[dali安装教程](https://docs.nvidia.com/deeplearning/dali/user-guide/docs/installation.html#nightly-builds)。
<a name="第4期"></a>
## 第4期
### Q4.1: PaddlePaddle 的模型文件都有哪几种?
**A**:
* PaddlePaddle保存的模型相关文件有两类
* 一类是用于*推理部署*的文件,包括后缀名为“`pdiparams`”、“`model`”的文件,其中“`pdiparams`”文件存储了模型参数信息,“`model`”文件存储了模型网络结构信息,对于推理部署文件,使用`paddle.jit.save`与`paddle.jit.load`接口进行保存、加载。
* 另一类模型相关文件则是用于*训练调优*过程中,包括后缀名为“`pdparams`”和“`pdopt`”的文件,其中“`pdparams`”文件存储了训练过程中的模型参数信息,“`pdopt`”文件存储了模型训练过程中的优化器信息,对于训练调优文件,使用`paddle.save`与`paddle.load`接口进行保存、加载。
* 利用推理部署文件,即可构建模型网络结构并加载模型参数,用于预测,利用训练调优文件,即可加载模型参数、优化器信息,用于恢复训练过程。
### Q4.2: HRNet的创新点体现在哪里
**A**:
* 在图像分类领域,大部分神经网络的设计思想是提取图像的高维特征,具体来说,通常输入图像的空间分辨率较高,通过多层卷积、池化,可以逐步得到空间分辨率更低,但是维度更高的特征图,然后可用于分类等场景。
* 然而*HRNet*的作者认为这种逐步降低空间分辨率的设计思想并不适合目标检测(图像区域层次的分类任务)、语义分割(图像像素层次的分类任务)等场景,因为空间分辨率在逐步降低的过程中,会丢失很多信息,最终学习得到的特征难以表达原始图像在高空间分辨率的信息,而区域层次分类任务和像素层次分类任务都对空间精度十分敏感。
* 因此*HRNet*的作者提出了并联不同空间分辨率特征图的思想,与此相对,*VGG*等神经网络则是通过不同的卷积池化层来串联不同空间分辨率的特征图。并且,*HRNet*通过连接同等深度、不同空间分辨率的特征图,使得不同空间分辨率特征图的信息可以得到充分交换,具体的网络结构如下图所示。
<div align="center">
<img src="../../images/faq/HRNet.png" width="800">
</div>
### Q4.3: 在HRNet中对于不同空间分辨率的特征图之间是如何建立连接的
**A**:
* 首先,在*HRNet*中,对特征图使用*stride*为*2*的*3 × 3*卷积,可以得到低空间分辨率但是为度更高的特征图;而对低空间分辨率特征图先使用*1 × 1*卷积进行通道数匹配,再使用最近邻插值的方式进行上采样,即可得到与高空间分辨率特征图相同空间分辨率、通道数的特征图;而对于相同空间分辨率的特征图,直接进行恒等映射即可。具体如下图所示。
<div align="center">
<img src="../../images/faq/HRNet_block.png" width="800">
</div>
### Q4.4: 模型中的“SE”表示什么意思
**A**:
* SE表示该模型使用了SE结构。SE结构来自于2017年ImageNet分类比赛的冠军方案*Squeeze-and-Excitation NetworksSENet**SENet*提出的SE结构可以迁移到任何其他网络中。其创新点是通过额外学习*scale*向量作为权重作用到特征图上,*scale*向量维度与特征图通道数相同,学习到的*scale*向量中每个维度上的数值表示对该维度特征通道的增强或减弱的大小,以此达到对重要的特征通道进行增强,不重要特征通道减弱的效果,从而让提取的特征指向性更强。
### Q4.5: SE结构具体如何实现的
<div align="center">
<img src="../../images/faq/SE_structure.png" width="800">
</div>
**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*操作。
* *Fex*操作表示两次全连接,作者将该操作称为*Excitation*。其中第一次全连接将向量的维度从*1 × 1 × C*压缩到*1 × 1 × C/r*,然后使用*RELU*,再通过第二次全连接将向量的维度恢复到*C*,这样操作的目的是为了减小计算量,*SENet*作者通过实验得出结论:在*r=16*时可以获得增益与计算量之间的平衡。
* 对于*Fsq*部分,关键是求得*C*维的向量,因此不局限于使用*Global Average Pooling*操作,*SENet*作者认为,最终求得的*scale*是按通道分别作用于*U*的,因此需要基于对应通道的信息计算对应的*scale*,故使用了最简单的*Global Average Pooling*操作,最终求得的*scale*向量表示了不同通道之间的分布关系,而忽略了同一个通道中的分布关系。
* 对于*Fex*部分,其作用是为了在每一个*mini batch*上的训练来求得基于所有训练数据的分布。因为我们的训练是在*mini batch*上进行的,而基于全部训练数据求得的*scale*才是最佳的,使用*Fex*部分,可以通过在每个*mini batch*上的训练来求得更为逼近全部训练数据的*scale*。