卷積的數學意義及信號學應用


1、卷積的數學意義

   從數學上講,卷積與加減乘除一樣是一種運算,其運算的根本操作是將兩個函數的其中一個先平移,然后再與另一個函數相稱后的累加和。這個運算過程中,因為涉及到積分、級數的操作,所以看起來很復雜。在卷積(轉自wiki百科)中已經講過了卷積的定義如下所示:

對於定義在連續域的函數,卷積定義為

 (f * g )(t) = \int f(\tau) g(t - \tau)\, d\tau

 

對於定義在離散域的函數,卷積定義為

(f * g)[m] = \sum_n {f[n] g[m - n]}

  這里令U(x,y) = f(x)g(y) ,考慮到函數 f 和 g 應該地位平等,即變量 x 和 y 應該地位平等,一種可取的辦法就是沿直線 x+y = t將U(x,y)卷起來。下面為t取實際值的時候的坐標圖,可以看到不同取值的t可以遍歷整個平面。

  將x+y=t中t取一次定值(這個定值可能是我們想要知道的某時刻的結果或着某種特征,由我們賦值),代入到U(x,y)中,就相當於U(x,y)所在平面沿着x+y=t直線做一次旋轉如下列動圖所示:

  這里便是完成了整個卷積的降維過程,完成降維過程后,U(x,y)也就從一個二元函數 U(x,y) = f(x)g(y) 被卷成一元函數 V(x)=f(x)g(t-x),最后再對x求積分(即遍歷降維后的軸上的特征點之和)。

2、卷積的C語言編寫

  編寫卷積的程序,需要根據其離散方程組來進行了解。前面已經知道了卷積的離散函數的定義公式為:

(f * g)[m] = \sum_n {f[n] g[m - n]}

  

在用C語言等其他語言進行實現是可以采用定義,利用兩個for循環完成代碼。 

  根據離散公式,可以編寫如下C++代碼:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;
float min(float a, float b)
{
	return a < b ? a : b;
}
void convolution(float *input1, float *input2, float *output, int mm, int nn)
{
	float *xx = new float[mm + nn - 1];
	float *tempinput2 = new float[mm + nn - 1];
	for (int i = 0; i < nn; i++)
	{
		tempinput2[i] = input2[i];
	}
	for (int i = nn; i < mm + nn - 1; i++)
	{
		tempinput2[i] = 0.0;
	}
	// do convolution 
	for (int i = 0; i < mm + nn - 1; i++)
	{
		xx[i] = 0.0;
		int tem = (min(i, mm)) == mm ? mm - 1 : min(i, mm);
		for (int j = 0; j <= tem; j++)
		{
			xx[i] += (input1[j] * tempinput2[i - j]);
		}
	}
	// set value to the output array 
	for (int i = 0; i < mm + nn - 1; i++)
		output[i] = xx[i];
		delete[] xx;
}

int main()
{
	float a[3] = {2,6,4 };
	float b[5] = {1,2,5,4,8};
	float *c = new float[9];
	convolution(a, b, c, 3, 5);
	for (int i = 0; i < 7; i++)
	{
		cout << c[i] << " ";
	}
	getchar();
	return 0;
}

  

  運行結果如上圖所示,打開matlab進行驗證有:

 

卷積的列表法計算 :

 

如圖所示:斜線上數據相加,便是卷積結果;該方法適合用於並行計算求卷積。

 

 

3、卷積的分類

  

1. 二維卷積

  • 圖中的輸入的數據維度為14×1414×14,過濾器大小為5×55×5,二者做卷積,輸出的數據維度為10×1010×10(145+1=1014−5+1=10)。如果你對卷積維度的計算不清楚,可以參考我之前的博客吳恩達深度學習筆記(deeplearning.ai)之卷積神經網絡(CNN)(上)

  • 上述內容沒有引入channel的概念,也可以說channel的數量為1。如果將二維卷積中輸入的channel的數量變為3,即輸入的數據維度變為(14×14×314×14×3)。由於卷積操作中過濾器的channel數量必須與輸入數據的channel數量相同,過濾器大小也變為5×5×35×5×3。在卷積的過程中,過濾器與數據在channel方向分別卷積,之后將卷積后的數值相加,即執行10×1010×10次3個數值相加的操作,最終輸出的數據維度為10×1010×10。

  • 以上都是在過濾器數量為1的情況下所進行的討論。如果將過濾器的數量增加至16,即16個大小為10×10×310×10×3的過濾器,最終輸出的數據維度就變為10×10×1610×10×16。可以理解為分別執行每個過濾器的卷積操作,最后將每個卷積的輸出在第三個維度(channel 維度)上進行拼接。

  • 二維卷積常用於計算機視覺、圖像處理領域。

2. 一維卷積

  • 圖中的輸入的數據維度為8,過濾器的維度為5。與二維卷積類似,卷積后輸出的數據維度為85+1=48−5+1=4。

  • 如果過濾器數量仍為1,輸入數據的channel數量變為16,即輸入數據維度為8×168×16。這里channel的概念相當於自然語言處理中的embedding,而該輸入數據代表8個單詞,其中每個單詞的詞向量維度大小為16。在這種情況下,過濾器的維度由55變為5×165×16,最終輸出的數據維度仍為44。

  • 如果過濾器數量為nn,那么輸出的數據維度就變為4×n4×n。

  • 一維卷積常用於序列模型,自然語言處理領域。

3. 三維卷積

