Lesson 16.3 卷积操作
3 卷積操作
這里有兩個(gè)長(zhǎng)度為9的列表,我們讓對(duì)應(yīng)位置的元素相乘,之后再相加:
a?9+b?8+7?c+6?d+5?e+f?4+g?3+h?2+i?1a * 9+b * 8+7 * c+6 * d+5 * e+f * 4+g * 3+h * 2+i * 1a?9+b?8+7?c+6?d+5?e+f?4+g?3+h?2+i?1如果我們把數(shù)字列表看作是權(quán)重,那以上式子就可以被看做一個(gè)加權(quán)求和的過(guò)程。現(xiàn)在,我們將九個(gè)數(shù)整理成如下的矩陣:
左側(cè)的矩陣我們稱之為字母矩陣,而右側(cè)的矩陣稱之為數(shù)字矩陣(也就是權(quán)重矩陣)。當(dāng)表示成矩陣之后,我們可以求解兩個(gè)矩陣的點(diǎn)積,也就是將對(duì)應(yīng)位置的元素相乘再相加等到一個(gè)標(biāo)量,這與我們剛才實(shí)現(xiàn)的加權(quán)求和運(yùn)算本質(zhì)一致。但此時(shí)我們發(fā)現(xiàn),在變成矩陣之前,a對(duì)應(yīng)的是9,i對(duì)應(yīng)的是1,而現(xiàn)在a對(duì)應(yīng)的是1,i對(duì)應(yīng)的是9。如果我們還想實(shí)現(xiàn)剛才的加權(quán)求和,就需要將數(shù)字矩陣在平面上順時(shí)針旋轉(zhuǎn)180度,得到旋轉(zhuǎn)矩陣:
現(xiàn)在,將旋轉(zhuǎn)矩陣與字母矩陣求點(diǎn)積,就可以得到與之前的加權(quán)求和一樣的結(jié)果了:
dotsum?=a?9+b?8+7?c+6?d+5?e+f?4+g?3+h?2+i?1\text { dotsum }=a * 9+b * 8+7 * c+6 * d+5 * e+f * 4+g * 3+h * 2+i * 1 ?dotsum?=a?9+b?8+7?c+6?d+5?e+f?4+g?3+h?2+i?1現(xiàn)在,dotsum的結(jié)果就是字母矩陣與原始數(shù)字矩陣的卷積。
卷積操作是一種常見(jiàn)的數(shù)學(xué)計(jì)算,二維矩陣的卷積表示其中一個(gè)矩陣在平面上旋轉(zhuǎn)180°后,與另一個(gè)矩陣求點(diǎn)積的結(jié)果。其中“卷”就是旋轉(zhuǎn),“積”就是點(diǎn)積,也就是加權(quán)求和。本質(zhì)上來(lái)說(shuō),卷積就是其中一個(gè)矩陣旋轉(zhuǎn)180°后,兩個(gè)矩陣對(duì)應(yīng)位置元素相乘再加和的結(jié)果。這個(gè)過(guò)程可以使用數(shù)學(xué)公式表示:[x11x12?x1nx21x22?x2n????xm1xm2?xmn]?[y11y12?y1ny21y22?y2n????ym1ym2?ymn]=∑i=0m?1∑j=0n?1x(m?i)(n?j)y(1+i)(1+j)\left[\begin{array}{cccc} x_{11} & x_{12} & \cdots & x_{1 n} \\ x_{21} & x_{22} & \cdots & x_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ x_{m 1} & x_{m 2} & \cdots & x_{m n} \end{array}\right] *\left[\begin{array}{cccc} y_{11} & y_{12} & \cdots & y_{1 n} \\ y_{21} & y_{22} & \cdots & y_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ y_{m 1} & y_{m 2} & \cdots & y_{m n} \end{array}\right]=\sum_{i=0}^{m-1} \sum_{j=0}^{n-1} x_{(m-i)(n-j)} y_{(1+i)(1+j)} ??????x11?x21??xm1??x12?x22??xm2???????x1n?x2n??xmn???????????????y11?y21??ym1??y12?y22??ym2???????y1n?y2n??ymn????????=i=0∑m?1?j=0∑n?1?x(m?i)(n?j)?y(1+i)(1+j)?其中xxx表示其中一個(gè)矩陣的值,yyy表示另一個(gè)矩陣的值,mmm與nnn分別是兩個(gè)矩陣的行數(shù)和列數(shù)。在其他教材或其他說(shuō)明中,你可能會(huì)見(jiàn)到使用其他符號(hào)的二維矩陣的卷積表示,但其本質(zhì)都與我們所說(shuō)的“旋轉(zhuǎn)再求內(nèi)積”一致。你也可能會(huì)見(jiàn)到卷積的代數(shù)表示(就是帶積分的那個(gè))、甚至是離散卷積的表示方式,幸運(yùn)的是那些與矩陣卷積有所不同,因此如果你感覺(jué)困惑,你可以不用去理會(huì)。
之前我們說(shuō)過(guò),只要我們對(duì)圖像數(shù)據(jù)進(jìn)行任意數(shù)學(xué)運(yùn)算,且得出的結(jié)果不超出圖像的像素范圍[0,255],就可以生成新的圖像。而卷積是一種從兩個(gè)矩陣中得出新數(shù)值的方式,這個(gè)操作正好可以用于圖像的變換。但圖像的矩陣?yán)飫?dòng)輒就幾百萬(wàn)甚至幾千萬(wàn)個(gè)像素,如何將卷積適用于圖片來(lái)得到一張新的圖片(也就是一個(gè)新的矩陣)呢?來(lái)看一個(gè)典型的操作:假設(shè)現(xiàn)在的權(quán)重矩陣如下:
假設(shè)現(xiàn)在的權(quán)重矩陣如下:[?101?202?101]\left[\begin{array}{rrr} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array}\right] ????1?2?1?000?121????我們讓它與下圖中左側(cè)的圖像進(jìn)行卷積。左側(cè)的圖像是一個(gè)6X6結(jié)構(gòu)的圖像,其左半邊的像素都為10,右半邊像素都為0的圖像,因此看起來(lái),它右側(cè)那一半是均勻的顏色,左側(cè)那半邊是另一種均勻的顏色,因此中間的豎線就是兩塊均勻顏色中的“邊緣”。為了實(shí)現(xiàn)卷積,我將權(quán)重矩陣進(jìn)行了180°的旋轉(zhuǎn),圖中所示的是旋轉(zhuǎn)矩陣。
對(duì)于這張圖像,卷積操作是這樣進(jìn)行的。首先,我們令旋轉(zhuǎn)矩陣與綠色區(qū)域進(jìn)行點(diǎn)積(對(duì)應(yīng)位置元素相乘再相加),得到卷積結(jié)果0,成為新矩陣的第一個(gè)元素。接下來(lái),我們?cè)趫D片上,將綠色區(qū)域向右移動(dòng)一個(gè)像素,再令旋轉(zhuǎn)矩陣與綠色區(qū)域進(jìn)行點(diǎn)積,得到卷積結(jié)果40。
同樣的,我們繼續(xù)移動(dòng)綠色區(qū)域,繼續(xù)計(jì)算點(diǎn)積:
當(dāng)橫向區(qū)域掃描完畢之后,我們向下移動(dòng)一個(gè)像素,繼續(xù)從左到右掃描:
以此類推,直到綠色區(qū)域掃描完畢整張圖像,得到右側(cè)的矩陣:
此時(shí),右側(cè)的矩陣就是我們?cè)谧髨D上使用權(quán)重矩陣[?101?202?101]\left[\begin{array}{rrr} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array}\right] ????1?2?1?000?121????進(jìn)行卷積計(jì)算的結(jié)果。我們得到了一張4X4尺寸的圖像,且中間兩列像素為40,兩邊為0,所以是中間較亮,兩邊較暗。原本的圖像在中間有一條明顯的“邊界”,現(xiàn)在我們權(quán)重矩陣對(duì)這張圖像進(jìn)行卷積后得出的圖“放大”了這個(gè)邊界,讓邊界亮了起來(lái),讓其他地方變暗了,這就實(shí)現(xiàn)了對(duì)圖像進(jìn)行“邊緣檢測(cè)”。當(dāng)然,由于我們現(xiàn)在所使用的圖像非常小(像素只有6*6),所以得到的邊緣檢測(cè)結(jié)果看起來(lái)邊緣非常粗,實(shí)際上在真實(shí)案例中,白色的線會(huì)是非常細(xì)的。
邊緣檢測(cè)是卷積操作的一個(gè)常見(jiàn)應(yīng)用,我們所使用的權(quán)重矩陣其實(shí)是縱向的索貝爾算子(Sobel
Operator),用于檢測(cè)縱向的邊緣,我們也可以使用橫向的索貝爾算子,以及拉普拉斯算子來(lái)檢測(cè)邊緣。在OpenCV當(dāng)中我們可以很容易地實(shí)現(xiàn)這個(gè)操作:
除了邊緣檢測(cè)之外,我們還可以使用其他權(quán)重矩陣與原圖卷積來(lái)修改圖像,例如銳化、模糊等等。
在這些例子中,有一個(gè)值得注意的問(wèn)題:我們首先確立權(quán)重矩陣,然后將矩陣旋轉(zhuǎn)180°之后再與感受野進(jìn)行點(diǎn)積,這個(gè)過(guò)程叫做“卷積”,但在實(shí)際執(zhí)行計(jì)算的時(shí)候,真正發(fā)揮作用的使旋轉(zhuǎn)后的旋轉(zhuǎn)矩陣。為什么我們不直接定義旋轉(zhuǎn)矩陣,而要先定義一個(gè)權(quán)重矩陣,再旋轉(zhuǎn)它呢?
事實(shí)上,就連OpenCV中的sobel和Laplacian函數(shù)都沒(méi)有進(jìn)行“旋轉(zhuǎn)”,而是直接定義了旋轉(zhuǎn)后矩陣?;蛟S是最初的研究者嘗試了“卷積”操作,就這樣流傳下來(lái),或許是原始權(quán)重矩陣的邏輯可能來(lái)源于某些理論,不旋轉(zhuǎn)將會(huì)使邊緣檢測(cè)失效,但在今天的計(jì)算機(jī)視覺(jué)技術(shù)中,尤其是深度學(xué)習(xí)中,大部分時(shí)候我們都不再進(jìn)行“旋轉(zhuǎn)”這個(gè)步驟了。甚至在許多卷積相關(guān)的講解中,會(huì)直接忽略旋轉(zhuǎn)這個(gè)步驟,導(dǎo)致許多人無(wú)法理解“卷積”的“卷”從何而來(lái)。
沒(méi)有旋轉(zhuǎn),我們也無(wú)需在關(guān)心最初的矩陣?,F(xiàn)在我們只關(guān)心與圖像相乘的旋轉(zhuǎn)矩陣,我們把旋轉(zhuǎn)矩陣的值稱為權(quán)重,將該矩陣稱為過(guò)濾器(filter,意為可以過(guò)濾出有效的特征),也被叫做卷積核(Convolution Kernel),每個(gè)卷積核在原圖上掃描的區(qū)域(被標(biāo)注為綠色的區(qū)域)被稱為感受野(receiptive field),卷積核與感受野輪流點(diǎn)積得到的新矩陣被叫做特征圖(feature map)或激活圖(activation map)。當(dāng)沒(méi)有旋轉(zhuǎn),只有點(diǎn)積的時(shí)候,圖像與矩陣之間的運(yùn)算就不是數(shù)學(xué)上的“卷積”,而是“互相關(guān)”(cross-correlation)了,但是基于歷史的原因和行業(yè)習(xí)慣,我們依然把整個(gè)過(guò)程稱為“卷積操作”,這個(gè)名字沿用到今天,也影響了深度學(xué)習(xí)中對(duì)卷積神經(jīng)網(wǎng)絡(luò)的稱呼。
4 卷積遇見(jiàn)深度學(xué)習(xí)
檢測(cè)邊緣、銳化、模糊、圖像降噪等卷積相關(guān)的操作,在圖像處理中都可以被認(rèn)為是在從圖像中提取部分信息,因此這部分圖像處理技術(shù)也被叫做“特征提取”技術(shù)。卷積操作后所產(chǎn)生的圖像可以作為特征被輸入到分類算法中,在傳統(tǒng)計(jì)算機(jī)視覺(jué)領(lǐng)域,這一操作常常被認(rèn)為可以提升模型表現(xiàn)并增強(qiáng)計(jì)算機(jī)對(duì)圖像的識(shí)別能力。計(jì)算機(jī)視覺(jué)是研究如何讓計(jì)算機(jī)從圖像或圖像序列中獲取信息并理解其信息的學(xué)科,理解就意味著識(shí)別、判斷甚至是推斷,因此識(shí)別在計(jì)算機(jī)視覺(jué)中是非常核心的需求,卷積操作在傳統(tǒng)計(jì)算機(jī)視覺(jué)中的地位就不言而喻了。數(shù)十年來(lái),計(jì)算機(jī)視覺(jué)工程師們使用前人的經(jīng)驗(yàn)與研究不斷提取特征,再送入機(jī)器學(xué)習(xí)算法中進(jìn)行識(shí)別和分類。然而,這樣做是有極限的。
在邊緣檢測(cè)的例子中,我們看到拉普拉斯和索貝爾算子的檢測(cè)是很明顯的。但是,如果使用我們之前導(dǎo)入的孔雀圖像,就會(huì)發(fā)現(xiàn)邊緣檢測(cè)的效果有些糟糕。
img = cv2.imread('/Users/zhucan/Desktop/blue-peacock.jpg') img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)laplacian = cv2.Laplacian(img,cv2.CV_64F,ksize=5) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)plt.figure(dpi=300) plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray') plt.title('Original'),plt.axis('off') plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray') plt.title('Laplacian'),plt.axis('off') plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') plt.title('Sobel X'),plt.axis('off') plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') plt.title('Sobel Y'),plt.axis('off')
為什么會(huì)這樣呢?這是因?yàn)?#xff0c;sobel和拉普拉斯算子對(duì)邊緣抓取的程度較輕(從圖像處理的原理上來(lái)看,他們只求取了圖像上的一維導(dǎo)數(shù),因此效果不夠強(qiáng)),這樣的抓取對(duì)于橫平豎直的邊緣、以及色彩差異較大的邊緣有較好的效果,對(duì)于孔雀這樣色彩豐富、線條和細(xì)節(jié)非常多的圖像,這兩種算子就不太夠用了。所以在各種邊緣檢測(cè)的例子中,如果你仔細(xì)觀察原圖,你就會(huì)發(fā)現(xiàn)原圖都是輪廓明顯的圖像。
這說(shuō)明,不同的圖像必須使用不同的權(quán)重進(jìn)行特征提取,同時(shí),我們還必須加深特征提取的深度。那什么樣的圖像應(yīng)該使用什么樣的權(quán)重呢?如何才能夠提取到更深的特征呢?同時(shí),如果過(guò)去的研究中提出的算子都不奏效,應(yīng)該怎么找到探索新權(quán)重的方案呢?即便有效地實(shí)現(xiàn)了邊檢檢測(cè)、銳化、模糊等操作,就能夠提升最終分類算法的表現(xiàn)嗎?其實(shí)不然。這些問(wèn)題困擾計(jì)算機(jī)視覺(jué)工程師許久,即便在傳統(tǒng)視覺(jué)中,我們已提出了不少對(duì)于這些問(wèn)題的解決方案,但從一勞永逸的方向來(lái)考慮,如果計(jì)算機(jī)自己能夠知道應(yīng)該使用什么算子、自己知道應(yīng)該提取到什么程度就好了。此時(shí),深度學(xué)習(xí)登場(chǎng)了。
總結(jié)
以上是生活随笔為你收集整理的Lesson 16.3 卷积操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Lesson 16.2 图像的基本操作
- 下一篇: Lesson 16.4 卷积遇见深度学习