diff --git "a/2022/03/03/Hilbert\347\232\204c-\345\256\236\347\216\260/index.html" "b/2022/03/03/Hilbert\347\232\204c-\345\256\236\347\216\260/index.html" index 4cc25fe..650ff8d 100644 --- "a/2022/03/03/Hilbert\347\232\204c-\345\256\236\347\216\260/index.html" +++ "b/2022/03/03/Hilbert\347\232\204c-\345\256\236\347\216\260/index.html" @@ -295,7 +295,7 @@

- 25 + 31 日志
diff --git "a/2022/03/03/c-\344\270\255fftw\345\272\223\347\232\204\345\256\211\350\243\205\345\217\212\345\237\272\347\241\200\344\275\277\347\224\250/index.html" "b/2022/03/03/c-\344\270\255fftw\345\272\223\347\232\204\345\256\211\350\243\205\345\217\212\345\237\272\347\241\200\344\275\277\347\224\250/index.html" index ae5708d..a08eb03 100644 --- "a/2022/03/03/c-\344\270\255fftw\345\272\223\347\232\204\345\256\211\350\243\205\345\217\212\345\237\272\347\241\200\344\275\277\347\224\250/index.html" +++ "b/2022/03/03/c-\344\270\255fftw\345\272\223\347\232\204\345\256\211\350\243\205\345\217\212\345\237\272\347\241\200\344\275\277\347\224\250/index.html" @@ -357,7 +357,7 @@

- 25 + 31 日志 diff --git "a/2022/03/03/\345\237\272\344\272\216github-Hexo\345\210\233\345\273\272\344\270\252\344\272\272\345\215\232\345\256\242/index.html" "b/2022/03/03/\345\237\272\344\272\216github-Hexo\345\210\233\345\273\272\344\270\252\344\272\272\345\215\232\345\256\242/index.html" index a0278b1..f0d212f 100644 --- "a/2022/03/03/\345\237\272\344\272\216github-Hexo\345\210\233\345\273\272\344\270\252\344\272\272\345\215\232\345\256\242/index.html" +++ "b/2022/03/03/\345\237\272\344\272\216github-Hexo\345\210\233\345\273\272\344\270\252\344\272\272\345\215\232\345\256\242/index.html" @@ -320,7 +320,7 @@

- 25 + 31 日志 diff --git "a/2022/03/28/pytorch\347\233\270\345\205\263/index.html" "b/2022/03/28/pytorch\347\233\270\345\205\263/index.html" index e022d3b..c449e45 100644 --- "a/2022/03/28/pytorch\347\233\270\345\205\263/index.html" +++ "b/2022/03/28/pytorch\347\233\270\345\205\263/index.html" @@ -357,7 +357,7 @@

- 25 + 31 日志 diff --git "a/2022/03/28/\346\267\261\345\272\246\345\255\246\344\271\240\347\275\221\347\273\234\347\233\270\345\205\263/index.html" "b/2022/03/28/\346\267\261\345\272\246\345\255\246\344\271\240\347\275\221\347\273\234\347\233\270\345\205\263/index.html" index 83f124c..af7a3df 100644 --- "a/2022/03/28/\346\267\261\345\272\246\345\255\246\344\271\240\347\275\221\347\273\234\347\233\270\345\205\263/index.html" +++ "b/2022/03/28/\346\267\261\345\272\246\345\255\246\344\271\240\347\275\221\347\273\234\347\233\270\345\205\263/index.html" @@ -411,7 +411,7 @@

- 25 + 31 日志 diff --git "a/2022/04/19/\347\233\256\346\240\207\346\243\200\346\265\213\347\233\270\345\205\263/index.html" "b/2022/04/19/\347\233\256\346\240\207\346\243\200\346\265\213\347\233\270\345\205\263/index.html" index 27bc0ad..7963ae2 100644 --- "a/2022/04/19/\347\233\256\346\240\207\346\243\200\346\265\213\347\233\270\345\205\263/index.html" +++ "b/2022/04/19/\347\233\256\346\240\207\346\243\200\346\265\213\347\233\270\345\205\263/index.html" @@ -493,7 +493,7 @@

- 25 + 31 日志 diff --git "a/2022/07/04/YOLOv4\346\200\273\347\273\223/index.html" "b/2022/07/04/YOLOv4\346\200\273\347\273\223/index.html" index eb313d4..619b7a5 100644 --- "a/2022/07/04/YOLOv4\346\200\273\347\273\223/index.html" +++ "b/2022/07/04/YOLOv4\346\200\273\347\273\223/index.html" @@ -622,7 +622,7 @@

- 25 + 31 日志 diff --git a/2022/07/25/Label Assignment/index.html b/2022/07/25/Label Assignment/index.html index 4152124..b86807a 100644 --- a/2022/07/25/Label Assignment/index.html +++ b/2022/07/25/Label Assignment/index.html @@ -471,7 +471,7 @@

总结 - 25 + 31 日志 diff --git a/2022/07/26/SSD Single Shot MultiBox Detector/index.html b/2022/07/26/SSD Single Shot MultiBox Detector/index.html index 866cdce..a8a03bf 100644 --- a/2022/07/26/SSD Single Shot MultiBox Detector/index.html +++ b/2022/07/26/SSD Single Shot MultiBox Detector/index.html @@ -416,7 +416,7 @@

- 25 + 31 日志 diff --git a/2022/08/22/Bert/index.html b/2022/08/22/Bert/index.html index 22136a4..df1805a 100644 --- a/2022/08/22/Bert/index.html +++ b/2022/08/22/Bert/index.html @@ -360,7 +360,7 @@

- 25 + 31 日志 diff --git a/2022/08/22/DETR/index.html b/2022/08/22/DETR/index.html index 4515f6c..5fd1742 100644 --- a/2022/08/22/DETR/index.html +++ b/2022/08/22/DETR/index.html @@ -358,7 +358,7 @@

缺点 - 25 + 31 日志 diff --git a/2022/08/22/Deformable DETR/index.html b/2022/08/22/Deformable DETR/index.html index f9d97cd..419c68a 100644 --- a/2022/08/22/Deformable DETR/index.html +++ b/2022/08/22/Deformable DETR/index.html @@ -356,7 +356,7 @@

- 25 + 31 日志 diff --git a/2022/08/22/Towards Data-Efficient Detection Transformer/index.html b/2022/08/22/Towards Data-Efficient Detection Transformer/index.html index ce249a2..ec25fdc 100644 --- a/2022/08/22/Towards Data-Efficient Detection Transformer/index.html +++ b/2022/08/22/Towards Data-Efficient Detection Transformer/index.html @@ -465,7 +465,7 @@

结论 - 25 + 31 日志 diff --git a/2022/08/22/VIT/index.html b/2022/08/22/VIT/index.html index b755835..6111d6e 100644 --- a/2022/08/22/VIT/index.html +++ b/2022/08/22/VIT/index.html @@ -324,7 +324,7 @@

- 25 + 31 日志 diff --git "a/2022/08/22/transformer\347\233\270\345\205\263/index.html" "b/2022/08/22/transformer\347\233\270\345\205\263/index.html" index 5a2b036..a69e087 100644 --- "a/2022/08/22/transformer\347\233\270\345\205\263/index.html" +++ "b/2022/08/22/transformer\347\233\270\345\205\263/index.html" @@ -407,7 +407,7 @@

缺点 - 25 + 31 日志 diff --git "a/2023/03/04/RK3588s\351\203\250\347\275\262\347\233\270\345\205\263-NEW/index.html" "b/2023/03/04/RK3588s\351\203\250\347\275\262\347\233\270\345\205\263-NEW/index.html" index 554b227..b0060c1 100644 --- "a/2023/03/04/RK3588s\351\203\250\347\275\262\347\233\270\345\205\263-NEW/index.html" +++ "b/2023/03/04/RK3588s\351\203\250\347\275\262\347\233\270\345\205\263-NEW/index.html" @@ -445,7 +445,7 @@

- 25 + 31 日志 diff --git "a/2023/03/21/RK3588\343\200\201ros\343\200\201fastdeploy\350\201\224\345\220\210\347\216\257\345\242\203\350\256\276\347\275\256/index.html" "b/2023/03/21/RK3588\343\200\201ros\343\200\201fastdeploy\350\201\224\345\220\210\347\216\257\345\242\203\350\256\276\347\275\256/index.html" index 2b726c2..2c55875 100644 --- "a/2023/03/21/RK3588\343\200\201ros\343\200\201fastdeploy\350\201\224\345\220\210\347\216\257\345\242\203\350\256\276\347\275\256/index.html" +++ "b/2023/03/21/RK3588\343\200\201ros\343\200\201fastdeploy\350\201\224\345\220\210\347\216\257\345\242\203\350\256\276\347\275\256/index.html" @@ -349,7 +349,7 @@

- 25 + 31 日志 diff --git "a/2023/04/12/c-\344\270\255\347\232\204ffmpeg\346\272\220\347\240\201\345\255\246\344\271\240/index.html" "b/2023/04/12/c-\344\270\255\347\232\204ffmpeg\346\272\220\347\240\201\345\255\246\344\271\240/index.html" index 3dfcb75..f5416ff 100644 --- "a/2023/04/12/c-\344\270\255\347\232\204ffmpeg\346\272\220\347\240\201\345\255\246\344\271\240/index.html" +++ "b/2023/04/12/c-\344\270\255\347\232\204ffmpeg\346\272\220\347\240\201\345\255\246\344\271\240/index.html" @@ -534,7 +534,7 @@

- 25 + 31 日志 diff --git "a/2023/04/12/ffmpeg\345\237\272\347\241\200\344\272\206\350\247\243/index.html" "b/2023/04/12/ffmpeg\345\237\272\347\241\200\344\272\206\350\247\243/index.html" index fd28792..250e4cd 100644 --- "a/2023/04/12/ffmpeg\345\237\272\347\241\200\344\272\206\350\247\243/index.html" +++ "b/2023/04/12/ffmpeg\345\237\272\347\241\200\344\272\206\350\247\243/index.html" @@ -1050,7 +1050,7 @@

- 25 + 31 日志 diff --git a/2023/04/23/AGW A New Baseline for Single-Cross-Modality Re-ID/index.html b/2023/04/23/AGW A New Baseline for Single-Cross-Modality Re-ID/index.html index ec8d5a2..1978e2a 100644 --- a/2023/04/23/AGW A New Baseline for Single-Cross-Modality Re-ID/index.html +++ b/2023/04/23/AGW A New Baseline for Single-Cross-Modality Re-ID/index.html @@ -302,7 +302,7 @@

- 25 + 31 日志 diff --git a/2023/04/23/Bag of Tricks and A Strong Baseline for Deep Person Re-identification.md/index.html b/2023/04/23/Bag of Tricks and A Strong Baseline for Deep Person Re-identification.md/index.html index 288eb41..84120fe 100644 --- a/2023/04/23/Bag of Tricks and A Strong Baseline for Deep Person Re-identification.md/index.html +++ b/2023/04/23/Bag of Tricks and A Strong Baseline for Deep Person Re-identification.md/index.html @@ -360,7 +360,7 @@

- 25 + 31 日志 diff --git "a/2023/04/23/\347\233\256\346\240\207\351\207\215\350\257\206\345\210\253\347\273\274\350\277\260\351\230\205\350\257\273/index.html" "b/2023/04/23/\347\233\256\346\240\207\351\207\215\350\257\206\345\210\253\347\273\274\350\277\260\351\230\205\350\257\273/index.html" index 171dd3f..bc8c4c7 100644 --- "a/2023/04/23/\347\233\256\346\240\207\351\207\215\350\257\206\345\210\253\347\273\274\350\277\260\351\230\205\350\257\273/index.html" +++ "b/2023/04/23/\347\233\256\346\240\207\351\207\215\350\257\206\345\210\253\347\273\274\350\277\260\351\230\205\350\257\273/index.html" @@ -347,7 +347,7 @@

- 25 + 31 日志 diff --git a/2023/06/18/RepVGG-Making-VGG-style-ConvNets-Great-Again/index.html b/2023/06/18/RepVGG-Making-VGG-style-ConvNets-Great-Again/index.html index 8205af5..ee0931b 100644 --- a/2023/06/18/RepVGG-Making-VGG-style-ConvNets-Great-Again/index.html +++ b/2023/06/18/RepVGG-Making-VGG-style-ConvNets-Great-Again/index.html @@ -338,7 +338,7 @@

- 25 + 31 日志 diff --git a/2023/06/18/YOLOv6-A-Single-Stage-Object-Detection-Framework-for-Industrial-Applications/index.html b/2023/06/18/YOLOv6-A-Single-Stage-Object-Detection-Framework-for-Industrial-Applications/index.html index bb18266..80ec503 100644 --- a/2023/06/18/YOLOv6-A-Single-Stage-Object-Detection-Framework-for-Industrial-Applications/index.html +++ b/2023/06/18/YOLOv6-A-Single-Stage-Object-Detection-Framework-for-Industrial-Applications/index.html @@ -359,7 +359,7 @@

- 25 + 31 日志 diff --git a/2023/06/18/YOLOv7-Trainable-bag-of-freebies-sets-new-state-of-the-art-for-real-time-object-detectors/index.html b/2023/06/18/YOLOv7-Trainable-bag-of-freebies-sets-new-state-of-the-art-for-real-time-object-detectors/index.html index 96dbcc8..4e65ec0 100644 --- a/2023/06/18/YOLOv7-Trainable-bag-of-freebies-sets-new-state-of-the-art-for-real-time-object-detectors/index.html +++ b/2023/06/18/YOLOv7-Trainable-bag-of-freebies-sets-new-state-of-the-art-for-real-time-object-detectors/index.html @@ -270,7 +270,10 @@

-
+
+
@@ -343,7 +346,7 @@

- 25 + 31 日志 diff --git a/2023/06/30/CSPNet/103a8eac372346009eeffe0dcad93118.png b/2023/06/30/CSPNet/103a8eac372346009eeffe0dcad93118.png new file mode 100644 index 0000000..b0b24ce Binary files /dev/null and b/2023/06/30/CSPNet/103a8eac372346009eeffe0dcad93118.png differ diff --git a/2023/06/30/CSPNet/150b965a21f743e8a22a9068a2ca9c15.png b/2023/06/30/CSPNet/150b965a21f743e8a22a9068a2ca9c15.png new file mode 100644 index 0000000..04ec44c Binary files /dev/null and b/2023/06/30/CSPNet/150b965a21f743e8a22a9068a2ca9c15.png differ diff --git a/2023/06/30/CSPNet/20201210234304222.png b/2023/06/30/CSPNet/20201210234304222.png new file mode 100644 index 0000000..d9d34ee Binary files /dev/null and b/2023/06/30/CSPNet/20201210234304222.png differ diff --git a/2023/06/30/CSPNet/20201210235050303.png b/2023/06/30/CSPNet/20201210235050303.png new file mode 100644 index 0000000..9f8deb5 Binary files /dev/null and b/2023/06/30/CSPNet/20201210235050303.png differ diff --git a/2023/06/30/CSPNet/281b211c0a544314af53007639dc64e8.png b/2023/06/30/CSPNet/281b211c0a544314af53007639dc64e8.png new file mode 100644 index 0000000..49fe0d8 Binary files /dev/null and b/2023/06/30/CSPNet/281b211c0a544314af53007639dc64e8.png differ diff --git a/2023/06/30/CSPNet/2d7ec7a7f418470698bc5a1f820be714.png b/2023/06/30/CSPNet/2d7ec7a7f418470698bc5a1f820be714.png new file mode 100644 index 0000000..791aa6f Binary files /dev/null and b/2023/06/30/CSPNet/2d7ec7a7f418470698bc5a1f820be714.png differ diff --git a/2023/06/30/CSPNet/419c23c79b0945b294cf22b5c14741b8.png b/2023/06/30/CSPNet/419c23c79b0945b294cf22b5c14741b8.png new file mode 100644 index 0000000..da290ef Binary files /dev/null and b/2023/06/30/CSPNet/419c23c79b0945b294cf22b5c14741b8.png differ diff --git a/2023/06/30/CSPNet/6fcccbe8978840aea95bca7d05e6306b.png b/2023/06/30/CSPNet/6fcccbe8978840aea95bca7d05e6306b.png new file mode 100644 index 0000000..b0b24ce Binary files /dev/null and b/2023/06/30/CSPNet/6fcccbe8978840aea95bca7d05e6306b.png differ diff --git a/2023/06/30/CSPNet/f3ba8572acaf4dab9e857b6403f518ef.png b/2023/06/30/CSPNet/f3ba8572acaf4dab9e857b6403f518ef.png new file mode 100644 index 0000000..3efe1f6 Binary files /dev/null and b/2023/06/30/CSPNet/f3ba8572acaf4dab9e857b6403f518ef.png differ diff --git a/2023/06/30/CSPNet/index.html b/2023/06/30/CSPNet/index.html new file mode 100644 index 0000000..4b44836 --- /dev/null +++ b/2023/06/30/CSPNet/index.html @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CSPNet | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ CSPNet +

+ + +
+ + + + +
+ + +

CSPNET: A NEW BACKBONE THAT CAN ENHANCE LEARNING CAPABILITY OF CNN

CSPNet 简介

在本文中,作者提出了跨阶段局部网络(CSPNet),用来缓解以往工作需要从网络架构角度进行大量推理计算的问题,作者把这个问题归结为网络优化中的重复梯度信息

+

作者的主要想法是通过分割梯度流,使梯度流通过不同的网络路径传播。通过切换拼接和转换,传播的梯度信息可以具有较大的相关性差异。此外,CSPNet可以大大减少计算量,并提高推理速度和准确性。除此之外,CSPNet 易于实现,并且足够通用,可以与 ResNet、ResNeXt 和 DenseNet 的体系结构相融合。

+

本文主要解决了以下的三个问题:

+
    +
  • 加强CNN的学习能力:现有的CNN网络存在经过轻量化之后的准确率大大下降的问题,现有的网络使用CSPNet的思想之后,计算量将减少10%至20%,准确率更高。
  • +
  • 消除计算瓶颈:认为过高的bottleneck会导致花费更多的时间进行推理,或部份算术单元会被闲置。所以将CNN的计算量均匀的分布在每一层,从而有效的提升每个计算单元的利用率。
  • +
  • 降低内存成本:在特征金字塔生成过程中采用了跨通道池化的方式进行特征映射。
  • +
+

CSPNet思想

    在原本DenseNet中,前面层的feature map全部传入后面层作为输入,在CSPNet中,将前面层的feature map在通道上一分为二,一部分输入到后面层,一部分直接通过short-cut的方式连接到transition层,这样可以缓解一部分的梯度信息重复计算问题,从而减少模型的计算量和显存占用。
+

CSPNet网络创新点

整体结构

img

+

