卷积的另一种解释
熟悉图像处理的童鞋一定都知道传说中的卷积定理,这个定理涉及到图像处理的一大黑科技——傅立叶变换。
关于傅立叶的高质量科普文章已经很多,这里就不多说了。套用之前看过的一个有赞的解释:如果把我们看到的图像比作一道做好的菜,那么傅立叶变换就是告诉我们这道菜具体的配料以及各种配料的用量。这个方法的神奇之处在于不管这道是如何做的(按类别码放还是大乱炖),它都能将配料清晰分出来。在图像处理中,这个配料被成为频率。其中有些信息被称作低频信息,有些被成为高频信息。
低频信息一般被我们是看作是整幅图像的基础,有点像一道菜中的主料。如果说这道菜是番茄炒蛋,那低频信息可以看作是番茄和蛋。高频信息一般是指那些变动比较大的,表达图像特点的信息,有点像一道菜的配料或者调料。对于番茄炒蛋,像是菜中调料和点缀的材料。
回到卷积中,卷积定理中说,两个矩阵的卷积的结果,等于两个矩阵在经过傅立叶变换后,进行元素级别的乘法(element-wise multiplication),然后再对结果进行反向傅立叶处理。如果我们用FFT表示傅立叶变换,IFFT表示反向傅立叶变换,那么下面两个过程结果是相同的(考虑到浮点数近似,可以认为相近就是相同):
- A = np.array()
- B = np.array() # matrix
- # method1
- C = conv2(A,B)
- #method2
- FFT_A = FFT(A)
- FFT_B = FFT(B)
- C = IFFT(FFT_A * FFT_B)
真实的代码不会像上面这样简单,但是大体来说结构也是相同的。看上去第二种方法比第一种方法啰嗦了不少,那么它的优势在哪里?
那我们就来看看上面提到的一些kernel在经过傅立叶变换后的样子:
首先是mean kernel:
然后是Sobel kernel:
最后是Gabor kernel:
我们前面说过,傅立叶变换可以帮助分析出高低频信息。在上面的图像中,(经过fft_shift的)图像的正中心是低频信息,越靠近边缘频率越高。由于最终要进行元素级的乘法,如果kernel在某个频率的数据比较低,经过乘法后输入数据在这个频率的数据也会变小。
- 如果我们把上面的图片想象成中心为原点的直角坐标系图,所以我们可以看出:
- mean kernel会把中心附近和坐标轴附近信息进行保留;
- Sobel kernel会保留y轴上下的信息,丢弃中间的信息和x轴两边的信息;
- Gabor kernel和Sobel kernel类似,但是保留的内容会更少些,更倾向于保留远离中心的像素。
所以从这个角度来分析结果,sobel kernel和gabor kernel更倾向于保留高频信息而弱化低频信息,而mean kernel则是弱化高频信息而保留低频信息。所以mean kernel和另外两个kernel的作用不同。
另外,对于一些文章中提到利用可视化的方法发现了自己的参数像gabor filter,也说明了它的卷积核作用是保留高频牺牲低频。
那么从这个角度分析,卷积层意义在哪里?如果我们任务是给我们一盘番茄炒蛋,问我们这盘菜是哪位师傅做的(记得小时候在饭店吃饭的时候,菜盘边上经常会有一张小纸条写着“XX号厨师为您服务”)。那么盘子里的数量众多的番茄和鸡蛋不一定能帮助我们找到厨师,而其中佐料的分量多少更有助于我们找出厨师的做菜风格。当然这里我们假设厨师有自己的风格,且正常发挥没有失误了。而这个思路也是卷积层采取的一种策略。
关于傅立叶变换以及频域信息分析显然没有这么简单,更多的细节还需要更多的分析,这里只是抛砖作个引子。
下一回将说说卷积层具体求解的问题。