在我前面的众多博文中,关于模型后处理轻量化的记录比较少,大多是在做项目开发,其实前面很多项目中都用到了对应的剪枝、蒸馏等轻量化的技术只是没有单独拿出来记录,这周正好有空闲的时间就想着把这部分的内容简单梳理一下,为了更加有逻辑条理,这里我以经典的YOLOv5网络模型为例,选取了平时项目中使用频度最高的三款参数量级的模型,以茶叶嫩芽场景为例来开发构建目标检测模型,之后基于pruning剪枝技术为例对模型进行剪枝轻量化处理,完成微调训练开发,此外还可以基于原始模型进行蒸馏训练提升原始的精度。
昨天的时候我已经从原生模型开发到剪枝处理、训练微调的完整流程进行了详细的实践记录,感兴趣的话可以自行移步阅读即可,如下所示:
《基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响》
《基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】》
本文的主要目的是想要在完成剪枝处理后,基于蒸馏训练技术来实现对剪枝后的模型进行精度的提升训练。本文主要是延续基于前两篇博文的内容,具有比较强的连续性,所以如有疑问还是需要阅读前两篇文章之后才行的,这里我就不再赘述了。
知识蒸馏(Knowledge Distillation)是一种用于模型压缩和迁移学习的技术,旨在将一个大型、复杂的模型的知识传递给一个更小、更简单的模型。它的基本思想是通过训练一个“教师模型”来辅助训练一个“学生模型”。
在知识蒸馏中,通常有两个模型参与训练过程:
- 教师模型(Teacher Model):通常是一个复杂的模型,具有较高的准确率。它可以是一个深度神经网络或其他模型。
- 学生模型(Student Model):通常是一个更小、更简单的模型,参数量较少,并希望达到与教师模型相似甚至更好的性能。
知识蒸馏的训练过程如下:
- 使用标注的训练数据训练教师模型,使其达到一个较高的准确率。
- 在训练过程中,使用教师模型的输出(通常是模型的软目标,即类别概率分布),作为学生模型的辅助标签。
- 使用标注的训练数据训练学生模型,使其尽可能地拟合教师模型的软目标。
- 最终,学生模型可以根据自身的参数和输入独立地进行预测。
知识蒸馏的目的是通过传递教师模型的知识,为学生模型提供更多的信息和启发,使得学生模型在保持高性能的同时,具有更小的模型体积和计算复杂度。这种压缩的模型可用于在资源受限的设备上进行部署,并且通常具有更低的推理时间和内存消耗。
除了模型压缩,知识蒸馏还可以用于迁移学习,在目标任务的训练数据有限的情况下,利用教师模型的知识来帮助学生模型更快地学习和泛化。
这里一个比较基础的想法和操作就是使用最原始官方模型结构训练得到的模型权重来作为教师网络,在前文中我对比了在不同剪枝程度下的模型效果,这里就以不同剪枝程度下的模型权重作为学生网络,其实即使不使用蒸馏技术直接怼剪枝后的网络模型进行微调训练也都是可以的,但是这里的目的是想要探索下蒸馏技术对于剪枝轻量化处理后的模型的性能提升能力。
二者的创建初始化也是很便利的,这里对照操作即可。
这里首先是剪枝程度为30的情况下对应模型的训练,如下所示:
#yolov5n
python train.py --teacher runs/train/yolov5n/weights/best.pt --student weights/yolov5n_layer_pruning_0.3.pt --data data/self.yaml --batch-size 4 --img-size 416 --name yolov5n_pruning_0.30_distillation
#yolov5s
python train.py --teacher runs/train/yolov5s/weights/best.pt --student weights/yolov5s_layer_pruning_0.3.pt --data data/self.yaml --batch-size 4 --img-size 416 --name yolov5s_pruning_0.30_distillation
#yolov5m
python train.py --teacher runs/train/yolov5m/weights/best.pt --student weights/yolov5m_layer_pruning_0.3.pt --data data/self.yaml --batch-size 4 --img-size 416 --name yolov5m_pruning_0.30_distillation
同样,这里可以看到:保持了与前文完全相同的训练参数。
等待训练完成后我们来看下实际的训练效果:
【yolov5n_pruning_0.30_distillation】
【yolov5s_pruning_0.30_distillation】
【yolov5m_pruning_0.30_distillation】
三款模型对比评估结果详情如下所示:
【yolov5n_pruning_0.30_distillation】
Validating runs/train/yolov5n_pruning_0.30_distillation/weights/best.pt...
Fusing layers...
YOLOv5n summary: 157 layers, 1283792 parameters, 0 gradients, 3.0 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|??????????| 5/5 [00:03<00:00, 1.29it/s]
all 40 100 0.396 0.447 0.391 0.117
Results saved to runs/train/yolov5n_pruning_0.30_distillation
【yolov5s_pruning_0.30_distillation】
Validating runs/train/yolov5s_pruning_0.30_distillation/weights/best.pt...
Fusing layers...
YOLOv5s summary: 166 layers, 5685216 parameters, 0 gradients
Class Images Instances P R mAP50 mAP50-95: 100%|??????????| 5/5 [00:03<00:00, 1.59it/s]
all 40 100 0.653 0.49 0.57 0.207
Results saved to runs/train/yolov5s_pruning_0.30_distillation
【yolov5m_pruning_0.30_distillation】
Validating runs/train/yolov5m_pruning_0.30_distillation/weights/best.pt...
Fusing layers...
YOLOv5m summary: 212 layers, 15704926 parameters, 0 gradients, 35.5 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|??????????| 5/5 [00:02<00:00, 1.70it/s]
all 40 100 0.416 0.33 0.322 0.114
Results saved to runs/train/yolov5m_pruning_0.30_distillation
为了直观地对比分析模型性能差异,这里对其进行可视化对比分析。
【Precision曲线】
精确率曲线(Precision-Recall Curve)是一种用于评估二分类模型在不同阈值下的精确率性能的可视化工具。它通过绘制不同阈值下的精确率和召回率之间的关系图来帮助我们了解模型在不同阈值下的表现。
精确率(Precision)是指被正确预测为正例的样本数占所有预测为正例的样本数的比例。召回率(Recall)是指被正确预测为正例的样本数占所有实际为正例的样本数的比例。
绘制精确率曲线的步骤如下:
使用不同的阈值将预测概率转换为二进制类别标签。通常,当预测概率大于阈值时,样本被分类为正例,否则分类为负例。
对于每个阈值,计算相应的精确率和召回率。
将每个阈值下的精确率和召回率绘制在同一个图表上,形成精确率曲线。
根据精确率曲线的形状和变化趋势,可以选择适当的阈值以达到所需的性能要求。
通过观察精确率曲线,我们可以根据需求确定最佳的阈值,以平衡精确率和召回率。较高的精确率意味着较少的误报,而较高的召回率则表示较少的漏报。根据具体的业务需求和成本权衡,可以在曲线上选择合适的操作点或阈值。
精确率曲线通常与召回率曲线(Recall Curve)一起使用,以提供更全面的分类器性能分析,并帮助评估和比较不同模型的性能。
【Recall曲线】
召回率曲线(Recall Curve)是一种用于评估二分类模型在不同阈值下的召回率性能的可视化工具。它通过绘制不同阈值下的召回率和对应的精确率之间的关系图来帮助我们了解模型在不同阈值下的表现。
召回率(Recall)是指被正确预测为正例的样本数占所有实际为正例的样本数的比例。召回率也被称为灵敏度(Sensitivity)或真正例率(True Positive Rate)。
绘制召回率曲线的步骤如下:
使用不同的阈值将预测概率转换为二进制类别标签。通常,当预测概率大于阈值时,样本被分类为正例,否则分类为负例。
对于每个阈值,计算相应的召回率和对应的精确率。
将每个阈值下的召回率和精确率绘制在同一个图表上,形成召回率曲线。
根据召回率曲线的形状和变化趋势,可以选择适当的阈值以达到所需的性能要求。
通过观察召回率曲线,我们可以根据需求确定最佳的阈值,以平衡召回率和精确率。较高的召回率表示较少的漏报,而较高的精确率意味着较少的误报。根据具体的业务需求和成本权衡,可以在曲线上选择合适的操作点或阈值。
召回率曲线通常与精确率曲线(Precision Curve)一起使用,以提供更全面的分类器性能分析,并帮助评估和比较不同模型的性能。
【F1值曲线】
F1值曲线是一种用于评估二分类模型在不同阈值下的性能的可视化工具。它通过绘制不同阈值下的精确率(Precision)、召回率(Recall)和F1分数的关系图来帮助我们理解模型的整体性能。
F1分数是精确率和召回率的调和平均值,它综合考虑了两者的性能指标。F1值曲线可以帮助我们确定在不同精确率和召回率之间找到一个平衡点,以选择最佳的阈值。
绘制F1值曲线的步骤如下:
使用不同的阈值将预测概率转换为二进制类别标签。通常,当预测概率大于阈值时,样本被分类为正例,否则分类为负例。
对于每个阈值,计算相应的精确率、召回率和F1分数。
将每个阈值下的精确率、召回率和F1分数绘制在同一个图表上,形成F1值曲线。
根据F1值曲线的形状和变化趋势,可以选择适当的阈值以达到所需的性能要求。
F1值曲线通常与接收者操作特征曲线(ROC曲线)一起使用,以帮助评估和比较不同模型的性能。它们提供了更全面的分类器性能分析,可以根据具体应用场景来选择合适的模型和阈值设置。
可以看到:剪枝+蒸馏处理后的模型与原生网络模型相比还是有不小的差距的。
接下来我们对其进行整体对比分析,同时展示:原生模型、剪枝模型和剪枝+蒸馏模型,如下所示:
【F1值】
【Precision】
【Recall】
接下来是第二组实验,剪枝程度为60,之后进行蒸馏训练。
【yolov5n_pruning_0.60_distillation】
【yolov5s_pruning_0.60_distillation】
【yolov5m_pruning_0.60_distillation】
三款模型对比评估结果详情如下所示:
【yolov5n_pruning_0.60_distillation】
Validating runs/train/yolov5n_pruning_0.60_distillation/weights/best.pt...
Fusing layers...
YOLOv5n summary: 157 layers, 932592 parameters, 0 gradients, 2.1 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|??????????| 5/5 [00:03<00:00, 1.36it/s]
all 40 100 0.214 0.15 0.108 0.0302
Results saved to runs/train/yolov5n_pruning_0.60_distillation
【yolov5s_pruning_0.60_distillation】
Validating runs/train/yolov5s_pruning_0.60_distillation/weights/best.pt...
Fusing layers...
YOLOv5s summary: 166 layers, 4637807 parameters, 0 gradients
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 5/5 [00:02<00:00, 1.78it/s]
all 40 100 0.0492 0.21 0.0219 0.00481
Results saved to runs/train/yolov5s_pruning_0.60_distillation
【yolov5m_pruning_0.60_distillation】
Validating runs/train/yolov5m_pruning_0.60_distillation/weights/best.pt...
Fusing layers...
YOLOv5m summary: 212 layers, 11711883 parameters, 0 gradients, 25.4 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 5/5 [00:02<00:00, 2.34it/s]
all 40 100 0.0879 0.07 0.0455 0.0152
Results saved to runs/train/yolov5m_pruning_0.60_distillation
为了直观地对比分析模型性能差异,这里对其进行可视化对比分析。
【F1】
【Precision】
【Recall】
整体对比结果如下所示:
【F1】
【Precision】
【Recall】
直观看下来感觉蒸馏训练下来的效果很不好。
最后来看剪枝程度为90的结果。
【yolov5n_pruning_0.90_distillation】
【yolov5s_pruning_0.90_distillation】
【yolov5m_pruning_0.90_distillation】
结果详情如下所示:
【yolov5n_pruning_0.90_distillation】
Validating runs/train/yolov5n_pruning_0.90_distillation/weights/best.pt...
Fusing layers...
YOLOv5n summary: 157 layers, 710530 parameters, 0 gradients, 1.4 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 5/5 [00:01<00:00, 2.84it/s]
all 40 100 0.00442 0.53 0.00368 0.000863
Results saved to runs/train/yolov5n_pruning_0.90_distillation
【yolov5s_pruning_0.90_distillation】
Validating runs/train/yolov5s_pruning_0.90_distillation/weights/best.pt...
Fusing layers...
YOLOv5s summary: 166 layers, 3920903 parameters, 0 gradients
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 5/5 [00:01<00:00, 3.38it/s]
all 40 100 0.00525 0.63 0.00443 0.00111
Results saved to runs/train/yolov5s_pruning_0.90_distillation
【yolov5m_pruning_0.90_distillation】
Validating runs/train/yolov5m_pruning_0.90_distillation2/weights/best.pt...
Fusing layers...
YOLOv5m summary: 212 layers, 8908815 parameters, 0 gradients, 17.7 GFLOPs
Class Images Instances P R mAP50 mAP50-95: 100%|??????????| 5/5 [00:01<00:00, 3.58it/s]
all 40 100 0.00133 0.16 0.000855 0.000268
Results saved to runs/train/yolov5m_pruning_0.90_distillation
这里的结果就更不好的了。
并非所有的方法都是可以直接起效的,跟参数调整也有很多关系,后面会在整理研究下,今天主要是整体流程的实践。
最后整体对比一下三种不同程度剪枝水平下蒸馏训练的结果:
【F1值】
【Precision】
【Recall】
直观地对比发现就是:随着剪枝程度的提高效果变得越来越差,蒸馏也没有办法带来有效的提升。
就技术本身来说,知识蒸馏是有很多手段和方法的,不同的场景、模型可能会有不同的适配方案,在实际的项目中是需要实地分析实践找到最行之有效的办法才行的。