传统的DenseNet中,第i层的输入与第i层的输出做concat,作为第i+1层的输入,这就要求输入和输出的分辨率保持不变,就是不做下采样操作,下采样操作在transition层进行。

+

在CSPDenseNet中,将输入特征数据在通道维度上划分为imgimg输入到DenseNet中,img直接在transition层与DenseBlock的输出在通道维度上做concat。在CSPDenseNet的transition层,先将Dense Block的输出结果img经过一个conv卷积操作,然后和img进行concat得到img,输入到另一个conv卷积操作得到img

+

上述图(b)中CSPDenseNet的前向推理过程如下:

+

img

+

参数更新过程如下:

+

img

+

经过上述改进之后,CSPDenseNet将原来DenseNet中对于全部feature map的重复梯度计算降低了一半,因为另一半x0’ 的feature map不在经过Dense Block,直接送入了transition层。所以这种网络结构叫做Cross Stage Partial DenseNet,就是跨Stage的部分的DenseNet。

+

Partial Dense Block

Partial Dense Block的设计目的为

+
    +
  • 增加梯度路径:通过拆分合并策略,可以使梯度路径的数量增加一倍。由于跨阶段策略,可以减轻使用显式特征映射复制进行连接所带来的缺点
  • +
  • 每层的平衡计算:通常,DenseNet的基础层通道数远大于增长率。由于局部密集块中涉及密集层操作的基础层通道仅占原始数量的一半,因此可以有效解决近一半的计算瓶颈
  • +
  • 减少内存流量:假设DenseNet中一个密集块的基本特征图大小为w × h × c,增长率为d,总共有m个密集层。则该密集块的CIO为$(c × m) + ((m^2 + m) × d)=2$,部分密集块的CIO为$(c × m) + (m^2 + m) × d)=2$。虽然m和d通常远小于c,但部分密集块最多可以节省网络内存流量的一半。
  • +
+

Partial Transition Layer

Partial Transition Layer的设计目的为使梯度组合的差异最大化。Partial Transition Layer是一种层次化的特征融合机制,它利用梯度流的聚合策略来防止不同的层学习重复的梯度信息。在这里,作者设计了两个CSPDenseNet变体来展示这种梯度流截断是如何影响网络的学习能力的。

+

在这里插入图片描述

+

上图中的 (c) 和 (d) 展示了两种不同的融合策略:

+

Fusion First:是将两部分生成的feature map进行拼接,然后进入过渡层。如果采用这种策略,将会损失大量的梯度信息。
Fusion Last:对于fusion last策略,来自稠密块的输出将经过过渡层,然后与来自Part1的feature map进行连接。如果采用这种策略,由于梯度流被截断,梯度信息将不会被重用。
如果我们使用上图所示的四种架构来进行图像分类,其结果如下图所示:

+

在这里插入图片描述

+

从上图可以看出,如果采用Fusion Last策略进行图像分类,计算成本明显下降,但Top-1的准确率仅下降0.1%。另一方面,CSP (fusion first)策略确实有助于显著降低计算成本,但Top-1的准确率显著下降1.5%。

+

通过使用跨阶段的分割和合并策略,我们能够有效地减少信息集成过程中重复的可能性。如果能够有效地减少重复的梯度信息,那么网络的学习能力将会得到很大的提高。

+

我们可以得到如下结论:

+
    +
  • 使用Fusion First有助于降低计算代价,但是准确率有显著下降。
  • +
  • 使用Fusion Last也是极大降低了计算代价,top-1 accuracy仅仅下降了0.1个百分点。
  • +
  • 同时使用Fusion First和Fusion Last相结合的CSP所采用的融合方式可以在降低计算代价的同时,提升准确率。
  • +
+

应用CSPNet的思想至其他网络:

img

+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_13,color_FFFFFF,t_70,g_se,x_16.png b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_13,color_FFFFFF,t_70,g_se,x_16.png new file mode 100644 index 0000000..fb907dc Binary files /dev/null and b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_13,color_FFFFFF,t_70,g_se,x_16.png differ diff --git a/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_14,color_FFFFFF,t_70,g_se,x_16.png b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_14,color_FFFFFF,t_70,g_se,x_16.png new file mode 100644 index 0000000..d4cc51f Binary files /dev/null and b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_14,color_FFFFFF,t_70,g_se,x_16.png differ diff --git a/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16-168726774348025.png b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16-168726774348025.png new file mode 100644 index 0000000..8e73dad Binary files /dev/null and b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16-168726774348025.png differ diff --git a/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16.png b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16.png new file mode 100644 index 0000000..7dcc1fc Binary files /dev/null and b/2023/06/30/CSPNet/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5aSn5rW3,size_20,color_FFFFFF,t_70,g_se,x_16.png differ diff --git a/2023/06/30/ELAN/3d05a481006d4031bc834323bbad4180.png b/2023/06/30/ELAN/3d05a481006d4031bc834323bbad4180.png new file mode 100644 index 0000000..b853bd4 Binary files /dev/null and b/2023/06/30/ELAN/3d05a481006d4031bc834323bbad4180.png differ diff --git a/2023/06/30/ELAN/628ff466598746f4ac251d9abbe94326.png b/2023/06/30/ELAN/628ff466598746f4ac251d9abbe94326.png new file mode 100644 index 0000000..dfdb0d1 Binary files /dev/null and b/2023/06/30/ELAN/628ff466598746f4ac251d9abbe94326.png differ diff --git a/2023/06/30/ELAN/index.html b/2023/06/30/ELAN/index.html new file mode 100644 index 0000000..1adcfe2 --- /dev/null +++ b/2023/06/30/ELAN/index.html @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ELAN | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ ELAN +

+ + +
+ + + + +
+ + +

(ELAN)Designing Network Design Strategies Through Gradient Path Analysis

文章作者的想法为,发现当今主流的网络设计策略大多是基于前馈路径,即基于数据路径设计网络架构。在本文中,我们希望通过提高网络学习能力来增强训练模型的表达能力。由于驱动网络参数学习的机制是反向传播算法,我们设计了基于反向传播路径的网络设计策略。提出了层级、阶段级和网络级的梯度路径设计策略。

+

背景

很多研究都是从相同的角度出发的,也就是从浅层抽取 low-level 特征,从深层抽取 high-level 特征,然后将这些特征结合起来,即是 data path(前向传播)的角度

+

本文作者的思考:

+

在这里插入图片描述如图所示,作者在 objective 和 loss 的角度分析了浅层和深层模型,作者发现通过调整 objective 和 loss layer 的配置,就可以控制每层学习到的特征(无论浅层还是深层)。
也就是说,网络学习到什么类型的特征取决于训练人员用什么信息投喂,而不是如何组合这些层,基于此,作者重新设计的网络结构

+

本文作者的出发点:

+

由于目前的参数更新方法都是反向传播规则,即目标函数会根据梯度来更新权重参数,所以本文是基于梯度传播路径来设计网络结构
本文的做法:为 layer-level、stage-level、network-level 设计了梯度路径:

+

Layer-level design:设计了梯度分流策略,并通过调整 layers 的数量和计算残差连接的 channel ratio,设计了 Partial Residual Network(PRN)(PRN 和本文是相同的作者团队)
Stage-level design:将硬件的特性引入网络结构中来加速网络的推理过程。作者通过最大化梯度结合和最小化硬件消耗的两个方式,设计了 Cross Stage Network(CSPNet)[33] (CSPNet 和本文是相同的作者团队)
Network-level design:作者考虑了梯度传播的效率来平衡网络的学习能力,以网络的梯度反传路径长度作为总基础,设计了 Efficient Layer Aggregation Network(ELAN)

+

ELAN

ELAN 的主要目标是为了解决 deep model scaling 时难以收敛的问题

+

ELAN 是由 VoVNet 和 CSPNet 结合而来的,且其整个网络的梯度长度的优化是基于 Stack in computational block 结构的

+

Stack in computational block:

+

在做模型缩放时,如果网络达到了一定的深度,再叠加深度时,网络的效果可能会不升反降

+

举个例子:

+
    +
  • scaled-YOLOv4,P7 model 使用很多操作和参数,但只获得了很小的性能提升
  • +
  • ResNet-152 约是 ResNet-50 参数量的 3 倍,但在 ImageNet 只带了了 1% 的 acc 提升,当 ResNet 堆叠到大约 200 层时,性能比 ResNet-152 更差
  • +
  • VoVNet 堆叠到 99 层时,其 acc 比 VoVNet-39 还低
  • +
+

分析:

+
    +
  • 从梯度路径的设计来看,作者认为随着堆叠层数的增加, VoVNet 比 ResNet 的性能下降更多的原因在于,VoVNet 是基于 OSA module 堆叠而来,而每个 OSA module 都包括一个 transition layer,所以每堆叠一个 OSA module,每个层的梯度路径都会增加 1
  • +
  • 而 ResNet 是基于 residual layers 堆叠而来的,每堆叠一个 residual layer,只会增加梯度最长路径
  • +
+

为了进一步分析,作者基于 YOLOR-CSP 进行了一些实验,并且发现:

+
    +
  • 当堆叠层数达到 80+ 时, CSP 早融合的方式比 normal CSP 效果更好,每个 stage 的最短梯度路径会减 1
  • +
  • 当网络继续变深和变宽,CSP 晚融合的方式得到了更好的效果,每个 layer 的最短梯度路径会减 1
  • +
+

Stack in computational block 如图 6 所示:

+
    +
  • 出发点 1:为了避免使用更多 transition layer
  • +
  • 出发点 2:让整个网络的最短梯度路径变得更长一些
  • +
+

E-LAN 结构如图 6c 所示:主要为了避免过多的使用 transition layer(会提升梯度最短路径,影响网络加深)

+

在这里插入图片描述

+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/MobileNet/099f6b5094204e1faf457ff6677f730e.png b/2023/06/30/MobileNet/099f6b5094204e1faf457ff6677f730e.png new file mode 100644 index 0000000..616733f Binary files /dev/null and b/2023/06/30/MobileNet/099f6b5094204e1faf457ff6677f730e.png differ diff --git a/2023/06/30/MobileNet/3ad597ec791743ca9fbea1f78cf0bd8d.png b/2023/06/30/MobileNet/3ad597ec791743ca9fbea1f78cf0bd8d.png new file mode 100644 index 0000000..aaa36eb Binary files /dev/null and b/2023/06/30/MobileNet/3ad597ec791743ca9fbea1f78cf0bd8d.png differ diff --git a/2023/06/30/MobileNet/3e28ca45a556474ab109a013a6efb3c2.png b/2023/06/30/MobileNet/3e28ca45a556474ab109a013a6efb3c2.png new file mode 100644 index 0000000..bc72f79 Binary files /dev/null and b/2023/06/30/MobileNet/3e28ca45a556474ab109a013a6efb3c2.png differ diff --git a/2023/06/30/MobileNet/6faa54a4ef7a4a4bb13c16196de618c8.png b/2023/06/30/MobileNet/6faa54a4ef7a4a4bb13c16196de618c8.png new file mode 100644 index 0000000..ffeb6f3 Binary files /dev/null and b/2023/06/30/MobileNet/6faa54a4ef7a4a4bb13c16196de618c8.png differ diff --git a/2023/06/30/MobileNet/721c0945ad57422da5c344f802e29d48.png b/2023/06/30/MobileNet/721c0945ad57422da5c344f802e29d48.png new file mode 100644 index 0000000..1d3b7af Binary files /dev/null and b/2023/06/30/MobileNet/721c0945ad57422da5c344f802e29d48.png differ diff --git a/2023/06/30/MobileNet/7abdcc43b7bb47c8937195e9a97f8ab3.png b/2023/06/30/MobileNet/7abdcc43b7bb47c8937195e9a97f8ab3.png new file mode 100644 index 0000000..c10d5b4 Binary files /dev/null and b/2023/06/30/MobileNet/7abdcc43b7bb47c8937195e9a97f8ab3.png differ diff --git a/2023/06/30/MobileNet/7ee519c66af94a6b9d3eb69cea3ce7bf.png b/2023/06/30/MobileNet/7ee519c66af94a6b9d3eb69cea3ce7bf.png new file mode 100644 index 0000000..5906efb Binary files /dev/null and b/2023/06/30/MobileNet/7ee519c66af94a6b9d3eb69cea3ce7bf.png differ diff --git a/2023/06/30/MobileNet/cd3017db342c44c5ae247f81d74e8413.png b/2023/06/30/MobileNet/cd3017db342c44c5ae247f81d74e8413.png new file mode 100644 index 0000000..ca8cbd6 Binary files /dev/null and b/2023/06/30/MobileNet/cd3017db342c44c5ae247f81d74e8413.png differ diff --git a/2023/06/30/MobileNet/dfc1b9f5f1c7443e85b6190eb6a8422b.png b/2023/06/30/MobileNet/dfc1b9f5f1c7443e85b6190eb6a8422b.png new file mode 100644 index 0000000..d142f60 Binary files /dev/null and b/2023/06/30/MobileNet/dfc1b9f5f1c7443e85b6190eb6a8422b.png differ diff --git a/2023/06/30/MobileNet/ed74994c96c043b086a6ef061bf0d4af.png b/2023/06/30/MobileNet/ed74994c96c043b086a6ef061bf0d4af.png new file mode 100644 index 0000000..6dcbca1 Binary files /dev/null and b/2023/06/30/MobileNet/ed74994c96c043b086a6ef061bf0d4af.png differ diff --git a/2023/06/30/MobileNet/f7310662dff144a79bce1bdccf5f90b2.png b/2023/06/30/MobileNet/f7310662dff144a79bce1bdccf5f90b2.png new file mode 100644 index 0000000..c8e92f6 Binary files /dev/null and b/2023/06/30/MobileNet/f7310662dff144a79bce1bdccf5f90b2.png differ diff --git a/2023/06/30/MobileNet/f750cdd5d58440e795006c3bee29c78c.png b/2023/06/30/MobileNet/f750cdd5d58440e795006c3bee29c78c.png new file mode 100644 index 0000000..3384975 Binary files /dev/null and b/2023/06/30/MobileNet/f750cdd5d58440e795006c3bee29c78c.png differ diff --git a/2023/06/30/MobileNet/index.html b/2023/06/30/MobileNet/index.html new file mode 100644 index 0000000..be2e031 --- /dev/null +++ b/2023/06/30/MobileNet/index.html @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MobileNet | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ MobileNet +

+ + +
+ + + + +
+ + +

MobileNet系列

MobileNetv1

贡献:

+
    +
  • 提出了深度可分离卷积,将标准卷积用逐通道卷积+逐点卷积来代替
  • +
  • 能够在边端设备使用,在保证效果的同时提升速度
  • +
+

深度可分离卷积

深度级可分离卷积其实是一种可分解卷积操作(factorized convolutions)。其可以分解为两个更小的操作:深度卷积(depthwise convolution) 和点卷积( pointwise convolution)。

+

对于一个标准卷积,输入一个$12123$的一个输入特征图,经过$ 553$的卷积核得到一个$881$的输出特征图。如果我们此时有$256$个特征图,我们将会得到一个$88256$的输出特征图,如下图所示:

+

img

+

对于深度卷积(其实就是组为1 的分组卷积)来说,将特征图通道全部进行分解,每个特征图都是单通道模式,并对每一个单独的通道特征图进行卷积操作。这样就会得到和原特征图一样通道数的生成特征图。假设输入$12123$ 的特征图,经过$5513$的深度卷积之后,得到了$88*3$的输出特征图。输入和输出的维度是不变的3,这样就会有一个问题,通道数太少,特征图的维度太少,不能够有效的获得信息。

+

img

+

逐点卷积就是$11$卷积,主要作用就是对特征图进行升维和降维。在深度卷积的过程中,我们得到了$883$的输出特征图,我们用256个$113$的卷积核对输入特征图进行卷积操作,输出的特征图和标准的卷积操作一样都是$88*256$了。如下图:

+

img

+

标准卷积与深度可分离卷积的过程对比如下:

+

img

+

深度可分离卷积的优势

对于标准卷积来说,卷积核的尺寸是$D_kD_kM$,一共有$N$个,所以标准卷积的参数量是:

+

img

+

其计算量计算如下

+

img

+

,深度可分离卷积的参数量由深度卷积和逐点卷积两部分组成。深度卷积的卷积核尺寸$D_kD_kM$;逐点卷积的卷积核尺寸为$11M$,一共有$N$个,所以深度可分离卷积的参数量是:

+

img

+

其计算量计算如下

+

img

+

网络结构

在这里插入图片描述

+

MobileNetV1 的结构如表 1 所示,下采样是使用步长为 2 的卷积实现的,共 28 层

+

在这里插入图片描述

+

MobileNetv2

贡献:

+
    +
  • 提出了倒残差结构:先 1x1 升维,使用 3x3 提取特征,最后再 1x1 降维,和残差结构的先降维后升维的结构是反的
  • +
  • 提出了线性瓶颈
  • +
+

MobileNetV2中的核心思想是,瓶颈对模型的中间输入和输出进行编码,而内层则用于封装模型从较低级别概念(如:像素等)转换到较高级别描述符(如:图像类别等)的能力。最后,与传统的剩余连接一样,快捷方式能够实现更快地训练速度和更高的准确率。

+

倒残差结构

实验发现在 MobileNetv1 中,深度卷积核的参数较多为 0,也就是其卷积核没有发挥提取特征作用。那么作者先通过 1x1 卷积将维度上升,再使用深度卷积,深度卷积的输入输出通道数更高,就能够提取更多的信息。

+

在这里插入图片描述

+
1
2
残差模块:输入首先经过1*1的卷积进行压缩,然后使用3*3的卷积进行特征提取,最后在用1*1的卷积把通道数变换回去。整个过程是“压缩-卷积-扩张”。这样做的目的是减少3*3模块的计算量,提高残差模块的计算效率。
倒残差模块:输入首先经过1*1的卷积进行通道扩张,然后使用3*3的depthwise卷积,最后使用1*1的pointwise卷积将通道数压缩回去。整个过程是“扩张-卷积-压缩”。为什么这么做呢?因为depthwise卷积不能改变通道数,因此特征提取受限于输入的通道数,所以将通道数先提升上去。文中的扩展因子为6。
+

线性瓶颈

线性瓶颈结构,就是末层卷积使用线性激活的瓶颈结构(将 ReLU 函数替换为线性函数),因为 ReLU 激活函数对低维信息会造成很大损失。

+

具体来说当低维信息映射到高维,然后经过Relu映射回低维时,若映射到的维度相对较高,则信息变换回去的损失较小;若映射到的维度相对较低,则信息变换回去后损失很大,如下图所示:

+

在这里插入图片描述

+

MobileNetv3

贡献:

