-
我们收集整理了开源以来在 issues 和用户群中的常见问题并且给出了简要解答,旨在为广大用户提供一些参考,也希望帮助大家少走一些弯路。
-
图像分类、识别、检索领域大佬众多,模型和论文更新速度也很快,本文档回答主要依赖有限的项目实践,难免挂一漏万,如有遗漏和不足,也希望有识之士帮忙补充和修正,万分感谢。
A:PaddleClas 是一个兼主体检测、图像分类、图像检索于一体的图像识别 repo,用于解决大部分图像识别问题,用户可以很方便的使用 PaddleClas 来解决小样本、多类别的图像识别问题。PaddleDetection 提供了目标检测、关键点检测、多目标跟踪等能力,方便用户定位图像中的感兴趣的点和区域,被广泛应用于工业质检、遥感图像检测、无人巡检等项目。
A: Momentum 优化器是在 SGD 优化器的基础上引入了“动量”的概念。在 SGD 优化器中,在 t+1
时刻,参数 w
的更新可表示为:
w_t+1 = w_t - lr * grad
其中,lr
为学习率,grad
为此时参数 w
的梯度。在引入动量的概念后,参数 w
的更新可表示为:
v_t+1 = m * v_t + lr * grad
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
。因此,太过“久远”的梯度信息对当前的参考意义很小,而“最近”的历史梯度信息对当前影响更大,这也是符合直觉的。
通过引入动量的概念,在参数更新时考虑了历史更新的影响,因此可以加快收敛速度,也改善了 SGD
优化器带来的损失(cost、loss)震荡问题。
A: 目前 PaddleClas 没有实现。如果需要,可以尝试自己修改代码。简单来说,该论文所提出的思想是使用较大分辨率作为输入,对已经训练好的模型最后的 FC 层进行 fine-tune。具体操作上,首先在较低分辨率的数据集上对模型网络进行训练,完成训练后,对网络除最后的 FC 层外的其他层的权重设置参数 stop_gradient=True
,然后使用较大分辨率的输入对网络进行 fine-tune 训练。
A:PaddleClas 提供了多种数据增广方式,可分为 3 类:
- 图像变换类: AutoAugment, RandAugment;
- 图像裁剪类: CutOut、RandErasing、HideAndSeek、GridMask;
- 图像混叠类:Mixup, Cutmix.
其中,RandAngment 提供了多种数据增强方式的随机组合,可以满足亮度、对比度、饱和度、色调等多方面的数据增广需求。
A:主体检测这块的输出数量是可以通过配置文件配置的。在配置文件中 Global.threshold 控制检测的阈值,小于该阈值的检测框被舍弃,Global.max_det_results 控制最大返回的结果数,这两个参数共同决定了输出检测框的数量。
A:训练数据是在 COCO、Object365、RPC、LogoDet 等公开数据集中随机抽取的子集。目前我们在 2.3 版本中推出了超轻量的主体检测模型,具体信息可以参考主体检测。关于主体检测模型的更多信息请参考主体检测。
A:目前的主体检测模型训练时使用了 COCO、Object365、RPC、LogoDet 等公开数据集,如果被检测数据是类似工业质检等于常见类别差异较大的数据,需要基于目前的检测模型重新微调训练。
A:circle loss
是统一了样本对学习和分类学习的两种形式,如果是分类学习的形式的话,可以增加 triplet loss
。
A:建议使用商品识别模型,一来是因为商品覆盖的范围比较广,被识别的图片是商品的概率更大,二来是因为商品识别模型的训练数据使用了 5 万类别的数据,泛化能力更好,特征会更鲁棒一些。
A:使用维度小的向量,为了加快计算,在实际使用过程中,可能使用 128 甚至更小。一般来说,512 的维度已经够大,能充分表示特征了。
Q1.6.1 PaddleClas 目前使用的 Möbius 向量检索算法支持类似于 faiss 的那种 index.add()的功能吗? 另外,每次构建新的图都要进行 train 吗?这里的 train 是为了检索加速还是为了构建相似的图?
A:目前在 release/2.3 分支已经支持 faiss 检索模块,并且不再支持 Möbius。关于 Möbius 提供的检索算法,是一种基于图的近似最近邻搜索算法,目前支持两种距离计算方式:inner product 和 L2 distance,但是 Möbius 暂不支持 faiss 中提供的 index.add 功能,如果需要增加检索库的内容,需要从头重新构建新的 index. 在每次构建 index 时,检索算法内部执行的操作是一种类似于 train 的过程,不同于 faiss 提供的 train 接口。因此需要 faiss 模块的话,可以使用 release/2.3 分支,需要 Möbius 的话,目前需要回退到 release/2.2 分支。
A: Query
与 Gallery
均为数据集配置,其中 Gallery
用于配置底库数据,Query
用于配置验证集。在进行 Eval 时,首先使用模型对 Gallery
底库数据进行前向计算特征向量,特征向量用于构建底库,然后模型对 Query
验证集中的数据进行前向计算特征向量,再与底库计算召回率等指标。
A:在保存权重的路径中存放了 train.log
。
A:
1.确保正确加载预训练模型, 最简单的加载方式添加参数 -o Arch.pretrained=True
即可;
2.模型微调时,学习率不要太大,如设置 0.001 就好。
A:可以,但目前 PaddleClas 并不支持视频输入。可以尝试修改一下 PaddleClas 代码,或者预先将视频逐帧转为图像存储,再使用 PaddleClas 进行预测。
A: PaddleClas 支持的数据预处理算子可在这里查看:ppcls/data/preprocess/__init__.py
,所有支持的算子均可在配置文件中进行配置,配置的算子名称需要和算子类名一致,参数与对应算子类的构造函数参数一致。如不需要对图像裁剪,则可去掉 CropImage
、RandCropImage
,使用 ResizeImage
替换即可,可通过其参数设置不同的 resize 方式,使用 size
参数则直接将图像缩放至固定大小,使用 resize_short
参数则会维持图像宽高比进行缩放。设置裁剪尺寸时,可通过 CropImage
算子的 size
参数,或 RandCropImage
算子的 size
参数。
A: 首先可以使用以下代码测试 Paddle 是否安装正确:
import paddle
paddle.utils.install_check.run_check()
正确安装时,通常会有如下提示:
PaddlePaddle is installed successfully! Let's start deep learning with PaddlePaddle now.
如未能安装成功,则会有相应问题的提示。 另外,在同时安装 CPU 版本和 GPU 版本 Paddle 后,由于两个版本存在冲突,需要将两个版本全部卸载,然后重新安装所需要的版本。
A: PaddleClas 在训练过程中,会保存/更新以下三类模型:
- 最新的模型(
latest.pdopt
,latest.pdparams
,latest.pdstates
),当训练意外中断时,可使用最新保存的模型恢复训练; - 最优的模型(
best_model.pdopt
,best_model.pdparams
,best_model.pdstates
); - 训练过程中,一个 epoch 结束时的断点(
epoch_xxx.pdopt
,epoch_xxx.pdparams
,epoch_xxx.pdstates
)。训练配置文件中Global.save_interval
字段表示该模型的保存间隔。将该字段设置大于总 epochs 数,则不再保存中间断点模型。
Q2.1.7: 在训练时,出现如下报错信息:ERROR: Unexpected segmentation fault encountered in DataLoader workers.
,如何排查解决问题呢?
A:尝试将训练配置文件中的字段 num_workers
设置为 0
;尝试将训练配置文件中的字段 batch_size
调小一些;检查数据集格式和配置文件中的数据集路径是否正确。
A:
-
使用
Mixup
或Cutmix
做训练时无法计算训练的精度(Acc)指标,因此需要在配置文件中取消Metric.Train.TopkAcc
字段,可参考 Metric.Train.TopkAcc。
A:
- 当需要
fine-tune
时,可以通过字段Global.pretrain_model
配置预训练模型权重文件的路径,预训练模型权重文件后缀名通常为.pdparams
; - 在训练过程中,训练程序会自动保存每个 epoch 结束时的断点信息,包括优化器信息
.pdopt
和模型权重信息.pdparams
。在训练过程意外中断等情况下,需要恢复训练时,可以通过字段Global.checkpoints
配置训练过程中保存的断点信息文件,例如通过配置checkpoints: ./output/ResNet18/epoch_18
即可恢复 18 epoch 训练结束时的断点信息,PaddleClas 将自动加载epoch_18.pdopt
和epoch_18.pdparams
,从 19 epoch 继续训练。
A:步骤如下:
- 基于 facebook 开源的
ResNeXt101-32x16d-wsl
模型去蒸馏得到了ResNet50-vd
模型; - 用这个
ResNet50-vd
,在 500W 数据集上去蒸馏MobilNetV3
; - 考虑到 500W 的数据集的分布和 100W 的数据分布不完全一致,所以这块,在 100W 上的数据上又 finetune 了一下,精度有微弱的提升。
A:训练 SwinTransformer 时,请使用版本大于等于 2.1.1
的 Paddle
,并且加载我们提供的预训练模型,学习率也不宜过大。
A:主体检测模型会返回检测框,但事实上为了让后续的识别模型更加准确,在返回检测框的同时也返回了原图。后续会根据原图或者检测框与库中的图片的相似度排序,相似度最高的库中图片的标签即为被识别图片的标签。
A:要达到实时的检测效果,需要检测速度达到实时性的要求;PP-YOLO 是 Paddle 团队提供的轻量级目标检测模型,检测速度和精度达到了很好的平衡,可以试试 PP-YOLO 来做检测. 关于 PP-YOLO 的使用,可以参照:PaddleDetection。
A:如果检测模型在自己的数据集上表现不佳,需要在自己的检测数据集上再 finetune 下
A:如果使用的是 release/2.2 分支,建议更新为 release/2.3 分支,在 release/2.3 分支中,我们使用 faiss 检索模块替换了 Möbius 检索模型,具体可以参考向量检索教程。如仍存在问题,可以在用户微信群中联系我们,也可以在 GitHub 提 issue。
A:识别模型的微调训练和分类模型的微调训练类似,识别模型可以加载商品的预训练模型,训练过程可以参考识别模型训练,后续我们也会持续细化这块的文档。
A:在训练 metric learning 时,使用的 Sampler 是 DistributedRandomIdentitySampler,该 Sampler 不会采样全部的图片,导致会让每一个 epoch 采样的数据不是所有的数据,所以无法跑完显示的 mini-batch 是正常现象。该问题在 release/2.3 分支已经优化,请更新到 release/2.3 使用。
A:在配置文件(如 inference_product.yaml)中,IndexProcess.score_thres
中会控制被识别的图片与库中的图片的余弦相似度的最小值。当余弦相似度小于该值时,不会打印结果。您可以根据自己的实际数据调整该值。
A:请确保 data_file.txt 中图片路径和图片名称中间的间隔为单个 table,而不是空格。
A:从 release/2.3 分支起,我们使用 faiss 检索模块替换了 Möbius 检索模型,已经支持在不构建底库的前提下新增底库数据,具体可以参考向量检索教程。
A:如果使用的是 release/2.2 分支,建议更新为 release/2.3 分支,在 release/2.3 分支中,我们使用 faiss 检索模块替换了 Möbius 检索模型,具体可以参考向量检索教程。如仍存在问题,可以在用户微信群中联系我们,也可以在 GitHub 提 issue。
A:pq_size
是 PQ 检索算法的参数。PQ 检索算法可以简单理解为“分层”检索算法,pq_size
是每层的“容量”,因此该参数的设置会影响检索性能,不过,在底库总数据量不太大(小于 10000 张)的情况下,这个参数对性能的影响很小,因此对于大多数使用场景而言,在构建底库时无需修改该参数。关于 PQ 检索算法的更多内容,可以查看相关论文。
A:具体可以参考 hub serving 参数。
A: 该问题通常是由于在导出时未能正确加载模型参数导致的,首先检查模型导出时的日志,是否存在类似下述内容:
UserWarning: Skip loading for ***. *** is not found in the provided dict.
如果存在,则说明模型权重未能加载成功,请进一步检查配置文件中的 Global.pretrained_model
字段,是否正确配置了模型权重文件的路径。模型权重文件后缀名通常为 pdparams
,注意在配置该路径时无需填写文件后缀名。
A:Paddle 支持两种转 ONNX 格式模型的方式,且依赖于 paddle2onnx
工具,首先需要安装 paddle2onnx
:
pip install paddle2onnx
-
从 inference model 转为 ONNX 格式模型:
以动态图导出的
combined
格式 inference model(包含.pdmodel
和.pdiparams
两个文件)为例,使用以下命令进行模型格式转换:paddle2onnx --model_dir ${model_path} --model_filename ${model_path}/inference.pdmodel --params_filename ${model_path}/inference.pdiparams --save_file ${save_path}/model.onnx --enable_onnx_checker True
上述命令中:
model_dir
:该参数下需要包含.pdmodel
和.pdiparams
两个文件;model_filename
:该参数用于指定参数model_dir
下的.pdmodel
文件路径;params_filename
:该参数用于指定参数model_dir
下的.pdiparams
文件路径;save_file
:该参数用于指定转换后的模型保存目录路径。
关于静态图导出的非
combined
格式的 inference model(通常包含文件__model__
和多个参数文件)转换模型格式,以及更多参数说明请参考 paddle2onnx 官方文档 paddle2onnx。 -
直接从模型组网代码导出 ONNX 格式模型:
以动态图模型组网代码为例,模型类为继承于
paddle.nn.Layer
的子类,代码如下所示:import paddle from paddle.static import InputSpec class SimpleNet(paddle.nn.Layer): def __init__(self): pass def forward(self, x): pass net = SimpleNet() x_spec = InputSpec(shape=[None, 3, 224, 224], dtype='float32', name='x') paddle.onnx.export(layer=net, path="./SimpleNet", input_spec=[x_spec])
其中:
InputSpec()
函数用于描述模型输入的签名信息,包括输入数据的shape
、type
和name
(可省略);paddle.onnx.export()
函数需要指定模型组网对象net
,导出模型的保存路径save_path
,模型的输入数据描述input_spec
。
需要注意,
paddlepaddle
版本需大于2.0.0
。关于paddle.onnx.export()
函数的更多参数说明请参考 paddle.onnx.export。