OpenCV 4.10.0
开源计算机视觉
|
上一篇教程: 如何启用 Halide 后端以提高效率
下一篇教程: OpenCV 与 OpenVINO 的使用
原作者 | Dmitry Kurtaev |
兼容性 | OpenCV >= 3.3 |
Halide 代码对我们使用的每个设备都是相同的。但是为了获得满意的效率,我们应该正确地调度计算。在本教程中,我们将介绍使用 OpenCV 深度学习模块中的 Halide 后端来调度网络的方法。
为了更好地理解 Halide 调度,您可能需要阅读 @ http://halide-lang.org/tutorials 上的教程。
如果您是第一次在 OpenCV 中使用 Halide,我们建议您从 如何启用 Halide 后端以提高效率 开始。
您可以通过编写文本配置文件来调度 Halide 管道的计算。这意味着您可以轻松地向量化、并行化和管理层计算的循环顺序。将包含特定设备调度指令的文件路径传递到 cv::dnn::Net::setHalideScheduler
,然后再进行第一次 cv::dnn::Net::forward
调用。
调度配置文件表示为 YAML 文件,其中每个节点都是一个已调度函数或调度指令。
考虑使用变量 n
表示批次维度、c
表示通道、y
表示行和 x
表示列。对于拆分后的变量,使用相同前缀但分别使用 o
和 i
后缀来表示外部变量和内部变量。例如,对于范围为 [0, 10)
的变量 x
,指令 split: { x: 2 }
会给出范围为 [0, 5)
的新变量 xo
和范围为 [0, 2)
的新变量 xi
。变量名 x
在同一个调度节点中不再可用。
您可以在 opencv_extra/testdata/dnn 中找到调度示例,并将其用于调度您的网络。
由于层融合,我们只需要调度融合集的顶层。因为对于每个输出值,我们都使用融合公式。例如,如果您有三个层,依次是卷积 + 缩放 + ReLU,
融合函数类似于
因此,只有名为 relu
的函数需要调度。
有时网络使用块结构构建,这意味着某些层是相同的或非常相似。如果您想对不同的层应用相同的调度,准确到平铺或向量化因子,请在调度文件开头的 patterns
部分定义调度模式。此外,您的模式可以使用一些参数变量。
您可以让 DNN 自动调度层。只需跳过 cv::dnn::Net::setHalideScheduler
的调用。有时它甚至可能比手动调度更高效。但是,如果特定层需要手动调度,您将能够混合使用手动和自动调度方式。编写调度文件,并跳过您希望自动调度的层。