+
    +
  • 使用 NAS 的方法搜寻更适合移动 CPU 的结构
  • +
  • 提出了 MobileNetV3-Large 和 MobileNetV3-Small,并引入了 h-swish 和 SE 等模块进行效果优化
  • +
+

MobileNetV3 提出的目标就是为了实现移动设备上的模型的准确率和耗时的平衡。

+
    +
  • MobileNetV1 引入了深度可分离卷积,来代替传统卷积
  • +
  • MobileNetV2 引入了线性瓶颈和反残差结构,来提升速度
  • +
  • MobileNetV3 为了 NAS 来搜寻更合适的网络,并且引入了 Swish 非线性方法的优化版本 h-swish 和 SE 模块,建立更高效的网络
  • +
+

网络优化

    +
  • 修改初始卷积核的个数
      +
    • 对于v2的输入层,通过3*3卷积将输入扩张成32维。作者发现,其实可以32再降低一点,所以这里改成了16,在保证了精度的前提下,降低了3ms的速度。关于这一点改变可以在最后给出的网络结构中看到
    • +
    +
  • +
  • 更改网络末端计算量大的层
  • +
  • 引入了SE模块
  • +
  • H-Swish激活函数
  • +
+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/RegVGG/4H7{5]]_TNU%XI%5PPH9KA9.png b/2023/06/30/RegVGG/4H7{5]]_TNU%XI%5PPH9KA9.png new file mode 100644 index 0000000..ad1c97d Binary files /dev/null and b/2023/06/30/RegVGG/4H7{5]]_TNU%XI%5PPH9KA9.png differ diff --git a/2023/06/30/RegVGG/aa1ad31949b54e76b0a282fab915478f.png b/2023/06/30/RegVGG/aa1ad31949b54e76b0a282fab915478f.png new file mode 100644 index 0000000..ab73da2 Binary files /dev/null and b/2023/06/30/RegVGG/aa1ad31949b54e76b0a282fab915478f.png differ diff --git a/2023/06/30/RegVGG/index.html b/2023/06/30/RegVGG/index.html new file mode 100644 index 0000000..bb138cb --- /dev/null +++ b/2023/06/30/RegVGG/index.html @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RegVGG | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ RegVGG +

+ + +
+ + + + +
+ + +

RepVGG: Making VGG-style ConvNets Great Again

主要贡献:提出了一种简单但功能强大的卷积神经网络结构,其网络结构,在推理时只具有3x3卷积和ReLU,在训练时具有多分支拓扑结构,通过结构重参数化技术实现训练时间和推理时间的解耦,并命名为RepVGG。

+

对于较为复杂的网络(ResNet的残差块以及Inception的分支连接),其精度往往较好,但其本身存在的问题如下:

    +
  • 会降低模型的推理速度并且减少内存利用率
  • +
  • 有些节点及算子会增加内存消耗并且对别的设备不友好。
  • +
+

论文中提到,大部分学者提到FLOPs(浮点运算的数量)会影响推理速度,但是论文中作者做了实验发现FLOPs对模型的速度并不是强相关。

+

作者提出的RepVGG,其具有以下优点:

+
    +
  • 该模型具有类似VGG的拓扑结构,没有任何分支,这意味着每一层都将其唯一前一层的输出作为输入,并将输出馈送到其唯一的后一层。
  • +
  • 该模型的主体部分仅使用3 × 3的conv和ReLU。
  • +
  • 模型的具体架构(包括具体的深度和层宽度)的实例化没有模型结构的自动搜索,手工细化,复合缩放,也没有其他代价较大的设计。
  • +
+

作者认为,多分支架构可以看作为许多较浅模型的隐式集成,并且具有较好的性能水平。

针对多分支架构的优点集中于训练上,而不希望用于推理上,故提出重参数化的方法来解耦训练时的多分支结构和推理时的简单架构,即意味着通过转换其参数将架构从一个转换到另一个。

+

img

+

如上图中(b)和(c)所示,即为转换之后的RepVGG和转换之前的RepVGG。其将分支看作退化的1x1卷积,进一步看作退化的3x3卷积。从而可以从(b)中的模型架构转变为(c)中的模型架构,可以用3x3卷积、BN、1x1卷积等模块进行原模型的等效替换。从而提升计算速度。

+

本文的核心贡献点如下:

    +
  • 我们提出了RepVGG,这是一种简单的架构,与最先进的技术相比,具有良好的速度-精度权衡。
  • +
  • 我们建议使用结构重参数化将训练时间的多分支拓扑与推理时间的平面结构解耦。
  • +
  • 我们展示了RepVGG在图像分类和语义分割方面的有效性,以及实现的效率和易用性。
  • +
+

如何实现结构重参数化:

在上述提到,RepVGG在训练时每一层都有三个分支,分别是identify,1x1,3x3,模型训练时,输出$ y=x+g(x)+f(x) $,每一层就需要3个参数块,对于n层网络,就需要$3*n$个参数块。所以我们需要重参数化,会使得推理时模型参数量小。

+

img

+

上图中的过程即为将训练好的多分支模型转换为单分支模型,从而达到推理时的高性能

+
1
2
3
对于重参数化的实现主要存在两个问题:
第一个问题,在每个卷积后都接上一个BN,怎么将卷积和BN融合。
第二个问题,存在不同大小的卷积,怎么将几个不同大小的卷积融合在一起。
+

对于第一个问题,在每个卷积后都接上一个BN,怎么将卷积和BN融合。

+

v2-84cdab58644fcbcafb3c690c1669b879_1440w

+

这其实就是一个卷积层,只不过权重考虑了BN的参数 我们令:

+

img

+

最终的融合结果即为:

+

img

+

2.2.2. conv_3x3和conv_1x1合并

这里为了详细说明下,假设输入特征图特征图尺寸为(1, 2, 3, 3),输出特征图尺寸与输入特征图尺寸相同,且stride=1,下面展示是conv_3x3的卷积过程:

+

img

+

conv_3x3卷积过程大家都很熟悉,看上图一目了然,首先将特征图进行pad=kernel_size//2,然后从左上角开始(上图中红色位置)做卷积运算,最终得到右边output输出。下面是conv_1x1卷积过程:

+

img

+

同理,conv_1x1跟conv_3x3卷积过程一样,从上图中左边input中红色位置开始进行卷积,得到右边的输出,观察conv_1x1和conv_3x3的卷积过程,可以发现他们都是从input中红色起点位置开始,走过相同的路径,因此,将conv_3x3和conv_1x1进行融合,只需要将conv_1x1卷积核padding成conv_3x3的形式,然后于conv_3x3相加,再与特征图做卷积(这里依据卷积的可加性原理)即可,也就是conv_1x1的卷积过程变成如下形式:

+

img

+

2.2.3. identity 等效为特殊权重的卷积层

identity层就是输入直接等于输出,也即input中每个通道每个元素直接输出到output中对应的通道,用一个什么样的卷积层来等效这个操作呢,我们知道,卷积操作必须涉及要将每个通道加起来然后输出的,然后又要保证input中的每个通道每个元素等于output中,从这一点,我们可以从PWconv想到,只要令当前通道的卷积核参数为1,其余的卷积核参数为0,就可以做到;从DWconv中可以想到,用conv_1x1卷积且卷积核权重为1,就能保证每次卷积不改变输入,因此,identity可以等效成如下的conv_1x1的卷积形式:

+

img

+

从上面的分析,我们进一步可以将indentity -> conv_1x1 -> conv_3x3的形式,如下所示:

+

img

+

上述过程就是对应论文中所属的下述从step1到step2的变换过程,涉及conv于BN层融合,conv_1x1与identity转化为等价的conv_3x3的形式:

+

img

+

结构重参数化的最后一步也就是上图中step2 -> step3, 这一步就是利用卷积可加性原理,将三个分支的卷积层和bias对应相加组成最终一个conv3x3的形式即可。
这里,大家可能既然把BN,identity,conv_1x1和conv_3x3都融合在一起了,为什么不干脆把ReLU也融合进去呢?其实也是可以将ReLU层进行融合的,但是需要进行量化conv输出tensor的值域直接使用relu输出的值阈(同时对应计算S和Z),就可以完成conv和relu合并。无量化动作的优化是无法完成conv+relu的合并*。这里的知识请大家参考论文:
*Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference

+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/RegVGG/v2-84cdab58644fcbcafb3c690c1669b879_1440w.webp b/2023/06/30/RegVGG/v2-84cdab58644fcbcafb3c690c1669b879_1440w.webp new file mode 100644 index 0000000..30c64ae Binary files /dev/null and b/2023/06/30/RegVGG/v2-84cdab58644fcbcafb3c690c1669b879_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-88962d2f0fc8f1371d0d521c04c2a57d_1440w.webp b/2023/06/30/RegVGG/v2-88962d2f0fc8f1371d0d521c04c2a57d_1440w.webp new file mode 100644 index 0000000..88eec4e Binary files /dev/null and b/2023/06/30/RegVGG/v2-88962d2f0fc8f1371d0d521c04c2a57d_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-89854f076457c9c03b733a389db96993_1440w.webp b/2023/06/30/RegVGG/v2-89854f076457c9c03b733a389db96993_1440w.webp new file mode 100644 index 0000000..372ecce Binary files /dev/null and b/2023/06/30/RegVGG/v2-89854f076457c9c03b733a389db96993_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-b05e6fa96bd642c1da2d36d39a543d7a_1440w.webp b/2023/06/30/RegVGG/v2-b05e6fa96bd642c1da2d36d39a543d7a_1440w.webp new file mode 100644 index 0000000..a7c55e9 Binary files /dev/null and b/2023/06/30/RegVGG/v2-b05e6fa96bd642c1da2d36d39a543d7a_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-b438e3a2ee316a6054a4e4c45443fef3_1440w.webp b/2023/06/30/RegVGG/v2-b438e3a2ee316a6054a4e4c45443fef3_1440w.webp new file mode 100644 index 0000000..1fea7f0 Binary files /dev/null and b/2023/06/30/RegVGG/v2-b438e3a2ee316a6054a4e4c45443fef3_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-b7409c315f10a158331bf90fcf32efd6_1440w.webp b/2023/06/30/RegVGG/v2-b7409c315f10a158331bf90fcf32efd6_1440w.webp new file mode 100644 index 0000000..955b921 Binary files /dev/null and b/2023/06/30/RegVGG/v2-b7409c315f10a158331bf90fcf32efd6_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-bc97e575d5007645901830109828a36f_1440w.webp b/2023/06/30/RegVGG/v2-bc97e575d5007645901830109828a36f_1440w.webp new file mode 100644 index 0000000..8b8af4d Binary files /dev/null and b/2023/06/30/RegVGG/v2-bc97e575d5007645901830109828a36f_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-cd0d2de067e4850fe4fafce70f58acf1_1440w.webp b/2023/06/30/RegVGG/v2-cd0d2de067e4850fe4fafce70f58acf1_1440w.webp new file mode 100644 index 0000000..c18fd59 Binary files /dev/null and b/2023/06/30/RegVGG/v2-cd0d2de067e4850fe4fafce70f58acf1_1440w.webp differ diff --git a/2023/06/30/RegVGG/v2-f5ce0b89a10aa36223275dccd6327cbe_1440w.webp b/2023/06/30/RegVGG/v2-f5ce0b89a10aa36223275dccd6327cbe_1440w.webp new file mode 100644 index 0000000..c6e7a0c Binary files /dev/null and b/2023/06/30/RegVGG/v2-f5ce0b89a10aa36223275dccd6327cbe_1440w.webp differ diff --git a/2023/06/30/ShuffleNet/0ddfad3d997b42c1a675fa533f4645b2.png b/2023/06/30/ShuffleNet/0ddfad3d997b42c1a675fa533f4645b2.png new file mode 100644 index 0000000..5555a1a Binary files /dev/null and b/2023/06/30/ShuffleNet/0ddfad3d997b42c1a675fa533f4645b2.png differ diff --git a/2023/06/30/ShuffleNet/index.html b/2023/06/30/ShuffleNet/index.html new file mode 100644 index 0000000..3f46777 --- /dev/null +++ b/2023/06/30/ShuffleNet/index.html @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ShuffleNet | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ ShuffleNet +

+ + +
+ + + + +
+ + +

ShuffleNet系列

ShuffleNetv1

现有网络的问题:

+

现有的高效结构如 Xception 和 ResNeXt,其实在极小的网络上的计算效率依然不太高,主要在于很耗费计算量的 1x1 卷积。

+

ShuffleNet 如何解决:使用 point-wise 分组卷积和 channel shuffle 两个操作,很好的降低计算量并保持准确率。这种结构能够允许网络使用更多的通道,帮助 encode 阶段提取更多的信息,这点对极小的网络非常关键。

+
    +
  • 使用 point-wise 卷积来降低 1x1 卷积的计算量
  • +
  • 使用 channel shuffle 能够让不同通道的信息进行交互
  • +
+

这里再介绍几个基本概念:

+

分组卷积:AlexNet 中提出的概念,在 ResNeXt 中有使用,也就是将特征图分为 N 个组,每组分别进行卷积,然后将卷积结果 concat 起来
深度可分离卷积:和 MobileNet 中都有使用,也就是每个特征图使用一个卷积核来提取特征,之后使用 1x1 的卷积进行通道间的特征融合
channel shuffle:shuffle 可以翻译为重新洗牌,也就是把不同组的 channel 再细分一下,打乱重新分组
模型加速:加速推理时候的速度,如剪枝、量化

+

在这里插入图片描述

+

ShuffleNet的亮点

    +
  • 结合\Group convolutions**\Channel Shuffle**
  • +
+

group conv的问题:现在的精简CNN网络设计中使用Group convolutions已经成为一种趋势,它可有效地减少传统CNN所需的密集计算的运算量。但同时由于Groups之间彼此并不share feature map特征,这样就会导致每个filter只对限定的一部分输入特征可见,最终使得输出特征集合的表达能力大大降低。

+

本文改进点:为了有效地对冲Groups convolution使用导致的Groups间特征互不相通的负面影响,作者提出了对Group convolution计算后对输出的output feature maps进行\shuffle处理**,以使得接下来的Group convolution filters可在每个group所输出的部分channels构成的集合上进行计算。

+

ShuffleNetv2

贡献:

+
    +
  • 提出了更应该使用直接的效率度量方法(如速度、耗时等)
  • +
  • 在 V1 的 channel shuffle 的基础上,又提出了 channel split,增强特征的重用性的同时也减少了计算量
  • +
  • 提出了设计高效网络的方法:
      +
    • 使用输入输出通道相同的卷积
    • +
    • 了解使用分组卷积的代价(分组越多,MAC 越大)
    • +
    • 合理的设定分组个数
    • +
    • 降低网络并行的分支(并行越多 MAC 越大)
    • +
    • 减少逐点运算
    • +
    +
  • +
+

ShuffleNetV2 首先提出了 4 条设计高效网络的方法:

+
    +
  • G1:Equal channel width minimizes memory access cost (MAC):当卷积层的输入特征矩阵与输出特征矩阵 channel 相等时 MAC 最小 (保持FLOPs不变时)
  • +
  • G2: Excessive group convolution increases MAC:当 GConv 的 groups 增大时(保持FLOPs不变时),MAC 也会增大,所以建议针对不同的硬件和需求,更好的设计对应的分组数,而非盲目的增加
  • +
  • G3: Network fragmentation reduces degree of parallelism:网络设计的碎片化程度(或者说并行的分支数量)越高,速度越慢(Appendix Fig 1)
  • +
  • G4:Element-wise operations are non-negligible:Element-wise操作,即逐点运算,带来的影响是不可忽视的,轻量级模型中,元素操作占用了相当多的时间,特别是在GPU上。这里的元素操作符包括 ReLU、AddTensor、AddBias 等。将 depthwise convolution 作为一个 element-wise operator,因为它的 MAC/FLOPs 比率也很高
  • +
+

基于上面4条指导准则总结如下:

+
    +
  • 1x1卷积进行平衡输入和输出的通道大小;
  • +
  • 组卷积要谨慎使用,注意分组数;
  • +
  • 避免网络的碎片化;
  • +
  • 减少元素级运算。
  • +
+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/VovNet/4c2143990db24da7be3fa4c43c96dd82.png b/2023/06/30/VovNet/4c2143990db24da7be3fa4c43c96dd82.png new file mode 100644 index 0000000..1263bcc Binary files /dev/null and b/2023/06/30/VovNet/4c2143990db24da7be3fa4c43c96dd82.png differ diff --git a/2023/06/30/VovNet/index.html b/2023/06/30/VovNet/index.html new file mode 100644 index 0000000..0621f25 --- /dev/null +++ b/2023/06/30/VovNet/index.html @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VovNet | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+ + + + + +
+

+ VovNet +

+ + +
+ + + + +
+ + +

VoVNet:An Energy and GPU-Computation Efficient Backbone Network for Real-Time Object Detection

大体介绍及缘由

因为 DenseNet 通过用密集连接,来聚合具有不同感受野大小的中间特征,因此它在对象检测任务上表现出良好的性能。虽然特征重用(feature reuse)的使用,让 DenseNet 以少量模型参数和 FLOPs,也能输出有力的特征,但是使用 DenseNet 作为 backbone 的目标检测器却表现出了运行速度慢和效率低下的弊端。作者认为是密集连接(dense connection)带来的输入通道线性增长,从而导高内存访问成本和能耗。

+

为了提高 DenseNet 的效率,作者提出一个新的更高效的网络 VoVet,由 OSAOne-Shot Aggregation,一次聚合)组成。OSA 仅在模块的最后一层聚合前面所有层的特征,这种结构不仅继承了 DenseNet 的多感受野表示多种特征的优点,也解决了密集连接效率低下的问题。基于 VoVNet 的检测器不仅速度比 DenseNet 快 2 倍,能耗也降低了 1.5-4.1 倍。另外,VoVNet 网络的速度和效率还优于 ResNet,并且其对于小目标检测的性能有了显著提高。

+

DenseNet和VoVNet之间的区别,大体上可以如下图所示:

+

img

+

贡献:

    +
  • 讨论了 MAC 和 GPU 计算的效率,并研究了如何设计更高效的结构

    +
  • +
  • 抛出了 DenseNet 网络结构中的问题,包括低效的、冗余的操作等

    +
  • +
  • 提出了 One-shot Aggregation(OSA),将中间的特征一次性聚合(在最后一层聚合一次),如图 1b 所示,能够在

    +

    保留 concat 优势的同时优化 MAC(中间层输入输出通道相同) 和 GPU 计算效率(无需 1x1 卷积)

    +
  • +
  • 基于 OSA 模块,构建了 VoVNet,一个 backbone 网络结构,并且将该 backbone 用于 DSOD、RefineDet、Mask R-CNN 等方法中,取得了比 DenseNet、ResNet 等方法更好的效率和准确率的平衡

    +
  • +
+

proposed method

重新思考密集连接

DenseNet 的优点

+

在计算第 $l$ 层的输出时,要用到之前所有层的输出的 concat 的结果。这种密集的连接使得各个层的各个尺度的特征都能被提取,供后面的网络使用。这也是它能得到比较高的精度的原因,而且密集的连接更有利于梯度的回传(ResNet shorcut 操作的加强版)。

+

DenseNet 缺点(导致了能耗和推理效率低的):

+
    +
  • 密集连接会增加输入通道大小,但输出通道大小保持不变,导致的输入和输出通道数都不相等。因此,DenseNet 具有具有较高的 MAC。
  • +
  • DenseNet 采用了 bottleneck 结构,这种结构将一个 3×3 卷积分成了两个计算(1x1+3x3 卷积),这带来了更多的序列计算(sequential computations),导致会降低推理速度。
  • +
+
+

密集连接会导致计算量增加,所以不得不采用 1×1 卷积的 bottleneck 结构。

+
+

One-shot Aggregation

OSA 模块就是只聚合每个 block 的最后一层特征,也就是在每个 block 的最后一层,对该 block 的前面所有层的特征进行 concat,只进行这一次的聚合。

+

该模块将中间层的特征聚合到最后一层。如图所示。每个卷积层包含双向连接,一个连接到下一层以产生具有更大感受野的特征,而另一个仅聚合到最终输出特征映射。

+

在这里插入图片描述

+
    +
  • 首先,在和 DenseNet-40 的 dense block 参数和计算量相似的基础上,设计 OSA module
  • +
  • 先使用层数相同的方式,随着每个卷积层输入尺度的减小,OSA 的输出比 dense block 的输出更大,OSA 模块的网络得到 93.6% acc,比同量级的 ResNet 效果好,由此可见,只在最后一层进行特征聚合,比使用全部中间层聚合更好
  • +
  • OSA 的 transition layer 和 DenseNet 有较大不同,OSA 中,从浅层来的特征对 transition layer 更有效,因为深层特征对 transition layer 没有很大的影响
  • +
  • 所以,将 OSA module 降为使用 5 层(共 43 通道),如图 2 最下边一行,得到了 5.44% err,和 DenseNet-40 的 5.24% 很接近,这说明使用大量的中间层的密集连接是低效且没有很大的作用
  • +
  • 在检测任务上,使用 5 层 43 通道的 OSA module 可以将 MAC 从 3.7M 降低到 2.5M,这是因为 OSA 的中间层输入输出通道是相同的,使得MAC 最低,此外,因为检测任务比分类任务使用更大分辨率的特征图,MAC 会更严重的影响耗时和效率
  • +
+

总之,OSA 能够提升 GPU 是计算效率,OSA 中间层的输入输出通道数相同,也不大需要使用 1x1 瓶颈层来降维,所以,OSA 层数更少、更高效

+

OSA 与 DenseNet 的不同之处总结如下:

    +
  • 每一层的输出并没有按路线(route)到所有后续的中间层,这使得中间层的输入大小是恒定的。这样就提高了 GPU 的计算效率。
  • +
  • 另外一个不同之处在于没有了密集连接,因此 MAC 比 DenseNet 小得多
  • +
  • 此外,由于 OSA 模块聚集了浅层特征,它包含的层更少。因此,OSA 模块被设计成只有几层,可以在 GPU 中高效计算。
  • +
+ +
+ + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2023/06/30/VovNet/v2-06f9e7e6761c98f4f554cb5aabe9cab2_1440w.webp b/2023/06/30/VovNet/v2-06f9e7e6761c98f4f554cb5aabe9cab2_1440w.webp new file mode 100644 index 0000000..56b506c Binary files /dev/null and b/2023/06/30/VovNet/v2-06f9e7e6761c98f4f554cb5aabe9cab2_1440w.webp differ diff --git a/archives/2022/03/index.html b/archives/2022/03/index.html index 4210ff8..c055449 100644 --- a/archives/2022/03/index.html +++ b/archives/2022/03/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -331,7 +332,7 @@

凯_kaiii

diff --git a/archives/2022/04/index.html b/archives/2022/04/index.html index c480340..2a6c0a0 100644 --- a/archives/2022/04/index.html +++ b/archives/2022/04/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -251,7 +252,7 @@

凯_kaiii

diff --git a/archives/2022/07/index.html b/archives/2022/07/index.html index 5d32135..83ca922 100644 --- a/archives/2022/07/index.html +++ b/archives/2022/07/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -291,7 +292,7 @@

凯_kaiii

diff --git a/archives/2022/08/index.html b/archives/2022/08/index.html index 4cd13a9..4a29b1e 100644 --- a/archives/2022/08/index.html +++ b/archives/2022/08/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -351,7 +352,7 @@

凯_kaiii

diff --git a/archives/2022/index.html b/archives/2022/index.html index e09deb4..21f21f8 100644 --- a/archives/2022/index.html +++ b/archives/2022/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -434,7 +435,7 @@

凯_kaiii

diff --git a/archives/2022/page/2/index.html b/archives/2022/page/2/index.html index 6aec3e0..ea10b42 100644 --- a/archives/2022/page/2/index.html +++ b/archives/2022/page/2/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -334,7 +335,7 @@

凯_kaiii

diff --git a/archives/2023/03/index.html b/archives/2023/03/index.html index 2279aca..e40e6f5 100644 --- a/archives/2023/03/index.html +++ b/archives/2023/03/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -271,7 +272,7 @@

凯_kaiii

diff --git a/archives/2023/04/index.html b/archives/2023/04/index.html index daa28fe..853dc05 100644 --- a/archives/2023/04/index.html +++ b/archives/2023/04/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -331,7 +332,7 @@

凯_kaiii

diff --git a/archives/2023/06/index.html b/archives/2023/06/index.html index d2ab8af..c4ba911 100644 --- a/archives/2023/06/index.html +++ b/archives/2023/06/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -159,6 +160,126 @@

凯_kaiii

2023
+ + + + + + + + + + + +
@@ -291,7 +412,7 @@

凯_kaiii

diff --git a/archives/2023/index.html b/archives/2023/index.html index aee76f9..6c2915c 100644 --- a/archives/2023/index.html +++ b/archives/2023/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -164,15 +165,15 @@

凯_kaiii

-
@@ -184,15 +185,15 @@

凯_kaiii

-
@@ -204,15 +205,15 @@

凯_kaiii

-
@@ -224,15 +225,15 @@

凯_kaiii

-
@@ -244,15 +245,15 @@

凯_kaiii

-
@@ -264,15 +265,15 @@

凯_kaiii

-
@@ -284,15 +285,15 @@

凯_kaiii

-
@@ -304,15 +305,15 @@

凯_kaiii

-
@@ -324,15 +325,15 @@

凯_kaiii

-
@@ -344,15 +345,15 @@

凯_kaiii

-
@@ -367,6 +368,9 @@

凯_kaiii

+ @@ -431,7 +435,7 @@

凯_kaiii

diff --git a/archives/2023/page/2/index.html b/archives/2023/page/2/index.html new file mode 100644 index 0000000..4c4dfed --- /dev/null +++ b/archives/2023/page/2/index.html @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 归档 | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+ + 还行! 目前共计 31 篇日志。 继续努力。 +
+ + +
+ 2023 +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/archives/index.html b/archives/index.html index 201abdb..dbb3084 100644 --- a/archives/index.html +++ b/archives/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -164,15 +165,15 @@

凯_kaiii

-
@@ -184,15 +185,15 @@

凯_kaiii

-
@@ -204,15 +205,15 @@

凯_kaiii

-
@@ -224,15 +225,15 @@

凯_kaiii

-
@@ -244,15 +245,15 @@

凯_kaiii

-
@@ -264,15 +265,15 @@

凯_kaiii

-
@@ -284,15 +285,15 @@

凯_kaiii

-
@@ -304,15 +305,15 @@

凯_kaiii

-
@@ -324,15 +325,15 @@

凯_kaiii

-
@@ -344,15 +345,15 @@

凯_kaiii

-
@@ -368,7 +369,7 @@

凯_kaiii

@@ -434,7 +435,7 @@

凯_kaiii

diff --git a/archives/page/2/index.html b/archives/page/2/index.html index 30e91b8..a4057f6 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -151,12 +151,13 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
- 2022 + 2023
@@ -164,15 +165,15 @@

凯_kaiii

-
@@ -184,15 +185,15 @@

凯_kaiii

-
@@ -204,15 +205,15 @@

凯_kaiii

-
@@ -224,15 +225,15 @@

凯_kaiii

-
@@ -244,15 +245,15 @@

凯_kaiii

-
@@ -264,35 +265,38 @@

凯_kaiii

-
+
+ 2022 +
-
@@ -304,15 +308,15 @@

凯_kaiii

-
@@ -324,15 +328,15 @@

凯_kaiii

-
@@ -344,15 +348,15 @@

凯_kaiii

-
@@ -368,7 +372,7 @@

凯_kaiii

@@ -434,7 +438,7 @@

凯_kaiii

diff --git a/archives/page/3/index.html b/archives/page/3/index.html index 438ebab..6b126fe 100644 --- a/archives/page/3/index.html +++ b/archives/page/3/index.html @@ -151,7 +151,8 @@

凯_kaiii

- 嗯..! 目前共计 25 篇日志。 继续努力。 + + 还行! 目前共计 31 篇日志。 继续努力。
@@ -164,15 +165,15 @@

凯_kaiii

-
@@ -184,15 +185,115 @@

凯_kaiii

+ +
+ +
+ +
+
+ + + + + + + + + +
+
+ +
-
@@ -204,15 +305,15 @@

凯_kaiii

-
@@ -224,15 +325,15 @@

凯_kaiii

-
@@ -244,15 +345,15 @@

凯_kaiii

-
@@ -268,7 +369,7 @@

凯_kaiii

@@ -334,7 +435,7 @@

凯_kaiii

diff --git a/archives/page/4/index.html b/archives/page/4/index.html new file mode 100644 index 0000000..1a3326a --- /dev/null +++ b/archives/page/4/index.html @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 归档 | 凯_kaiii + + + + + + + + + + + + +
+
+ +
+
+ + +
+ + + +

凯_kaiii

+ +
+

暂无

+
+ + +
+ + + + + + + + + +
+
+ + +
+ + 0% +
+ + +
+
+
+ + +
+ + + + + +
+
+
+ + 还行! 目前共计 31 篇日志。 继续努力。 +
+ + +
+ 2022 +
+ + + + +
+
+ + + + + + + + + +
+ + + + +
+ + + + + + + + +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html index 138c56f..7296bf9 100644 --- a/index.html +++ b/index.html @@ -148,7 +148,7 @@

凯_kaiii

- +
- - - - - - - -
- - - - - -
-

- - -

- - -
- - - - -
- - -

ffmpeg是什么

FFmpeg是一个库和工具的集合,用于处理音频、视频、字幕和相关元数据等多媒体内容。

-

ffmpeg的组成

ffmpeg由以下几个核心依赖包组成

-
    -
  • libavcodec - 提供了更广泛的编码器解码器的实现。各种格式的编解码代码(如aacenc.c、aacdec.c等)都位于该目录下。
  • -
  • libavformat - 实现了流协议、容器格式和基本的I/O实现。用于各种音视频封装格式的生成和解析,包括获取解码所需信息、读取音视频数据等功能。各种流媒体协议代码(如rtmpproto.c等)以及音视频格式的(解)复用代码(如flvdec.c、flvenc.c等)都位于该目录下。
  • -
  • libavutil - 为核心工具包,包含一些公共的工具函数的使用库,包括算数运算,字符操作等。
  • -
  • libavfilter - 提供各种音视频滤波器。
  • -
  • libavdevice - 用于硬件的音视频采集、加速和显示。
  • -
  • libswresample - 提供音频重采样,采样格式转换和音频混合等功能。
  • -
  • libswscale - 提供原始视频的比例缩放、色彩映射转换、图像颜色空间或格式转换的功能。
  • -
-

ffmpeg用到的工具

    -
  • ffmpeg是一个用于操作、转换和流式传输多媒体内容的命令行工具箱。
  • -
  • ffplay是一款简约的多媒体播放器。
  • -
  • ffprobe是一种检查多媒体内容的简单分析工具。
  • -
  • 其他小工具,如”aviocat”、”ismindex”和”qt faststart”。
  • -
-

ffmpeg的源码编译

ffmpeg的源码下载 以ffmpeg release 6.0为例

1
git clone https://github.com/FFmpeg/FFmpeg/tree/release/6.0
-

yasm的安装

由于ffmpeg的安装过程中为了提高效率使用了汇编指令,而yasm是汇编编译器,在ffmpeg的编译过程中对其有依赖,所以需要对其提前进行下载安装。

-

linux环境下直接:

- -

ffmpeg的源码编译

进入ffmpeg的源码文件夹。

-
1
2
3
4
./configure --prefix=/usr/local/ffmpeg
make && make install
vi /etc/profile
export PATH=$PATH:/usr/local/ffmpeg/bin
-

ffmpeg的安装测试

在命令行中直接输入ffmpeg,得到ffmpeg相关的信息输出即可。

-

常见使用方法

具体详细版的ffmpeg文档可见: ffmpeg中文文档

-

统一语法

1
ffmpeg [全局选项] {[输入文件选项] -i 输入文件} ... {[输出文件选项] 输出文件} ...
-