這里采用代數的方式對三維卷積進行介紹,具體思想與一維卷積、二維卷積相同。

  • 假設輸入數據的大小為a1×a2×a3a1×a2×a3,channel數為cc,過濾器大小為ff,即過濾器維度為f×f×f×cf×f×f×c(一般不寫channel的維度),過濾器數量為nn。

  • 基於上述情況,三維卷積最終的輸出為(a1f+1)×(a2f+1)×(a3f+1)×n(a1−f+1)×(a2−f+1)×(a3−f+1)×n。該公式對於一維卷積、二維卷積仍然有效,只有去掉不相干的輸入數據維度就行。

  • 三維卷積常用於醫學領域(CT影響),視頻處理領域(檢測動作及人物行為)。

 

 

4、卷積的信號學應用

打個比方,往平靜的水面里面扔石頭。我們把水面的反應看作是一種沖擊響應。水面在t=0時刻石頭丟進去的時候會激起高度為h(0)的波紋,但水面不會立馬歸於平靜,隨着時間的流逝,波紋幅度會越來越小,在t=1時刻,幅度衰減為h(1), 在t=2時刻,幅度衰減為h(2)……直到一段時間后,水面重復歸於平靜。

從時間軸上來看,我們只在t=0時刻丟了一塊石頭,其它時刻並沒有做任何事,但在t=1,2….時刻,水面是不平靜的,這是因為過去(t=0時刻)的作用一直持續到了現在。

那么,問題來了:

如果我們在t=1時刻也丟入一塊石子呢?此時t=0時刻的影響還沒有消失(水面還沒有恢復平靜)新的石子又丟進來了,那么現在激起的波浪有多高呢?答案是當前激起的波浪與t=0時刻殘余的影響的疊加。那么t=0時刻對t=1時刻的殘余影響有多大呢?


為了便於說明,接下來我們作一下兩個假設:

1. 水面對於“單位石塊”的響應是固定的

2. 丟一個兩倍於的“單位石塊”的石塊激起的波紋高度是丟一個石塊的兩倍(即系統滿足線性疊加原理)

現在我們來計算每一時刻的波浪有多高:

  • t=0時刻:

y(0)=x(0)*h(0);

  • t=1時刻:

當前石塊引起的影響x(1)*h(0);

t=0時刻石塊x(0)引起的殘余影響x(0)*h(1);

y(1)=x(1)*h(0)+ x(0)*h(1);

  • t=2時刻:

當前石塊引起的影響x(2)*h(0);

t=0時刻石塊x(0)引起的殘余影響x(0)*h(2);

t=1時刻石塊x(1)引起的殘余影響x(1)*h(1);

y(2)=x(2)*h(0)+ x(1)*h(1)+x(0)*h(2);

……

  • t=N時刻:

當前石塊引起的影響x(N)*h(0);

t=0時刻石塊x(0)引起的殘余影響x(0)*h(N);

t=1時刻石塊x(1)引起的殘余影響x(1)*h(N-1);

y(N)=x(N)*h(0)+ x(N-1)*h(1)+x(N-2)*h(2)+…+x(0)*h(N);

這就是離散卷積的公式了

理解了上面的問題,下面我們來看看“翻轉”是怎么回事:

當我們每次要丟石子時,站在當前的時間點,系統的對我們的回應都是h(0),時間軸之后的(h(1),h(2).....)都是對未來的影響。而整體的回應要加上過去對於現在的殘余影響。

現在我們來觀察t=4這個時刻。

站在t=0時刻看他對於未來(t=4)時刻(從現在往后4秒)的影響,可見是x(0)*h(4)

站在t=1時刻看他對於未來(t=4)時刻的影響(從現在往后3秒),可見是x(1)*h(3)

站在t=2時刻看他對於未來(t=4)時刻的影響(從現在往后2秒),可見是x(2)*h(2)

站在t=3時刻看他對於未來(t=4)時刻的影響(從現在往后1秒),可見是x(3)*h(1)

所以所謂的翻轉只是因為你站立的現在是過去的未來,而因為h(t)始終不變,故h(1)其實是前一秒的h(1),而前一秒的h(1)就是現在,所以從當前x(4)的角度往左看,你看到的是過去的作用。h(t)未翻轉前,當從h(0)往右看,你看到的是現在對於未來的影響,當翻轉h(t)之后,從h(0)往左看,你依次看到的越來越遠的過去對現在的影響,而這個影響,與從x=4向左看的作用影響相對應(都是越來越遠的過去),作用與作用的響應就對應起來了,這一切的本質,是因為你站立的時間觀察點和方向在變。

   

 5、卷積的圖像處理原理

    一幅圖像在生成的過程中,會隨機產生一些噪點,如下圖所示:

 

  噪點在圖片中,就相當於在平地上聳起的山峰,是一個與其他數據不符的一個較大值。

     

 

   我們可以通過卷積操作將噪點通過濾波給濾掉,首先,將圖片用矩陣表示出來。

  然后通過下面的核來進行濾波(這個在后面的文章中將會詳細講到,原理與卷積在信號處理中的應用一樣)

  經過如下的卷積運算

  就可以完成在圖片上的平均濾波的效果了,通過卷積濾波后的效果如下所示:

 

 

 

 

 

 

參考資料

卷積為什么叫「卷」積?

如何通俗易懂地解釋卷積?

在定義卷積時為什么要對其中一個函數進行翻轉?

Matlab中fileter和conv的區別及卷積的計算方法

卷積C語言實現

卷積神經網絡(CNN)之一維卷積、二維卷積、三維卷積詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM