说卷积实现是基于GEMM矩阵乘法还是基于1x1内核是什么意思?

问题描述

我一直试图理解(但不幸的是失败了)如何在软件中实现图像(包括高度,宽度,通道)上的卷积

我听说人们说他们的卷积实现是使用Gemm完成的,或者是使用“直接卷积”完成的,或者是使用1x1内核完成的。

我发现它非常令人困惑,无法用各种各样的方式来描述它-我认为,我将pytorch conv2d这样的典型卷积理解为对图片,但是当有人说他们使用以下一种方式进行conv2d时,这意味着什么?

对于使用Gemm进行卷积,基于this paper的理解是,使用im2colim2row ops然后将这些输入图像和滤镜分别转换为2d矩阵两个简单地乘以矩阵。

将3d输入图像(高度,宽度,输入通道)转换为2d矩阵,将4d内核(输出通道,输入通道,内核高度,内核宽度)转换为2d矩阵。还是“基于Gemm卷积实现”还有其他含义?如果那是什么意思,那么与“使用1x1内核进行卷积”有什么不同?

解决方法

1x1内核或1x1卷积(内核在这里甚至意味着什么)

您可以进行3x3卷积,因此有一个正方形,其中包含9个在图像上滑动的元素(具有某些指定的步幅,膨胀等)。在这种情况下,您有1x1卷积,因此内核是单个元素(也有stride=1并且没有膨胀)。

因此,您无需使用求和即可滑动窗口,而只需使用此单值内核线性投影每个像素即可。

这是一种廉价的操作,被用作许多现代体系结构中的深度可分离卷积的一部分,以增加/减少通道数。

GEMM

在您提供的文章中,排在最前面:

[...]函数称为GEMM。它是BLAS(基本线性代数)的一部分 子程序)

因此BLAS是一个规范,它描述了一组低级代数运算以及应如何在计算机上执行它们。

现在,您拥有针对特定体系结构量身定制的BLAS的许多实现,或具有在某些情况下可用的某些特征。例如,有cuBLAS是为GPU编写和优化的(并由PyTorch之类的深度学习“高级”库大量使用),或者是Intel's MKL是针对Intel CPU的(您可以在网络)

通常,这些代码是使用低级(Fortran,C,Assembly,C ++)语言编写的,以实现最佳性能。

GEMM是通用化矩阵乘法例程,用于实现完全连接的层和卷积,并由各种BLAS实现提供。 它与深度学习卷积本身无关,它是一种快速的矩阵乘法例程(考虑诸如高速缓存命中之类的事情)

直接卷积

这是一种O(n^2)复杂性的方法,因此您可以简单地将项目彼此相乘​​。使用O(n*log(n))的快速傅里叶变换是一种更有效的方法。一些信息presented in this answer和有关此部分的问题将更适合与数学相关的stackexchanges。