-
1
ffmpeg [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ...
-

基本选项

能力集列表

-
    -
  • -formats:列出支持的文件格式。
  • -
  • -codecs:列出支持的编解码器。
  • -
  • -decoders:列出支持的解码器。
  • -
  • -encoders:列出支持的编码器。
  • -
  • -protocols:列出支持的协议。
  • -
  • -bsfs:列出支持的比特流过滤器。
  • -
  • -filters:列出支持的滤镜。
  • -
  • -pix_fmts:列出支持的图像采样格式。
  • -
  • -sample_fmts:列出支持的声音采样格式。
  • -
-

常用输入选项

-
    -
  • -i filename:指定输入文件名。
  • -
  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
  • -
  • -ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。
  • -
-

对于输入,以下选项通常是自动识别的,但也可以强制设定。

-
    -
  • -c codec:指定解码器,需使用能力集列表中的名称。
  • -
  • -acodec codec:指定声音的解码器,需使用能力集列表中的名称。
  • -
  • -vcodec codec:指定视频的解码器,需使用能力集列表中的名称。
  • -
  • -b:v bitrate:设定视频流的比特率,整数,单位bps。
  • -
  • -r fps:设定视频流的帧率,整数,单位fps。
  • -
  • -s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。
  • -
  • -pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。
  • -
  • -ar sample rate:设定音频流的采样率,整数,单位Hz。
  • -
  • -ab bitrate:设定音频流的比特率,整数,单位bps。
  • -
  • -ac channels:设置音频流的声道数目。
  • -
-

常用输出选项

-
    -
  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
  • -
  • -c codec:指定编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
  • -
  • -acodec codec:指定声音的编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
  • -
  • -vcodec codec:指定视频的编码器,需使用能力集列表中的名称(编解码器设定为”copy“表示不进行编解码)。
  • -
  • -r fps:设定视频编码器的帧率,整数,单位fps。
  • -
  • -pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。
  • -
  • -ar sample rate:设定音频编码器的采样率,整数,单位Hz。
  • -
  • -b bitrate:设定音视频编码器输出的比特率,整数,单位bps。
  • -
  • -ab bitrate:设定音频编码器输出的比特率,整数,单位bps。
  • -
  • -ac channels:设置音频编码器的声道数目。
  • -
  • -an 忽略任何音频流。
  • -
  • -vn 忽略任何视频流。
  • -
  • -t hh:mm:ss[.xxx]:设定输出文件的时间长度。
  • -
  • -to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的画可以设定终止时间点。
  • -
-

ffmpeg音视频转换流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 _______              ______________
| | | |
| input | demuxer | encoded data | decoder
| file | ---------> | packets | -----+
|_______| |______________| |
v
_________
| |
| decoded |
| frames |
|_________|
________ ______________ |
| | | | |
| output | <-------- | encoded data | <----+
| file | muxer | packets | encoder
|________| |______________|
-

ffmpeg调用libavformat库(含分离器demuxer)读取输入文件,分离出各类编码的数据包(流)。编码数据包通过解码器解码出非压缩的数据帧(raw视频/PCM格式音频…),这些数据帧可以被滤镜进一步处理。经过滤镜处理的数据被重新编码为新的数据包(流),然后经过混合器混合(例如按一定顺序和比例把音频数据包和视频数据包交叉组合),写入到输出文件。

-

滤镜处理(Filtering)

在上述音视频转换流程中,decoder得到原始音视频数据之后,可以使用libavfilter库中的滤镜进行处理,滤镜之间可以组合使用filtergraphs ,对于ffmpeg而言,滤镜分为简单滤镜复合滤镜

-

简单滤镜

简单滤镜即为只有一个输入和输出的滤镜,且滤镜两边的数据为同一类型的数据,可以理解为从raw data到encoder处理之前简单附加的一步。其具体流程可如下所示:

-
1
2
3
4
5
6
7
8
9
10
 _________                        ______________
| | | |
| decoded | | encoded data |
| frames |\ | packets |
|_________| \ /||______________|
\ __________ /
simple \ | | / encoder
filtergraph \| filtered |/
| frames |
|__________|
-

tips:滤镜改变的不止可以为帧内容,还可以是帧属性。例如帧率的变化,尺寸的变化等。对应于帧内容并不发生改变。

-

复合滤镜

不为简单滤镜的行为均可视为复合滤镜,例如多个输入多个输出的场景,示意图如下:

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 _________
| |
| input 0 |\ __________
|_________| \ | |
\ _________ /| output 0 |
\ | | / |__________|
_________ \| complex | /
| | | |/
| input 1 |---->| filter |\
|_________| | | \ __________
/| graph | \ | |
/ | | \| output 1 |
_________ / |_________| |__________|
| | /
| input 2 |/
|_________|
-

复合滤镜由-filter_complex选项进行设定。注意这是一个全局选项,因为一个复合滤镜必然是不能只关联到一个单一流或者文件的。-lavfi选项等效于-filter_complex

-

一个复合滤镜的简单例子就是overlay滤镜,它从两路输入中,把一个视频叠加到一个输出上。对应的类似音频滤镜是amix

-

流拷贝

流拷贝(Stream copy)是一种对指定流数据仅仅进行复制的拷贝(copy)模式。这种情况下ffmpeg不会对指定流进行解码和编码步骤,而仅仅是分离和混合数据包。这种模式常用于文件包装格式的转换或者修改部分元数据信息,这个过程简单图示如下:

-
-
1
2
3
4
5
_______              ______________            ________
| | | | | |
| input | demuxer | encoded data | muxer | output |
| file | ---------> | packets | -------> | file |
|_______| |______________| |________|
-
-

因为这种模式下不存在解码和编码过程,所以也特别快,而且不会造成新的质量损失。然而这也使得这样的模式不能适合很多工作需求,例如这个模式下不能使用大量的滤镜了,因为滤镜仅能对未压缩(编码)的数据进行处理。

-

4.1流处理

默认情况下,ffmpeg把输入文件每种类型(视频、音频和字幕)仅仅采用一个流转换输出到输出文件中,就是把最好效果的流进行输出:

-
    -
  • 对于视频,它是具有最高分辨率的流
  • -
  • 对于音频,它是具有最多频道的流
  • -
  • 对于字幕,它是第一个找到的字幕流,但有一个警告。输出格式的默认字幕编码器可以是基于文本的,也可以是基于图像的,并且仅选择相同类型的字幕流
  • -
  • 在几个相同类型的流速率相等的情况下,选择具有最低索引的流。
  • -
-

当然,你可以禁用默认设置,而采用-vn/-an/-sn选项进行专门的指定,如果要进行完全的手动控制,则是以-map选项,它将禁止默认值而选用指定的配置。

-

4.1流处理

流处理独立于流选择,下面描述的字幕除外。流处理通过-codec选项进行设置,该选项寻址到特定输出文件内的流。特别是,-codec在流选择过程之后被ffmpeg应用,因此不影响后者。如果没有为流类型指定-codec选项,ffmpeg将选择输出文件muxer注册的默认编码器。

-

对于字幕存在例外。如果为输出文件指定了字幕编码器,则将包括找到任何类型的第一个字幕流,如文本或图像。 ffmpeg不验证指定的编码器是否可以转换所选的流,或者转换的流是否在输出格式中是可接受的。这通常也适用:当用户手动设置编码器时,流选择过程不能检查编码流是否可以复用到输出文件中。如果不能,则ffmpeg将中止,并且所有输出文件都将无法处理。

-

4.2例子

假设以下三个输入文件。

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
input file 'A.avi'
stream 0: video 640x360
stream 1: audio 2 channels

input file 'B.mp4'
stream 0: video 1920x1080
stream 1: audio 2 channels
stream 2: subtitles (text)
stream 3: audio 5.1 channels
stream 4: subtitles (text)

input file 'C.mkv'
stream 0: video 1280x720
stream 1: audio 2 channels
stream 2: subtitles (image)
-
示例:自动流选择
1
ffmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov
-

指定了三个输出文件,对于前两个out1 out2,由于未设置-map选项,因此ffmpeg将自动为这两个文件选择流。
out1.mkv是一个Matroska容器文件,接受视频,音频和字幕流,因此ffmpeg将尝试选择每种类型中的一种。
对于视频,它将从B.mp4中选择流 stream 0 ,其在所有输入视频流中具有最高分辨率。
对于音频,它将从B.mp4中选择流 stream 3 ,因为它具有最多的通道。
对于字幕,它将从B.mp4中选择流 stream 2 ,这是A.avi和B.mp4中的第一个字幕流。
out2.wav只接受音频流,因此只选择来自B.mp4的stream 3。
out3.mov,由于设置了-map选项,因此不会进行自动流选择。 -map 1:a选项将从第二个输入B.mp4中选择所有音频流。此输出文件中不包含其他流。
对于前两个输出,将对所有包含的流进行转码。选择的编码器将是每种输出格式注册的默认编码器,可能与所选输入流的编解码器不匹配。
对于第三个输出,-c:a copy意为使用指定音视频编码中的所有音频流编解码器,设置为copy,因此不会发生以及不可能发生解码 - 过滤 - 编码操作。所选流的数据包应从输入文件传送,并在输出文件中复用。

-
示例:自动字幕选择
1
ffmpeg -i C.mkv out1.mkv -c:s dvdsub -an out2.mkv
-

尽管out1.mkv是Matroska容器文件,它接受字幕流,但只能选择视频和音频流。 C.mkv的字幕流是基于图像的,并且Matroska复用器的默认字幕编码器是基于文本的,因此字幕的转码操作预计会失败,因此不选择该流。 然而,在out2.mkv中,在命令中-c:s dvdsub指定字幕编码器,因此,除了视频流之外,还选择字幕流。 -an的存在禁用out2.mkv的音频流选择。

-

选项

所有的数值选项,如果没有特殊定义,则需要一个接受一个字符串代表一个数作为输入,这可能跟着一个单位量词首字母,例如"k","m""G"

-

如果i是附加到SI单位的首字母,完整的字母将被解释为一个2的幂数单位,这是基于1024而不是1000的,添加B的SI单位则是再将此值乘以8。例如KBMiBGB

-

对于选项中不带参数的布尔选项,即把相应的值设置为true,它们可以添加no设置为false,例如nofoo就相当于foo false

-

流说明(限定)符

    -
  • 很多选项是作用于单独的流的,例如码率(bitrate)或者编码(codec),流说明符就是精确的为每个流指定相应的选项。
  • -
  • 一个流说明符是一个以冒号分隔的字符串,其中分隔出的部分是附加选项,例如-codec:a:1 ac3表示编码器是对第2音频流以ac3编码。
  • -
  • 一个流说明符可能匹配多个流,则该选项是所有匹配项的选项,例如-b:a 128k表示所有的音频流都是128k的码率。
  • -
  • 一个空的流说明符匹配所有的流,例如-codec copy或者-codec: copy表示所有的流都不进行再次编码(包括视频和音频)
  • -
-

可能的流说明符有:

-
    -
  • stream_index:匹配流的索引,例如-threads:1 4表示对2号流采用4个线程处理
  • -
  • stream_type[:stream_index]:stream_typev表示视频,a表示音频,s表示字幕,d表示数据和t表示附加/附件等可能,如果stream_index同时被指定,则匹配该索引对于的该类型的流。例如-codec:v:0 h264表示第1视频流是h.264编码。
  • -
  • p:program_id[:stream_index]:如果stream_index被指定,则表示被program_id指定的程序仅作用于stream_index所指流,否则将作用于所有流。
  • -
  • #stream_id或者i:stream_id:匹配stream_id所指流(MPEG-TS中的PID)
  • -
  • m:key[:value]:匹配在元数据中以标签key=value值的流,如果value没有设置,则匹配所有。
  • -
  • u:匹配不能被配置的流,这时编码器必须被定义且有必要的视频维度或者音频采样率之类的信息。注意ffmpeg匹配由元数据标识的状态仅对于输入文件有效。
  • -
-

常规选项

这些常规选项也可以用在ffmpeg项目中其他ff*工具,例如ffplayer

-
    -
  • -L:显示授权协议

    -
  • -
  • -h,-?,-help,--help[arg]:显示帮助,一个附加选项可以指定帮助显示的模式,如果没有参数,则是基本选项(没有特别声明)说明被显示,下面是参数定义

    -
      -
    • long:在基本选项说明基础上增加高级选项说明
    • -
    • full:输出完整的选项列表,包括编(解)码器,分离器混合器以及滤镜等等的共享和私有选项
    • -
    • decoder=decoder_name:输出指定解码器名的详细信息。可以使用-decoders来获取当前支持的所有解码器名
    • -
    • encoder=encoder_name:输出指定编码器名的详细信息。可以使用-encoders来获取当前支持的所有编码器名
    • -
    • demuxer=demuxer_name:输出指定分离器名详细信息。可以使用-formats来获取当前支持的所有分离器和混合器
    • -
    • muxer=muxer_name:输出指定混合器名详细信息。可以使用-formats来获取当前支持的所有分离器和混合器
    • -
    • filter=filter_name:输出指定滤镜名的详细信息。可以使用-filters来获取当前支持的所有滤镜
    • -
    -
  • -
  • -version:显示版

    -
  • -
  • -buildconf : 显示构建选项

    -
  • -
  • -formats:显示所有有效的格式(包括设备)

    -
  • -
  • -devices:显示有效设备

    -
  • -
  • -codecs:显示所有已支持的编码(libavcodec中的)

    -
  • -
  • -decoders:显示所有有效解码器

    -
  • -
  • -encoders:显示所有有效的编码器

    -
  • -
  • -bsfs:显示有效的数据流(bitstream)滤镜

    -
  • -
  • -protocols:显示支持的协议

    -
  • -
  • -filters:显示libavfilter中的滤镜

    -
  • -
  • -pix_fmts:显示有效的像素(pixel)格式

    -
  • -
  • -sample_fmts:显示有效的实例格式

    -
  • -
  • -layouts:显示信道名字和信道布局

    -
  • -
  • -colors:显示注册的颜色名

    -
  • -
  • -sources device[,opt1=val1[,opt2=val]...]:显示自动识别的输入设备源。一些设备可能需要提供一些系统指派的源名字而不能自动识别。返回的列表不能认为一定是完整的(即有可能还有设备没有列出来)

    -

    ffmpeg -sources pulse,server=192.168.0.4

    -
  • -
  • -sinks device[,opt1=val1[,opt2=val]...]:显示自动识别的输出设备。一些设备可能需要提供一些系统指派的源名字而不能自动识别。返回的列表不能认为一定是完整的(即有可能还有设备没有列出来)

    -

    ffmpeg -sinks pulse,server=192.168.0.4

    -
  • -
  • -loglevel [repeat+]loglevel 或者 -v [repeat+]loglevel:设置日志层次。如果附加有repeat+则表示从第一条非压缩行到达到最后消息n次之间的行将被忽略。"repeat"也可以一直使用,如果没有现有日志层级设置,则采用默认日志层级。如果有多个日志层级参数被获取,使用"repeat"不改变当前日志层级。日志层级是一个字符串或数值,有以下可能值:

    -
      -
    • quiet,-8,什么都不输出,是无声的

      -
    • -
    • panic,0,仅显示造成进程失败的致命错误,它当前不能使用

      -
    • -
    • fatal,8仅仅显示致命错误,这些错误使得处理不能继续

      -
    • -
    • error,16显示所有的错误,包括可以回收的错误(进程还可以继续的)

      -
    • -
    • warning,24显示所有警告和错误,任何错误或者意外事件相关信息均被显示

      -
    • -
    • info,32显示过程中的信息,还包括警告和错误,则是默认值

      -
    • -
    • verbose,40类似info,但更冗长

      -
    • -
    • debug,48显示所有,包括调试信息

      -
    • -
    • trace,56

      -

      默认的日志输出是stderr设备,如果在控制台支持颜色,则错误和警告标记的颜色将被显示处理,默认日志的颜色设置可以由环境变量的AV_LOG_FORCE_NOCOLOR或者NO_COLOR或者环境变量AV_LOG_RORCE_COLOR覆盖。环境变量NO_COLOR不推荐使用,因为其已经不被新版本支持。

      -
    • -
    -
  • -
  • -report:复制所有命令行和控制台输出到当前目录下名为program-YYYMMDD-HHMMSS.log文件中。这常用于报告bug,所以一般会同时设置-loglevel verbose

    -

    设置环境变量FFREPORT可以起到相同的效果。如果值是一个以分隔的关键值对,则将影响到报告效果。值中的特殊符号或者分隔符必须被转义(参考ffmepg-utils手册中”引用逃逸”(“Quoting and escaping”)章节)。以下是选项值范围:

    -
      -
    • file:设置报告文件名字,%p被扩展为程序名字,%t是时间码,%%表示一个字符%

      -
    • -
    • level:用数字设定日志信息详略程度(参考-longlevel)

      -

      例如:

      -
      1
      `FFREPORT=file=ffreport.log:level=32 ffmpeg -i input output`
      -

      会把日志信息输出到环境变量定义的文件中, 内容包括简要过程信息,警告和错误。

      -
    • -
    -
  • -
  • -hide_banner:禁止打印输出banner。所有FFmpeg工具使用中常规都会在前面显示一些版权通知、编译选项和库版本等,这个选项可以禁止这部分的显示。

    -
  • -
  • cpuflags flags(global):允许设置或者清除cpu标志性和。当前这个选项主要还是测试特性,不要使用,除非你明确需要:

    -
    1
    2
    3
    ffmpeg -cpuflags -sse+mmx ... 
    ffmpeg -cpuflags mmx ...
    ffmpeg -cpuflags 0 ...
    -

    可能的选项参数有:

    -
      -
    • x86

      -
        -
      • mmx
      • -
      • mmxext
      • -
      • sse
      • -
      • sse2
      • -
      • sse2slow
      • -
      • sse3
      • -
      • atom
      • -
      • sse4.1
      • -
      • sse4.2
      • -
      • avx
      • -
      • avx2
      • -
      • xop
      • -
      • fma3
      • -
      • fma4
      • -
      • 3dnow
      • -
      • 3dnowext
      • -
      • bmi1
      • -
      • bmi2
      • -
      • cmov
      • -
      -
    • -
    • ARM

      -
        -
      • armv5te
      • -
      • armv6
      • -
      • armv6t2
      • -
      • vfp
      • -
      • vfpv3
      • -
      • neon
      • -
      • setend
      • -
      -
    • -
    • AArch64

      -
        -
      • armv8
      • -
      • vfp
      • -
      • neon
      • -
      -
    • -
    • PowerPC

      -
        -
      • altivec
      • -
      -
    • -
    • Specific Processors

      -
        -
      • pentium2
      • -
      • pentium3
      • -
      • pentium4
      • -
      • k6
      • -
      • athlon
      • -
      • athlonxp
      • -
      • k8
      • -
      -
    • -
    -
  • -
  • -opencl_bench:输出所有效OpenCL设备的基准测试情况。当前选项仅在编译FFmepg中打开了--enable-opencl才有效。

    -

    当FFmpeg指定了--enable-opencl编译后,这个选项还可以通过全局参数-opencl_options进行设定,参考OpenCL选项,在ffmpeg-utils手册中对于选项的支持情况,这包括在特定的平台设备上支持OpenCL的能力。默认,FFmpeg会运行在首选平台的首选设备上,通过设置全局的OpenCL则可以实现在选定的OpenCL设备上运行,这样就可以在更快的OpenCL设备上运行(平时节点,需要时才选用性能高但耗电的设备)

    -

    这个选项有助于帮助用户了解信息以进行有效配置。它将在每个设备上运行基准测试,并以性能排序所有设备,用户可以在随后调用ffmpeg时使用-opencl_options配置合适的OpenCL加速特性。

    -

    一般以下面的步骤使用这个参数:

    -
    -
    1
    ffmpeg -opencl_bench        
    -
    -

    注意输出中第一行的平台ID(pidx)和设备ID(didx),然后在选择平台和设备用于命令行:

    -
    -
    1
    ffmpeg -opencl_options platform_idx=pidx:device_idx=didx ...
    -
    -
  • -
  • opencl_options options(global):设置OpenCL环境选项,这个选项仅仅在FFmpeg编译选项中打开了--enable-opencl才有效。

    -

    options必须是一个由:分隔的key=value键值对列表。参考OpenCL选项,在ffmpeg-utils手册中对于选项的支持情况

    -
  • -
-

AV选项

这些选项由特定的库提供(如libavformat,libavdevice以及libavcodec)。为了更多的了解AV选项,使用-help进行进一步了解。它们可以指定下面2个分类:

-
    -
  • generic(常规):这类选项可以用于设置容器、设备、编码器、解码器等。通用选项对列在AVFormatContext中的容器/设备以及AVCodecContext中的编码有效。
  • -
  • private(私有):这类仅对特定的容器、设备或者编码有效。私有选项由相应的 容器/设备/编码 指定(确定)。
  • -
-

例如要在一个默认为ID3v2.4为头的MP3文件中写入ID3v2.3头,需要使用id3v2_version 私有选项来对MP3混流:

-
-
1
ffmpeg -i input.flac -id3v2_version 3 out.mp3
-
-

所有编码AV选项是针对单独流的,所以必须详细指定。

-

注意

-
    -
  1. -nooption语法不能被用于AV选项中的布尔值项目,而必须使用-option 0/-option 1
  2. -
  3. 以往使用v/a/s命名指定每个流的AV选项语法已经不建议使用,它们很快就会失效移除。
  4. -
-

主要选项

    -
  • -f fmt (input/output) :指定输入或者输出文件格式。常规可省略而使用依据扩展名的自动指定,但一些选项需要强制明确设定。

    -
  • -
  • -i filename (input):指定输入文件

    -
  • -
  • -y (global):默认自动覆盖输出文件,而不再询问确认。

    -
  • -
  • -n (global):不覆盖输出文件,如果输出文件已经存在则立即退出

    -
  • -
  • -c[:stream_specifier] codec (input/output,per-stream)

    -
  • -
  • -codec[:stream_specifier] codec (input/output,per-stream) 为特定的文件选择编/解码模式,对于输出文件就是编码器,对于输入或者某个流就是解码器。选项参数中codec是编解码器的名字,或者是copy(仅对输出文件)则意味着流数据直接复制而不再编码。例如:

    -
    1
    ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
    -

    是使用libx264编码所有的视频流,然后复制所有的音频流。

    -

    再如除了特殊设置外所有的流都由c匹配指定:

    -
    1
    ffmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
    -

    这将在输出文件中第2视频流按libx264编码,第138音频流按libvorbis编码,其余都直接复制输出。

    -
  • -
  • -t duration (input/output):限制输入/输出的时间。如果是在-i前面,就是限定从输入中读取多少时间的数据;如果是用于限定输出文件,则表示写入多少时间数据后就停止。duration可以是以秒为单位的数值或者 hh:mm:ss[.xxx]格式的时间值。 注意-to-t是互斥的,-t有更高优先级。

    -
  • -
  • -to position (output):只写入position时间后就停止,position可以是以秒为单位的数值或者 hh:mm:ss[.xxx]格式的时间值。 注意-to-t是互斥的,-t有更高优先级。

    -
  • -
  • -fs limit_size (output):设置输出文件大小限制,单位是字节(bytes)。

    -
  • -
  • -ss position (input/output):

    -
      -
    • 当在-i前,表示定位输入文件到position指定的位置。注意可能一些格式是不支持精确定位的,所以ffmpeg可能是定位到最接近position(在之前)的可定位点。当有转码发生且-accurate_seek被设置为启用(默认),则实际定位点到position间的数据被解码出来但丢弃掉。如果是复制模式或者-noaccurate_seek被使用,则这之间的数据会被保留。
    • -
    • 当用于输出文件时,会解码丢弃position对应时间码前的输入文件数据。
    • -
    • position可以是以秒为单位的数值或者 hh:mm:ss[.xxx]格式的时间值
    • -
    -
  • -
  • -itsoffset offset (input):设置输入文件的时间偏移。offset必须采用时间持续的方式指定,即可以有-号的时间值(以秒为单位的数值或者 hh:mm:ss[.xxx]格式的时间值)。偏移会附加到输入文件的时间码上,意味着所指定的流会以时间码+偏移量作为最终输出时间码。

    -
  • -
  • -timestamp date (output):设置在容器中记录时间戳。

    -

    date 必须是一个时间持续描述格式,即

    -
    1
    2
    3
    [(YYYY-MM-DD|YYYYMMDD)[T|t| ]]((HH:MM:SS[.m...]]])|(HHMMSS[.m...]]]))[Z]
    或者为
    now
    -
  • -
  • -metadata[:metadata_specifier] key=value (output,per-metadata):指定元数据中的键值对。

    -

    流或者章的metadata_specifier可能值是可以参考文档中-map_metadata部分了解。

    -

    简单的覆盖-map_metadata可以通过一个为空的选项实现,例如:

    -
    -
    1
    ffmpeg -i in.avi -metadata title="my title" out.flv
    -

    设置第1声道语言:

    -
    1
    ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
    -
    -
  • -
  • -taget type (output):指定目标文件类型(vcd,svcd,dvd,dv,dv50),类型还可以前缀一个pal-,ntsc-或者film-来设定更具体的标准。所有的格式选项(码率、编码、缓冲尺寸)都会自动设置,而你仅仅只需要设置目标类型:

    -
    -
    1
    ffmpeg -i myfile.avi -taget vcd /tmp/vcd.mpg
    -
    -

    当然,你也可以指定一些额外的选项,只要你知道这些不会与标准冲突,如:

    -
    -
    1
    ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
    -
    -
  • -
  • -dframes number (output):设定指定number数据帧到输出文件,这是-frames:d的别名。

    -
  • -
  • frames[:stream_specifier] framecount (output,per-stream):在指定计数帧后停止写入数据。

    -
  • -
  • -q[:stream_specifier] q (output,per-stream)

    -
  • -
  • -qscale[:stream_specifier] q (output,per-stream)

    -

    使用固定的质量品质(VBR)。用于指定q|qscale编码依赖。如果qscale没有跟stream_specifier则只适用于视频。其中值q取值在0.01-255,越小质量越好。

    -
  • -
  • -filter[:stream_specifier] filtergraph (output,per-stream):创建一个由filtergraph指定的滤镜,并应用于指定流。

    -

    filtergraph是应用于流的滤镜链图,它必须有一个输入和输出,而且流的类型需要相同。在滤镜链图中,从in标签指定出输入,从out标签出输出。要了解更多语法,请参考ffmpeg-filters手册。

    -

    参考-filter_complex选项以了解如何建立多个输入/输出的滤镜链图。

    -
  • -
  • -filter_script[:stream_specifier] filename (output,per-stream):这个选项类似于-filter,只是这里的参数是一个文件名,它的内容将被读取用于构建滤镜链图。

    -
  • -
  • -pre[:stream_specifier] preset_name (output,per-stream):指定预设名字的流(单个或者多个)。

    -
  • -
  • -stats (global):输出编码过程/统计,这是系统默认值,如果你想禁止,则需要采用-nostats

    -
  • -
  • -progress url (global):发送友好的处理过程信息到url。处理过程信息是一种键值对(key=value)序列信息,它每秒都输出,或者在一次编码结束时输出。信息中最后的一个键值对表明了当前处理进度。

    -
  • -
  • -stdin:允许标准输入作为交互。在默认情况下除非标准输入作为真正的输入。要禁用标准输入交互,则你需要显式的使用-nostdin进行设置。禁用标准输入作为交互作用是有用的,例如FFmpeg是后台进程组,它需要一些相同的从shell开始的调用(ffmpeg ... </dev/null)。

    -
  • -
  • -debug_ts (global):打印时间码信息,默认是禁止的。这个选项对于测试或者调试是非常有用的特性,或者用于从一种格式切换到另外的格式(包括特性)的时间成本分析,所以不用于脚本处理中。还可以参考-fdebug ts选项。

    -
  • -
  • -attach filename (output):把一个文件附加到输出文件中。这里只有很少文件类型能被支持,例如使用Matroska技术为了渲染字幕的字体文件。附件作为一种特殊的流类型,所以这个选项会添加一个流到文件中,然后你就可以像操作其他流一样使用每种流选项。在应用本选项时,附件流须作为最后一个流(例如根据-map映射流或者自动映射时需要注意)。注意对于Matroska你也可以在元数据标签中进行类型设定: > ffmpeg -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv

    -
  • -
