【CNN基础】计算机如何计算卷积操作

0. 前言

对于卷积操作我们都很清楚其具体过程,不过卷积操作是如何在计算机上实现的呢?

我们当然可以按照卷积的操作那样去用一系列的for循环来实现,但效率很低下,而矩阵的乘法可以被高度优化和加速,且目前有很多现成的算法和加速包。于是问题就转换为:我们能否把卷积操作转换为矩阵的乘法?

实际上是可以的,而且还非常简单易懂。

1. 把卷积操作转换为矩阵乘法

我们先来快速回顾一下卷积的操作:假设卷积核大小为3x3,则feature map在原图上的一个感受野大小为3x3,将感受野在原图上进行滑动(一般步长stride=1),就可以得到一张feature map。D个卷积核就会得到D个feature map。

具体如何计算feature map的大小可以参考我的这篇博客:【CNN基础】计算卷积操作输出Feature Map的size
在这里插入图片描述

1.1 将卷积核化为矩阵

我们假设在某一层有D个卷积核,尺寸为K x K x C(即有C个channel,说明输入的feature map有C个channel)
在这里插入图片描述
我们把每一个KxKxC维度的卷积核拆成一个K2C长度的行向量,把D个K2C长度的行向量按行堆叠,就形成了一个Dx(K2C)的二维矩阵,如下所示:
在这里插入图片描述

1.2 将输入的Feature Map化为矩阵

我们假设输入的feature map尺寸为H x W x C,H、W为高和宽,C代表C个channel,如下图所示(卷积核大小为K x K x C)。
在这里插入图片描述

我们知道,感受野会在整个输入图像中滑动,每次滑动一个stride,假设感受野在整张图象上滑动N次。从上图可以看出,一个感受野为一K x K x C的矩形,我们将其拉伸为K2C个元素列向量,如下图所示:

在这里插入图片描述
由于感受野在输入图像上滑动了N次,每次都会产生一个K2C的列向量,我们把这些列向量按列堆叠,就形成了一个(K2C)xN的二维矩阵,如下所示:
在这里插入图片描述

1.3 矩阵乘法

我们将卷积核转换成的Dx(K2C)矩阵与输入的feature map经过感受野滑动得到的(K2C)xN矩阵进行相乘,得到DxN的二维矩阵,如下所示:

在这里插入图片描述
图片来源:同济子豪兄

最终输出D x N的二维向量的每一行代表:一个卷积核生成的feature map拉成的行向量(共N个元素)

END :)

猜你喜欢

转载自blog.csdn.net/qq_44166630/article/details/124168655