我正在尝试实现卷积神经网络,但我不明白为什么使用 im2col 操作更有效。它基本上将要乘以过滤器的输入存储在单独的列中。但是为什么不应该直接使用循环来计算卷积而不是首先执行 im2col 呢?
1 回答
好吧,你的想法是对的,在 Alex Net 中,几乎 95% 的 GPU 时间和 89% 的 CPU 时间都花在了卷积层和全连接层上。
卷积层和全连接层是使用代表通用矩阵到矩阵乘法的 GEMM 实现的。
所以基本上在 GEMM 中,我们使用一个名为的函数将卷积运算转换为矩阵乘法运算,该函数
im2col()
以一种可以通过矩阵乘法实现卷积输出的方式排列数据。现在,您可能有一个问题,而不是直接进行元素卷积,为什么我们要在其间添加一个步骤以不同的方式排列数据,然后使用 GEMM。
对此的答案是,科学程序员已经花费了数十年时间优化代码以执行大型矩阵到矩阵的乘法运算,并且非常规则的内存访问模式所带来的好处超过了任何其他损失。我们在 cuBLAS 库中有一个优化的 CUDA GEMM API,英特尔 MKL 有一个优化的 CPU GEMM,而 ciBLAS 的 GEMM API 可用于支持 OpenCL 的设备。
Element wise 卷积由于涉及不规则的内存访问而表现不佳。
反过来,
Im2col()
以矩阵乘法的内存访问规则的方式排列数据。Im2col()
虽然函数增加了很多数据冗余,但使用 Gemm 的性能优势超过了这种数据冗余。Im2col()
这就是在神经网络中使用运算的原因。此链接解释了如何
Im2col()
为 GEMM 安排数据: https ://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/