-

(这时要访问到附件流,则就是访问输出文件中的第3个流)

-
    -
  • -dump_attachment[:stream_specifier] filename (input,per-stream):从输入文件中解出指定的附件流到文件filename: > ffmpeg -dump_attachment:t:0 out.ttf -i INPUT

    -

    如果想一次性把所有附件都解出来,则 > ffmpeg -dump_attachment:t “” -i INPUT

    -

    技术说明:附件流是作为编码扩展数据来工作的,所以其他流数据也能展开,而不仅仅是这个附件属性。

    -
  • -
  • -noautorotate:禁止自动依据文件元数据旋转视频。

    -
  • -
-

视频(video)选项

    -
  • -vframes number (output):设置输出文件的帧数,是-frames:v的别名。

    -
  • -
  • -r[:stream_specifier] fps (input/output,per-stream):设置帧率(一种Hz值,缩写或者分数值)。

    -

    在作为输入选项时,会忽略文件中存储的时间戳和时间戳而产生的假设恒定帧率fps,即强制按设定帧率处理视频产生(快进/减缓效果)。这不像-framerate选项是用来让一些输入文件格式如image2或者v412(兼容旧版本的FFmpeg)等,要注意这一点区别,而不要造成混淆。

    -

    作为输出选项时,会复制或者丢弃输入中个别的帧以满足设定达到fps要求的帧率。

    -
  • -
  • -s[:stream_specifier] size (input/output,per-stream):设置帧的尺寸。

    -

    当作为输入选项时,是私有选项video_size的缩写,一些文件没有把帧尺寸进行存储,或者设备对帧尺寸是可以设置的,例如一些采集卡或者raw视频数据。

    -

    当作为输出选项是,则相当于scale滤镜作用在滤镜链图的最后。请使用scale滤镜插入到开始或者其他地方。

    -

    数据的格式是wxh,即宽度值X高度值,例如320x240,(默认同源尺寸)

    -
  • -
  • aspect[:stream_specifier] aspect (output,per-stream):指定视频的纵横比(长宽显示比例)。aspect是一个浮点数字符串或者num:den格式字符串(其值就是num/den),例如”4:3”,”16:9”,”1.3333”以及”1.7777”都是常用参数值。

    -

    如果还同时使用了-vcodec copy选项,它将只影响容器级的长宽比,而不是存储在编码中的帧纵横比。

    -
  • -
  • -vn (output):禁止输出视频

    -
  • -
  • -vcodec codec (output):设置视频编码器,这是-codec:v的一个别名。

    -
  • -
  • -pass[:stream_specifier] n (output,per-stream):选择当前编码数(1或者2),它通常用于2次视频编码的场景。第一次编码通常把分析统计数据记录到1个日志文件中(参考-passlogfile选项),然后在第二次编码时读取分析以精确要求码率。在第一次编码时通常可以禁止音频,并且把输出文件设置为null,在windows和类unix分别是:

    -
    -

    ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null

    -
    -
  • -
  • -passlogfile[:stream_specifier] prefix (output,per-stream):设置2次编码模式下日志文件存储文件前导,默认是”ffmepg2pass”,则完整的文件名就是”PREFIX-N.log”,其中的N是指定的输出流序号(对多流输出情况)

    -
  • -
  • -vf filtergraph (output):创建一个filtergraph的滤镜链并作用在流上。它实为-filter:v的别名,详细参考-filter选项。

    -
  • -
-

高级视频选项

    -
  • -pix_fmt[:stream_specifier] format (input/output,per-stream):设置像素格式。使用-pix_fmts可以显示所有支持的像素格式。如果设置的像素格式不能被选中(启用),则ffmpeg会输出一个警告和并选择这个编码最好(兼容)的像素格式。如果pix_fmt前面前导了一个+字符,ffmepg会在要求的像素格式不被支持时退出,这也意味着滤镜中的自动转换也会被禁止。如果pix_fmt是单独的+,则ffmpeg选择和输入(或者滤镜通道)一样的像素格式作为输出,这时自动转换也会被禁止。

    -
  • -
  • -sws_flags flags (input/output):选择SwScaler放缩标志量。

    -
  • -
  • -vdt n:丢弃的门限设置。

    -
  • -
  • -rc_override[:stream_specifier] override (output,per-stream):在特定时间范围内的间隔覆盖率,override的格式是”int\int\int”。其中前两个数字是开始帧和结束帧,最后一个数字如果为正则是量化模式,如果为负则是品质因素。

    -
  • -
  • -ilme:支持交错编码(仅MPEG-2和MPEG-4)。如果你的输入是交错的,而且你想保持交错格式,又想减少质量损失,则选此项。另一种方法是采用-deinterlace对输入流进行分离,但会引入更多的质量损失。

    -
  • -
  • -psnr:计算压缩帧的PSNR

    -
  • -
  • -vstats:复制视频编码统计分析到日志文件vstats_HHMMSS.log

    -
  • -
  • -vstats_file file:复制视频编码统计分析到file所指的日志文件中。

    -
  • -
  • -top[:stream_specifier] n (output,per-stream): 指明视频帧数据描述的起点。顶部=1/底部=0/自动=-1(以往CRT电视扫描线模式)

    -
  • -
  • -dc precision:Intra_dc_precision值。

    -
  • -
  • -vtag fourcc/tag (output):是-tag:v的别名,强制指定视频标签/fourCC (FourCC全称Four-Character Codes,代表四字符代码 (four character code), 它是一个32位的标示符,其实就是typedef unsigned int FOURCC;是一种独立标示视频数据流格式的四字符代码。)

    -
  • -
  • -qphist (global):显示QP直方图。

    -
  • -
  • -vbsf bitstream_filter:参考-bsf以进一步了解。

    -
  • -
  • -force_key_frames[:stream_specifier] time[,time...] (output,per-stream) :(见下)

    -
  • -
  • -force_key_frames[:stream_specifier] expr:expr (output,per-stream):强制时间戳位置帧为关键帧,更确切说是从第一帧起每设置时间都是关键帧(即强制关键帧率)。

    -

    如果参数值是以expr:前导的,则字符串expr为一个表达式用于计算关键帧间隔数。关键帧间隔值必须是一个非零数值。

    -

    如果一个时间值是”chapters [delta]”则表示文件中从delta章开始的所有章节点计算以秒为单位的时间,并把该时间所指帧强制为关键帧。这个选项常用于确保输出文件中所有章标记点或者其他点所指帧都是关键帧(这样可以方便定位)。例如下面的选项代码就可以使“第5分钟以及章节chapters-0.1开始的所有标记点都成为关键帧”:

    -
    -

    -force_key_frames 0:05:00,chapters-0.1

    -
    -

    其中表达式expr接受如下的内容:

    -
      -
    • n:当前帧序数,从0开始计数

      -
    • -
    • n_forced:强制关键帧数

      -
    • -
    • prev_forced_n:之前强制关键帧数,如果之前还没有强制关键帧,则其值为NAN

      -
    • -
    • prev_forced_t:之前强制关键帧时间,如果之前还没有强制关键帧则为NAN

      -
    • -
    • t:当前处理到的帧对应时间。

      -

      例如要强制每5秒一个关键帧:

      -
      -

      -force_key_frames expr:gte(t,n_forced*5)

      -
      -

      从13秒后每5秒一个关键帧:

      -
      -

      -force_key_frames expr:if(isnan(prev_forced_t),gte(t,13),gte(t,prev_forced_t+5))

      -
      -

      注意设置太多强制关键帧会损害编码器前瞻算法效率,采用固定GOP选项或采用一些近似设置可能更高效。

      -
    • -
    -
  • -
  • -copyinkf[:stream_specifier] (output,per-stream):流复制时同时复制非关键帧。

    -
  • -
  • -hwaccel[:stream_specifier] hwaccel (input,per-stream):使用硬件加速解码匹配的流。允许的hwaccel值为:

    -
      -
    • none:没有硬件加速(默认值)

      -
    • -
    • auto:自动选择硬件加速

      -
    • -
    • vda:使用Apple的VDA硬件加速

      -
    • -
    • vdpau:使用VDPAU(Video Decode and Presentation API for Unix,类unix下的技术标准)硬件加速

      -
    • -
    • dxva2:使用DXVA2 (DirectX Video Acceleration,windows下的技术标准) 硬件加速。

      -

      这个选项可能并不能起效果(它依赖于硬件设备支持和选择的解码器支持)

      -

      注意:很多加速方法(设备)现在并不比现代CPU快了,而且额外的ffmpeg需要拷贝解码的帧(从GPU内存到系统内存)完成后续处理(例如写入文件),从而造成进一步的性能损失。所以当前这个选项更多的用于测试。

      -
    • -
    -
  • -
  • -hwaccel_device:[:stream_specifier] hwaccel_device (input,per-stream):选择一个设备用于硬件解码加速。这个选项必须同时指定了-hwaccel才可能生效。它也依赖于指定的设备对于特定编码的解码加速支持性能。

    -
      -
    • vdpau:对应于VDPAU,在X11(类Unix)显示/屏幕 上的,如果这个选项值没有选中,则必须在DISPLAY环境变量中有设置。
    • -
    • dxva2:对应于DXVA2,这个是显示硬件(卡)的设备号,如果没有指明,则采用默认设备(对于多个卡时)。
    • -
    -
  • -
-

音频选项

    -
  • -aframes number (output):设置number音频帧输出,是-frames:a的别名
  • -
  • -ar[:stream_specifier] freq (input/output,per-stream):设置音频采样率。默认是输出同于输入。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。对于输出则可以强制设置音频量化的采用率。
  • -
  • -aq q (output):设置音频品质(编码指定为VBR),它是-q:a的别名。
  • -
  • -ac[:stream_specifier] channels (input/output,per-stream):设置音频通道数。默认输出会有输入相同的音频通道。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。
  • -
  • -an (output):禁止输出音频
  • -
  • -acode codec (input/output):设置音频解码/编码的编/解码器,是-codec:a的别名
  • -
  • -sample_fmt[:stream_specifier] sample_fmt (output,per-stream):设置音频样例格式。使用-sample_fmts可以获取所有支持的样例格式。
  • -
  • -af filtergraph (output):对音频使用filtergraph滤镜效果,其是-filter:a的别名,参考-filter选项。
  • -
-

高级音频选项

    -
  • -atag fourcc/tag (output):强制音频标签/fourcc。这个是-tag:a的别名。
  • -
  • -absf bitstream_filter:要深入了解参考-bsf
  • -
  • -guess_layout_max channels (input,per-stream):如果音频输入通道的布局不确定,则尝试猜测选择一个能包括所有指定通道的布局。例如:通道数是2,则ffmpeg可以认为是2个单声道,或者1个立体声声道而不会认为是6通道或者5.1通道模式。默认值是总是试图猜测一个包含所有通道的布局,用0来禁用。
  • -
-

字幕选项

    -
  • -scodec codec (input/output):设置字幕解码器,是-codec:s的别名。
  • -
  • -sn (output):禁止输出字幕
  • -
  • -sbsf bitstream_filter:深入了解请参考-bsf
  • -
-

高级字幕选项

    -
  • -fix_sub_duration:修正字幕持续时间。对每个字幕根据接下来的数据包调整字幕流的时间常数以防止相互覆盖(第一个没有完下一个就出来了)。这对很多字幕解码来说是必须的,特别是DVB字幕,因为它在原始数据包中只记录了一个粗略的估计值,最后还以一个空的字幕帧结束。

    -

    这个选项可能失败,或者出现夸张的持续时间或者合成失败,这是因为数据中有非单调递增的时间戳。

    -

    注意此选项将导致所有数据延迟输出到字幕解码器,它会增加内存消耗,并引起大量延迟。

    -
  • -
  • -canvas_size size:设置字幕渲染区域的尺寸(位置)

    -
  • -
-

高级选项

    -
  • -map [-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]] | [linklabel] (output):设定一个或者多个输入流作为输出流的源。每个输入流是以input_file_id序数标记的输入文件和input_stream_id标记的流序号共同作用指明,它们都以0起始计数。如果设置了sync_file_id:stream_specifier,则把这个输入流作为同步信号参考。

    -

    命令行中的第一个-map选项指定了输出文件中第一个流的映射规则(编号为0的流,0号流),第二个则指定1号流的,以此类推。

    -

    如果在流限定符前面有一个-标记则表明创建一个“负”映射,这意味着禁止该流输出,及排除该流。

    -

    一种替代的形式是在复合滤镜中利用[linklabel]来进行映射(参看-filter_complex选项)。其中的linklabel必须是输出滤镜链图中已命名的标签。

    -

    例子:映射第一个输入文件的所有流到输出文件:

    -
    1
    ffmpeg -i INPUT -map 0 output
    -

    又如,如果在输入文件中有两路音频流,则这些流的标签就是”0:0”和”0:1”,你可以使用-map来选择某个输出,例如: > ffmpeg -i INPUT -map 0:1 out.wav

    -

    这将只把输入文件中流标签为”0:1”的音频流单独输出到out.wav中。

    -

    再如,从文件a.mov中选择序号为2的流(流标签0:2),以及从b.mov中选择序号为6的流(流标签1:6),然后共同复制输出到out.mov需要如下写:

    -
    1
    2
    3
    4
    5
    6
    7
    ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
    选择所有的视频和第三个音频流则是:
    ffmpeg -i INPUT -map 0:v -map:a:2 OUTPUT
    选择所有的流除了第二音频流外的流进行输出是:
    ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
    选择输出英语音频流:
    ffmpeg -i INPUT -map 0:m:language:eng OUTPUT
    -

    注意应用了该选项将自动禁用默认的映射。

    -
  • -
  • -ignore_unknown:如果流的类型未知则忽略,而不进行复制。

    -
  • -
  • -copy_unknown:复制类型未知的流。

    -
  • -
  • -map_channel [input_file_id.stream_specifier.channel_id|-1][:output_file_id.stream_specifier]:从输入文件中指定映射一个通道的音频到输出文件指定流。如果output_file_id.stream_specifier没有设置,则音频通道将映射到输出文件的所有音频流中。

    -

    使用-1插入到input_file_id.stream_specifier.chnnel_id会映射一个静音通道

    -

    例如INPUT是一个立体声音频文件,你可以分别选择两个音频通道(下面实际上对于输入是交换了2个音频通道顺序进行输出): > ffmpeg -i INPUT -map_channel 0.0.1 -map_channel 0.0.0 OUTPUT

    -

    如果你想静音第一个通道,而只保留第二通道,则可使用: > ffmpeg -i INPUT -map_channel -1 -map_channel 0.0.1 OUTPUT

    -

    -map_channel选项指定的顺序在输出文件中输出音频流通道布局,即第一个-map_channel对应输出中第一个音频流通道,第二个对应第二个音频流通道,以此类推(只有一个则是单声道,2个是立体声)。联合使用-ac-map_channel,而且在输入的-map_channel-ac不匹配(例如只有2个-map_channel,又设置了-ac 6)时将使指定音频流通道提高增益。

    -

    你可以详细的对每个输入通道指派输出以分离整个输入文件,例如下面就把有INPUT文件中的两个音频分别输出到两个输出文件中(OUTPUT_CH0 和 OUTPUT_CH1 ): > ffmpeg -i INPUT -map_channel 0.0.0 OUTPUT_CH0 -map_channel 0.0.1 OUTPUT_CH1

    -

    下面的例子则把一个立体声音频的两个音频通道分离输出到两个相互独立的流(相当于两个单声道了)中(但还是放置在同一个输出文件中): > ffmpeg -i stereo.wav -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 -y out.ogg

    -

    注意当前一个输出流仅能与一个输入通道连接,既你不能实现利用-map_channel把多个输入的音频通道整合到不同的流中(从同一个文件或者不同文件)或者是混合它们成为单独的流,例如整合2个单声道形成立体声是不可能的。但是分离一个立体声成为2个独立的单声道是可行的。

    -

    如果你需要类似的应用,你需要使用amerge滤镜,例如你需要整合一个媒体(这里是input.mkv)中的2个单声道成为一个立体声通道(保持视频流不变),你需要采用下面的命令: > ffmpeg -i input.mkv -filter_complex “[0:1] [0:2] amerge” -c:a pcm_s16le -c:v copy output.mkv

    -
  • -
  • -map_metadata[:metadata_spec_out] infile[:metadata_spec_in] (output,per-metadata):在下一个输出文件中从infile读取输出元数据信息。注意这里的文件索引也是以0开始计数的,而不是文件名。参数metadata_spec_in/out指定的元数据将被复制,一个元数据描述可以有如下的信息块:

    -
      -
    • g:全局元数据,这些元数据将作用于整个文件

      -
    • -
    • s[:stream_spec]:每个流的元数据,steam_spec的介绍在流指定章节。如果是描述输入流,则第一个被匹配的流相关内容被复制,如果是输出元数据指定,则所有匹配的流相关信息被复制到该处。

      -
    • -
    • c:chapter_index:每个章节的元数据,chapter_index也是以0开始的章节索引。

      -
    • -
    • p:program_index:每个节目元数据,program_index是以0开始的节目索引

      -

      如果元数据指定被省略,则默认是全局的。

      -

      默认全局元数据会从第一个输入文件每个流每个章节依次复制(流/章节),这种默认映射会因为显式创建了任意的映射而失效。一个负的文件索引就可以禁用默认的自动复制。

      -

      例如从输入文件的第一个流复制一些元数据作为输出的全局元数据 > ffmpeg -i in.ogg -map_metadata 0:s:0 out.mp3

      -

      与上相反的操作,例如复制全局元数据给所有的音频流 > ffmpeg -i in.mkv -map_metadata:s:a 0:g out.mkv

      -

      注意这里简单的0在这里能正常工作是因为全局元数据是默认访问的。

      -
    • -
    -
  • -
  • -map_chapters input_file_index (output):从输入文件中复制由input_file_index指定的章节的内容到输出。如果没有匹配的章节,则复制第一个输入文件至少一章内容(第一章)。使用负数索引则禁用所有的复制。

    -
  • -
  • -benchmark (global):在编码结束后显示基准信息。则包括CPU使用时间和最大内存消耗,最大内存消耗是不一定在所有的系统中被支持,它通常以显示为0表示不支持。

    -
  • -
  • -benchmark_all (global):在编码过程中持续显示基准信息,则包括CPU使用时间(音频/视频 的 编/解码)

    -
  • -
  • -timelimit duration (global):ffmpeg在编码处理了duration秒后退出。

    -
  • -
  • -dump (global):复制每个输入包到标准输出设备

    -
  • -
  • -hex (global):复制包时也复制荷载信息

    -
  • -
  • -re (input):以指定帧率读取输入。通常用于模拟一个硬件设备,例如在直播输入流(这时是读取一个文件)。不应该在实际设备或者在直播输入中使用(因为这将导致数据包的丢弃)。默认ffmpeg会尽量以最高可能的帧率读取。这个选项可以降低从输入读取的帧率,这常用于实时输出(例如直播流)。

    -
  • -
  • -loop_input:循环输入流。当前它仅作用于图片流。这个选项主要用于FFserver自动化测试。这个选项现在过时了,应该使用-loop 1

    -
  • -
  • -loop_output number_of_times:重复播放number_of_times次。这是对于GIF类型的动画(0表示持续重复而不停止)。这是一个过时的选项,用-loop替代。

    -
  • -
  • -vsync parameter:视频同步方式。为了兼容旧,常被设置为一个数字值。也可以接受字符串来作为描述参数值,其中可能的值是:

    -
      -
    • 0,passthrough:每个帧都通过时间戳来同步(从解复用到混合)。

      -
    • -
    • 1,cfr:帧将复制或者降速以精准达到所要求的恒定帧速率。

      -
    • -
    • 2,vfr:个别帧通过他们的时间戳或者降速以防止2帧具有相同的时间戳

      -
    • -
    • drop:直接丢弃所有的时间戳,而是在混合器中基于设定的帧率产生新的时间戳。

      -
    • -
    • -1,auto:根据混合器功能在1或者2中选择,这是默认值。

      -

      注意时间戳可以通过混合器进一步修改。例如avoid_negative_ts被设置时。

      -

      利用-map你可以选择一个流的时间戳作为凭据,它可以对任何视频或者音频 不改变或者重新同步持续流到这个凭据。

      -
    • -
    -
  • -
  • -frame_drop_threshold parameter:丢帧的阀值,它指定后面多少帧内可能有丢帧。在帧率计数时1.0是1帧,默认值是1.1。一个可能的用例是避免在混杂的时间戳或者需要增加精准时间戳的情况下确立丢帧率。

    -
  • -
  • -async samples_per_second:音频同步方式。”拉伸/压缩”音频以匹配时间戳。参数是每秒最大可能的音频改变样本。-async 1是一种特殊情况指只有开始时校正,后续不再校正。

    -

    注意时间戳还可以进一步被混合器修改。例如avoid_negative_ts选项被指定时

    -

    已不推荐这个选项,而是用aresample音频滤波器代替。

    -
  • -
  • -copyts:不处理输入的时间戳,保持它们而不是尝试审核。特别是不会消除启动时间偏移值。

    -

    注意根据vsync同步选项或者特定的混合器处理流程(例如格式选项avoid_negative_ts被设置)输出时间戳会忽略匹配输入时间戳(即使这个选项被设置)

    -
  • -
  • -start_at_zero:当使用-copyts,位移输入时间戳作为开始时间0.这意味着使用该选项,同时又设置了-ss,例如-ss 50则输出中会从50秒开始加入输入文件时间戳。

    -
  • -
  • ```
    -copytb mode

    -
    1
    2
    3

    :指定当流复制时如何设置编码时间基准。

    -

    mode

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69

    参数是一个整数值,可以有如下可能:

    - `1`表示使用分离器时间基准,从分离器中复制时间戳到编码中。复制可变帧率视频流时需要避免非单调递增的时间戳。
    - `0`表示使用解码器时间基准,使用解码器中获取的时间戳作为输出编码基准。
    - `-1`尝试自动选择,只要能产生一个正常的输出,这是默认值。

    - `-shortest (output)`:完成编码时最短输入端。

    - `-dts_delta_threshold`:时间不连续增量阀值。

    - `-muxdelay seconds (input)`:设置最大 解复用-解码 延迟。参数是秒数值。

    - `-maxpreload seconds (input)`:设置初始的 解复用-解码延迟,参数是秒数值。

    - `-streamid output-stream-index:new-value (output)`:强制把输出文件中序号为output-stream-id的流命名为new-value的值。这对应于这样的场景:在存在了多输出文件时需要把一个流分配给不同的值。例如设置0号流为33号流,1号流为36号流到一个mpegts格式输出文件中(这相当于对流建立链接/别名):

    > ffmpeg -i infile -streamid 0:33 -streamid 1:36 out.ts

    - `-bsf[:stream_specifier] bitstream_filters (output,per-stream)`:为每个匹配流设置bit流滤镜。`bitstream_filters`是一个逗号分隔的bit流滤镜列表。可以使用`-bsfs`来获得当前可用的bit流滤镜。

    > ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264 ffmpeg -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt

    - `-tag[:stream_specifier codec_tag (input/output,per-stream`:为匹配的流设置标签/fourcc。

    - `-timecode hh:mm:ssSEDff`:指定时间码,这里`SEP`如果是`:`则不减少时间码,如果是`;`或者`.`则可减少。

    > ffmpeg -i input.mpg -timecode 01:02:03.04 -r 30000/1001 -s ntsc output.mpg

    - `-filter_complex filtergraph (global)`:定义一个复合滤镜,可以有任意数量的输入/输出。最简单的滤镜链图至少有一个输入和一个输出,且需要相同类型。参考`-filter`以获取更多信息(更有价值)。`filtergraph`用来指定一个滤镜链图。关于`滤镜链图的语法`可以参考`ffmpeg-filters`相关章节。

    其中输入链标签必须对应于一个输入流。filtergraph的具体描述可以使用`file_index:stream_specifier`语法(事实上这同于`-map`)。如果`stream_specifier`匹配到了一个多输出流,则第一个被使用。滤镜链图中一个未命名输入将匹配链接到的输入中第一个未使用且类型匹配的流。

    使用`-map`来把输出链接到指定位置上。未标记的输出会添加到第一个输出文件。

    **注意**这个选项参数在用于`-lavfi`源时不是普通的输入文件。 > ffmpeg -i video.mkv -i image.png -filter_complex '[0:v][1:v]overlay[out]' -map '[out]' out.mkv

    这里`[0:v]`是第一个输入文件的第一个视频流,它作为滤镜的第一个(主要的)输入,同样,第二个输入文件的第一个视频流作为滤镜的第二个输入。

    假如每个输入文件只有一个视频流,则我们可以省略流选择标签,所以上面的内容在这时等价于:

    > ffmpeg -i video.mkv -i image.png -filter_complex 'overlay[out]' -map '[out]' out.mkv

    此外,在滤镜是单输出时我们还可以进一步省略输出标签,它会自动添加到输出文件,所以进一步简写为:

    > ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv

    利用`lavfi`生成5秒的 红`color`(色块):

    > ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv

    - `-lavfi filtergraph (global)`:定义一个复合滤镜,至少有一个输入和/或输出,等效于`-filter_complex`。

    - `-filter_complex_script filename (global)`:这个选项类似于`-filter_complex`,唯一不同就是它的参数是文件名,会从这个文件中读取复合滤镜的定义。

    - `-accurate_seek (input)`:这个选项会启用/禁止输入文件的精确定位(配合`-ss`),它默认是启用的,即可以精确定位。需要时可以使用`-noaccurate_seek`来禁用,例如在复制一些流而转码另一些的场景下。

    - `-seek_timestamp (input)`:这个选项配合`-ss`参数可以在输入文件上启用或者禁止利用时间戳的定位。默认是禁止的,如果启用,则认为`-ss`选项参数是正式的时间戳,而不是由文件开始计算出来的偏移。这一般用于具有不是从0开始时间戳的文件,例如一些传输流(直播下)。

    - `-thread_queue_size size (input)`:这个选项设置可以从文件或者设备读取的最大排队数据包数量。对于低延迟高速率的直播流,如果不能及时读取,则出现丢包,所以提高这个值可以避免出现大量丢包现象。

    - `-override_ffserver (global)`:对`ffserver`的输入进行指定。使用这个选项`ffmpeg`可以把任意输入映射给`ffserver`并且同时控制很多编码可能。如果没有这个选项,则`ffmpeg`仅能根据`ffserver`所要求的数据进行传输。

    这个选项应用场景是`ffserver`需要一些特性,但文件/设备不提供,这时可以利用`ffmpeg`作为中间处理环节控制后输出到`ffserver`到达所需要求。

    - `-sdp_file file (global)`:输出`sdp`信息到文件`file`。它会在至少一个输出不是`rtp`流时同时输出`sdp`信息。

    - ```
    -discard (input)
    -

    :允许丢弃特定的流或者分离出的流上的部分帧,但不是所有的分离器都支持这个特性。

    -
      -
    • none:不丢帧
    • -
    • default:丢弃无效帧
    • -
    • noref:丢弃所有非参考帧
    • -
    • bidir:丢弃所有双向帧
    • -
    • nokey:丢弃所有非关键帧
    • -
    • all:丢弃所有帧
    • -
    -
  • -
  • -xerror (global):在出错时停止并退出

    -
  • -
-

作为一个特殊的例外,你可以把一个位图字幕(bitmap subtitle)流作为输入,它将转换作为同于文件最大尺寸的视频(如果没有视频则是720x576分辨率)。注意这仅仅是一个特殊的例外的临时解决方案,如果在libavfilter中字幕处理方案成熟后这样的处理方案将被移除。

-

例如需要为一个储存在DVB-T上的MPEG-TS格式硬编码字幕,而且字幕延迟1秒: > ffmpeg -i input.ts -filter_complex \ ‘[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay’ \ -sn -map ‘#0x2dc’ output.mkv

-

(0x2d0, 0x2dc 以及 0x2ef 是MPEG-TS 的PIDs,分别指向视频、音频和字幕流,一般作为MPEG-TS中的0:0,0:3和0:7是实际流标签)

-

预设文件

一个预设文件是选项/值对的序列(option=value),每行都是一个选项/值对, 用于指定一系列的选项,而这些一般很难在命令行中指定(限于命令行的一些限制,例如长度限制)。以#开始的行是注释,会被忽略。一般ffmpeg会在目录树中检查presets子目录以获取预设文件。

-

有两种类型的预设文件:ffpreset 和 avpreset。

-
ffpreset类型预设文件

采用ffpreset类型预设文件主要包含vpreapresprefpre选项。其中fpre选项的参数可以代替预设的名称作为输入预设文件名,以用于任何一种编码格式。对于vpreaprespre选项参数会指定一个预设定文件用于当前编码格式以替代(作为)同类项的预订选项。

-

选用预设文件传递vpreaprespre的参数arg有下面一些搜索应用规则:

-
    -
  • 将在目录$FFMPEG_DATADIR(如果设置了)和$HOME/.ffmpeg目录和配置文件中定义的数据目录(一般是PREFIX/share/ffmpeg),以及ffpresets所在的执行文件目录下ffmpeg搜索对应的预定义文件arg.ffpreset,例如参数是libvpx-1080p,则对应于文件libvpx-1080p.ffpreset
  • -
  • 如果没有该文件,则进一步在前述目录下搜索codec_name-arg.ffpreset文件,如果找到即应用。例如选择了视频编码器-vcodec libvpx-vpre 1080p则对应的预设文件名是libvpx-1080p.ffpreset
  • + +
+ + + + + + + +
+ + + + + +
+

+ + +

+ + +
+ + + + +
+ + +

YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications

YOLOv6发现以往的模型存在以下问题:

    +
  • 来自RepVGG的重参数化是一种尚未在检测中得到很好利用的优越技术。我们还注意到,对于RepVGG块,简单的模型缩放变得不切实际,因此我们认为小型和大型网络之间的网络设计的优雅一致性是不必要的。对于小型网络,简单的单路径架构是更好的选择,但对于大型模型,单路径架构的参数和计算成本的指数增长使其不可行
  • +
  • 基于重参数化的检测器的量化也需要细致的处理,否则在训练和推理过程中由于其异构配置而导致的性能下降将难以处理。
  • +
  • 以前的工作往往不太关注部署,其延迟通常在V100等高成本机器上进行比较。当涉及到真正的服务环境时,存在硬件差距。通常,像Tesla T4这样的低功耗gpu成本更低,并且提供相当好的推理性能。
  • +
  • 考虑到架构差异,标签分配和损失函数设计等高级领域特定策略需要进一步验证;
  • +
  • 对于部署,我们可以容忍训练策略的调整,以提高精度性能,但不增加推理成本,例如知识蒸馏。
-
avpreset类型预设文件

avprest类型预设文件以pre选项引入。他们工作方式类似于ffpreset类型预设文件(即也是选项值对序列),但只对于特定编码器选项,因此一些 选项值 对于不适合的编码器是无效的。根据pre的参数arg查找预设文件基于如下规则:

-
    -
  • 首先搜索$AVCONV_DATADIR所指目录(如果定义了),其次搜索$HOME/.avconv目录,然后搜索执行文件所在目录(通常是PREFIX/share/ffmpeg),在其下查找arg.avpreset文件。第一个匹配的文件被应用。
  • -
  • 如果查找不到,如果还同步还指定了编码(如-vcodec libvpx)再以前面目录顺序,以codec_name-arg.avpreset再次查找文件。例如对于有选项-vcodec libvpx-pre 1080p将搜索libvpx-1080p.avpreset
  • -
  • 如果还没有找到,将在当前目录下搜索arg.avpreset文件
  • +

    本文的主要工作

      +
    • 我们重新设计了一系列不同规模的网络,为不同场景的工业应用量身定制。
    • +
    • 不同规模的架构不同,以实现最佳的速度和精度权衡,其中小模型具有简单的单路径主干,而大模型构建在高效的多分支块上。
    • +
    • 我们为YOLOv6注入了一种自蒸馏策略,同时执行分类任务和回归任务。同时,我们动态调整来自老师和标签的知识,帮助学生模型在所有训练阶段更有效地学习知识。
    • +
    • 我们广泛验证了标签分配、损失函数和数据增强技术的先进检测技术,并有选择地采用它们来进一步提高性能。
    • +
    • 我们在RepOptimizer和通道式蒸馏的帮助下,对检测的量化方案进行了改革,这导致了一个永远快速和准确的检测器,在batchsize大小为32时,具有43.3%的COCO AP和869 FPS的吞吐量。
    -

    例子

    视频和音频抓取

    如果你指定了输入格式和设备,ffmpeg可以直接抓取视频和音频:

    -
    -
    1
    ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
    -
    -

    或者采用ALSA音频源(单声道,卡的id是1)替代OSS:

    -
    -
    1
    ffmpeg -f alsa -ac 1 -i hw:1 -f video4linux2 -i /dev/video0 /tmp/out.mpg
    -
    -

    注意对于不同的视频采集卡,你必须正确激活视频源和通道,例如Gerd Knorr的xawtv。你还需要设置正确的音频记录层次和混合模式。只有这样你才能采集到想要的视音频。

    -

    X11显示的抓取

    可以通过ffmpeg直接抓取X11显示内容:

    -
    -
    1
    ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0+10,20 /tmp/out.mpg
    -

    0.0是X11服务的显示屏幕号(display.screen),定义于DISPLAY环境变量。10是水平偏移,20是垂直偏移

    -
    -

    视频和音频文件格式转换

    任何支持的文件格式或者协议都可以作为ffmpeg输入。例如:

    -
      -
    • 你可以使用YUV文件作为输入

      -
      -

      ffmpeg -i /tmp/test%d.Y /tmp/out.mpg

      -
      -

      这里可能是这样一些文件

      -
      -

      /tmp/test0.Y, /tmp/test0.U, /tmp/test1.V, /tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc…

      -
      -

      这里Y还有对应分辨率的2个关联文件U和V。这是一种raw数据文件而没有文件头,它可以被所有的视频解码器生成。你必须利用-s对它指定一个尺寸而不是让ffmpeg去猜测。

      -
    • -
    • 你可以把raw YUV420P文件作为输入:

      -
      -

      ffmpeg -i /tmp/test/yuv /tmp/out.avi

      -
      -

      test.yuv 是一个包含raw YUV通道数据的文件。每个帧先是Y数据,然后是U和V数据。

      -
    • -
    • 也可以输出YUV420P类型的文件

      -
      -

      ffmpeg -i mydivx.avi hugefile.yuv

      -
      -
    • -
    • 可以设置一些输入文件和输出文件

      -
      -

      ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg

      -
      -

      这将转换一个音频和raw的YUV视频到一个MPEG文件中

      -
    • -
    • 你也可以同时对音频或者视频进行转换

      -
      -

      ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2

      -
      -

      这里把a.wav转换为MPEG音频,同时转换了采样率为22050HZ

      -
    • -
    • 你也可以利用映射同时编码多个格式作为输入或者输出:

      -
      -

      ffmpeg -i /tmp/a.wav -map 0:a -b:a 64k /tmp/a.mp2 -map 0:a -b:a 128k /tmp/b.mp2

      -
      -

      这将同时把a.wav以64k码率输出到a.mp2,以128k码率输出到b.mp2。 “-map file:index”指定了对于每个输出是连接到那个输入流的。

      -
    • -
    • 还可以转换解码VOBs:

      -
      -

      ffmpeg -i snatch_1.vob -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi

      -
      -

      这是一个典型的DVD抓取例子。这里的输入是一个VOB文件,输出是MPEG-4编码视频以及MP3编码音频的AVI文件。注意在这个命令行里使用了B-frames(B帧)是兼容DivX5的,GOP设置为300则意味着有一个内帧是适合29.97fps的输入视频。此外,音频流采用MP3编码需要运行LAME支持,它需要通过在编译是设置--enable-libmp3lame。这种转换设置在多语言DVD抓取转换出所需的语言音频时特别有用。

      -

      注意要了解支持那些格式,可以采用ffmpeg -formats

      -
    • -
    • 可以从一个视频扩展生成图片(序列),或者从一些图片生成视频:

      +

      使用的方法&模型的具体结构

      img

        -
      • 导出图片

        -
        -

        ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg

        -
        -

        这将每秒依据foo.avi生成一个图片命名为foo-001.jpeg ,foo-002.jpeg以此类推,图片尺寸是WxH定义的值。

        -

        如果你想只生成有限数量的视频帧,你可以进一步结合-vframes或者-t或者-ss选项实现。

        -
      • -
      • 从图片生成视频

        -
        -

        ffmpeg -f image2 -framerate 12 -i foo-%03d.jpeg -s WxH foo.avi

        -
        -

        这里的语法foo-%03d.jpeg指明使用3位数字来补充完整文件名,不足3位以0补齐。这类似于C语言的printf函数中的格式,但只接受常规整数作为部分。

        -

        当导入一个图片序列时,-i也支持shell的通配符模式(内置的),这需要同时选择image2的特性选项-pattern_type glob:例如下面就利用了所有匹配foo-*.jpeg的图片序列创建一个视频:

        -
        -

        ffmpeg -f image2 -pattern_type glob -framerate 12 -i ‘foo-*.jpeg’ -s WxH foo.avi

        -
        -
      • +
      • 网络设计:
          +
        • backbone:与其他主流架构相比,我们发现在相似的推理速度下,RepVGG骨干网在小型网络中具有更强的特征表示能力,但由于参数和计算成本的爆炸式增长,它难以扩展以获得更大的模型。在这方面,我们将RepBlock作为我们小型网络的构建块。对于大型模型,我们修改了一个更有效的CSP块,命名为CSPStackRep块。
        • +
        • neck:YOLOv6的颈部在YOLOv4和YOLOv5之后采用PAN拓扑。我们用RepBlocks或CSPStackRep Blocks增强颈部以获得RepPAN。
        • +
        • head:我们简化了解耦头,使其更高效,称为高效解耦头。
      • -
      • 你可以把很多相同类型的流一起放到一个输出中:

        -
        -

        ffmpeg -i test1.avi -i test2.avi -map 1:1 -map 1:0 -map 0:1 -map 0:0 -c copy -y test12.nut

        -
        -

        这里最后输出文件test12.nut包括了4个流,其中流的顺序完全根据前面-map的指定顺序。

        -
      • -
      • 强制为固定码率编码(CBR)输出视频:

        -
        -

        ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v

        -
        -
      • -
      • 使用lambda工具的4个选项lminlmaxmblmin以及mblmax使你能更简单的从q转换到QP2LAMBDA:

        -
        -

        ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext

        -
        -
      • +
      • 标签分配:我们通过大量实验评估了标签分配策略的最新进展,结果表明TAL更有效,更适合训练。
      • +
      • 损失函数:主流无锚目标检测器的损失函数包含分类损失,anchor回归损失和对象损失。对于每一种损失,我们系统地用所有可用的技术进行实验,最终选择VariFocal loss作为我们的分类损失,SIoU/GIoU loss作为我们的回归损失
      • +
      • 行业便利的改进:我们引入了额外的常见做法和技巧来提高性能,包括自蒸馏更多的训练epoch。分类和anchor回归分别由教师模型监督。由于DFL,anchor回归的精馏成为可能。此外,通过余弦衰减动态衰减软、硬标签信息的比例,帮助学员在训练过程中有选择地获取不同阶段的知识。此外,我们在评估中遇到了没有增加额外灰色边界的性能受损问题,对此我们提供了一些补救措施。
      • +
      • 量化和部署:为了解决基于再参数化的量化模型的性能下降问题,我们使用RepOptimizer训练YOLOv6,以获得ptq友好的权重。我们进一步采用QAT与通道智能蒸馏和图优化来追求极致的性能。
      +

      Network Design

      ​ 单阶段物体探测器通常由以下几个部分组成:主干、颈部和头部。主干网主要决定了特征表示能力,而其设计由于计算成本较大,对推理效率的影响很大。颈部用于将低级的物理特征与高级的语义特征进行聚合,然后在所有层次上建立金字塔形特征映射。头部由几个卷积层组成,并根据颈部组装的多层次特征来预测动态检测结果。从结构的角度来看,它可以分为基于锚头和无锚头,或者是参数耦合头和参数解耦头。

      +

      ​ 在YOLOv6中,基于硬件友好的网络设计的原则,我们提出了两个缩放的可再参数化的骨干和颈,以适应不同大小的模型,以及一个有效的解耦与混合通道策略的头。YOLOv6的整体架构如图所示。

      +

      img

      +

      Backbone

      ​ 多分支网络通常比单路径网络具有更好的分类性能,但它往往伴随着并行性的降低,并导致推理延迟的增加。相反,像VGG这样的普通单路网络具有高并行性和更少的内存占用的优点,从而获得了更高的推理效率。最近在RepVGG中,提出了一种结构重参数化方法,将训练时间的多分支拓扑与推理时间的平面架构解耦,以实现更好的速度精度权衡。

      +

      受上述工作的启发,我们设计了一个高效的可重新参数化的骨干,称为EffificientRep。对于小模型,训练阶段骨干的主要成分是RepBlock,如下图所示在推理阶段,每个RepBlock转换为3×3卷积层(表示为RepConv),具有ReLU激活函数,3×3卷积在主流gpu和cpu上得到了高度优化,并且它具有更高的计算密度。因此,高效的代表骨干网充分利用了硬件的计算能力,从而显著降低了推理延迟,同时提高了表示能力。

      +

      ​ 然而,随着模型容量的进一步扩大,单路网络中的计算成本和参数数量呈指数级增长。为了更好地实现计算负担和准确性之间的权衡,我们修改了CSPStackRep块来构建中大型网络的主干。如图所示,CSPStackRepBlock由三个1×1卷积层和一堆由两个RepVGGBlock或RepConv(分别在训练或推理时)组成,具有残差连接。此外,采用跨阶段部分(CSP)连接,在不增加计算成本的情况下提高性能。

      +

      img

      +

      Neck

      采用YOLO v4和YOLO v5的PAN结构,将RepBlock(用于小型模型)或CSPStackRep块替换为YOLOv5中使用的CSPBlock),并相应地调整宽度和深度。YOLOv6的颈部被表示为Rep-PAN。

      +

      Effificient decoupled head: YOLOv5的检测头是一个耦合头,分类和定位分支共享参数,而FCOS和YOLOX的检测头将两个分支解耦,并在每个分支中额外引入两个3×3卷积层来提高性能。在YOLOv6中,我们采用了一种混合信道策略来构建一个更有效的解耦头。具体来说,我们将中间的3个3×3卷积层的数量减少到只有一个。头部的宽度由主干和颈部的宽度乘数共同缩放。这些修改进一步降低了计算成本,以实现更低的推理延迟。

      +

      Achor-free: Achor-free检测头因其更好的泛化能力和解码预测结果的简单性而脱颖而出。其后处理的时间成本大大降低了。无锚点探测器有两种类型的无锚点检测器:基于锚点的和基于关键点的。在YOLOv6中,我们采用了基于锚点的范式,其框回归分支实际上预测了从锚点到边界框四边的距离。

      +

      Label Assignment

      ​ 标签分配负责在训练阶段为预定义的锚点分配标签。先前的工作提出了各种标签分配策略,从简单的基于iou的策略和内部地面真值方法到其他更复杂的方案。

      +

      SimOTA OTA认为目标检测中的标签分配是一个最优的传输问题。它从全局的角度为每个地面真实对象定义了正/负的训练样本。SimOTA是OTA的一个简化版本,它减少了额外的超参数并保持了性能。在YOLOv6的早期版本中,使用了SimOTA作为标签分配方法。然而,在实践中,我们发现引入SimOTA会减慢培训过程。而且经常陷入不稳定的训练。因此,我们希望有一个替代SimOTA。

      +

      Task alignment learning 任务对齐学习(TAL)首次在TOOD中提出,其中设计了一个统一的分类分数和预测框质量的统一度量。用此度量替换IoU以分配对象标签。在一定程度上,缓解了任务(分类和预测框回归)的错位问题。TOOD的另一个主要贡献是关于任务状头(T-head)。T-head堆栈卷积层来构建交互式特性,在此之上使用了任务对齐预测器(TAP)。PP-YOLOE用轻量级ESE注意取代T-head的层注意,形成ET-head。然而,我们发现ET-head会恶化我们模型的推理速度,它没有精度增益。因此,我们保留了我们的高效解耦头的设计。

      +

      此外,我们观察到TAL比SimOTA带来更多的性能改善,稳定训练。因此,我们在YOLOv6中采用TAL作为默认的标签分配策略。

      +

      Loss Functions

      ​ 对象检测包含两个子任务:分类和定位,对应于两个损失函数:分类损失和预测框回归损失。对于每个子任务,近年来都有各种不同的损失函数。在本节中,我们将介绍这些损失函数,并描述我们如何为YOLOv6选择最佳的损失函数。

      +

      Classifification Loss

      ​ 提高分类器的性能是优化检测器的关键部分。Focal Loss改进了传统的交叉熵损失,解决了正负样本或硬易样本之间的类不平衡问题。为了解决训练和推理之间质量估计和分类使用不一致的问题,Quality Focal Loss(QFL)进一步扩展了Focal Loss,并将分类评分和定位质量联合表示出来进行分类监督。而VariFocal Loss (VFL)来源于Focal Loss,但它不对称地处理正样本和负样本。通过考虑不同重要程度的正样本和负样本,它平衡了来自两个样本的学习信号。Poly Loss将常用的分类损失分解为一系列加权多项式基。它在不同的任务和数据集上调整多项式系数,通过实验证明了其优于交叉熵损失和焦点损失。

      +

      ​ 我们评估了YOLOv6上的所有这些高级分类损失,并最终采用了VFL 。

      +

      Box Regression Loss

      ​ 预测框回归损失提供了重要的学习信号精确的定位边界框。L1损失是早期工作中原始的预测框回归损失。逐渐地,各种设计良好的预测框回归损失已经出现,如iou系列损失和概率损失。

      +

      IoU-series Loss IoU损失回归了一个预测框作为一个整体单位的四个边界。由于它与评价度量的一致性,它已被证明是有效的。IoU有许多变体,如GIoU、DIoU、CIoU、α-IoU和SIoU等,形成了相关的损失函数。我们用GIoU、CIoU和SIoU进行了实验。而SIOU应用于YOLOv6-N和YOLOv6-T,而其他的则使用GIoU。

      +

      Probability Loss Distribution Focal Loss(DFL)将预测框位置的基本连续分布简化为一个离散的概率分布。它在不引入任何其他强先验的情况下考虑数据中的模糊性和不确定性,有助于提高预测框的定位精度,特别是在地面-真值盒的边界模糊的情况下。在DFL的基础上,DFLv2 开发了一个轻量级的子网络,以利用分布统计数据与真实定位质量之间的密切相关性,进一步提高了检测性能。然而,DFL通常比一般的预测框回归多输出17×的回归值,这导致了大量的开销。额外的计算成本明显地阻碍了对小模型的训练。而DFLv2则由于额外的子网络而进一步增加了计算负担。在我们的实验中,DFLv2在我们的模型上带来了与DFL相似的性能增益。因此,我们只在YOLOv6-M/L中采用DFL。实验细节见第3.3.3节。

      +

      Object Loss

      ​ Object loss首先是在FCOS中提出的,以降低低质量的边界框的得分,以便在后处理中可以过滤掉它们。它也被用于YOLOX来加速收敛和提高网络精度。作为像FCOS和YOLOX这样的无锚框架,我们尝试在YOLOv6中使用ObjectLoss。不幸的是,它并没有带来许多积极的影响。

      +

      Industry-handy improvements

      More training epochs

      ​ 实验结果表明,训练时间越长,探测器就具有进步的性能。我们将训练从300个epochs延长到400个epochs,以达到更好的收敛性。

      +

      Self-distillation

      ​ 为了进一步提高模型的准确性,同时不引入太多额外的计算成本,我们采用经典的知识蒸馏技术来最小化教师模型和学生模型之间预测的KL散度。我们限制教师模型是预先训练的学生模型,因此我们称之为自我蒸馏。请注意,kl-散度通常用于度量数据分布之间的差异。然而,在目标检测中有两个子任务,其中只有分类任务可以直接利用基于kl-散度的知识精馏。由于DFL损失[20],我们也可以在预测框回归上执行它。知识蒸馏损失可以表述为:

      +

      img

      +

      ​ 其中imgimg分别为教师模型和学生模型的类别预测,因此imgimg为预测框回归预测。总体损失函数现在可以表述为:

      +

      img

      +

      ​ 其中,Ldet是用预测和标签计算出的检测损失。引入超参数α来平衡两个损失。在训练的早期阶段,从教师模型那里得到的软标签更容易学习。随着训练的继续,学生模型的表现将与教师模型相匹配,这样硬标签将对学生更有帮助。在此基础上,我们将余弦权值衰减应用于α,以动态调整来自教师的硬标签和软标签的信息。

      +

      Gray border of images

      ​ 我们注意到,在评估YOLOv5 和YOLOv7 实现中的模型性能时,在每个图像周围都设置了一个半步幅的灰色边界。虽然没有添加任何有用的信息,但它有助于检测图像边缘附近的物体。这个技巧也适用于YOLOv6。 然而,额外的灰度像素明显降低了推理速度。如果没有灰色边框,YOLOv6的性能就会恶化。我们假设该问题与Mosaic augmentation中的灰色边界填充有关。实验在关闭mosaic增强在最后的epochs进行验证。在这方面,我们改变了灰度边界的面积,并将具有灰度边界的图像的大小直接调整为目标图像的大小。结合这两种策略,我们的模型可以保持甚至提高性能,而不降低推理速度。

      +

      Quantization and Deployment

      ​ 对于工业部署,通常的做法是采用量化以进一步加快运行时,而不会影响太多性能。训练后量化(PTQ)直接用一个小的校准集对模型进行量化。而量化感知训练(QAT)进一步提高了对训练集的访问的性能,这通常与蒸馏联合使用。然而,由于在YOLOv6中大量使用重新参数化块,以前的PTQ技术不能产生高性能,而在训练和推理过程中匹配假量化器时,很难合并QAT。我们在这里展示了在部署期间的陷阱和我们的解决方法。

      +

      Reparameterizing Optimizer

      ​ RepOptimizer在每个优化步骤中提出梯度重新参数化。该技术也能很好地解决了基于再参数化的模型的量化问题。因此,我们以这种方式重建了YOLOv6的重新参数化块,并使用重新优化器对其进行训练,以获得对PTQ友好的权值。特征图的分布很窄,这大大有利于量化过程。

      +

      img

      +

      Sensitivity Analysis

      ​ 我们通过将量化敏感操作部分转换为浮点计算,进一步提高了PTQ的性能。为了获得灵敏度分布,我们常用了几个指标,即均方误差(MSE)、信噪比(SNR)和余弦相似度。通常,为了进行比较,可以选择输出特征映射(在激活某一层之后)来计算有量化和没有量化的这些度量。作为一种替代方法,它也可以通过开关特定层的量化来计算验证AP。

      +

      ​ 我们在使用重新优化器训练的YOLOv6-S模型上计算所有这些指标,并选择前6个敏感层,以浮动形式运行。敏感性分析的完整图表见B.2。

      +

      img

      +

      Quantization-aware Training with Channel-wise Distillation

      在PTQ不足的情况下,我们建议涉及量化感知训练(QAT)来提高量化性能。为了解决在训练和推理过程中假量化器的不一致性问题,有必要在重新优化器上建立QAT。此外,在YOLOv6框架内采用了通道蒸馏(后来称为CW蒸馏),如图5所示。这也是一种自蒸馏的方法,其中教师网络是在fp32精度上的学生模型。参见第3.5.1节中的实验。

      +

      cda38d2ac2884096b174b6dc66edbb6e

@@ -1910,7 +985,7 @@

- +

- +