今日休假笆焰,把卷積神經(jīng)網(wǎng)絡(luò)梳理下。先從一些基本概念入手见坑,什么是卷積嚷掠?為什么叫這么個名字?
搜索了一遍荞驴,網(wǎng)上有很多人已經(jīng)表述的非常好了不皆,這里用自己理解的語言重述下。
既然是卷積熊楼,肯定是一種積霹娄,積我們知道是兩個數(shù)的乘的結(jié)果,那么卷積也是一種乘鲫骗,所以需要兩個相乘的單元犬耻。
先考慮在一維變量上:
函數(shù) f 與函數(shù) g 不停在搏斗,同時把搏斗的結(jié)果進行求和挎峦,而且這個過程是從生到死(負無窮-正無窮)
下面是連續(xù)函數(shù)的積分表達形式香追,效果是一樣的
上面的兩個式子可以看到有共同的地方就是:
這就有意思了,也就是解釋卷積的“卷”的關(guān)鍵所在坦胶。
x+y=a 是一條直線,a 的取值從負無窮到正無窮,這個過程就是把 xy 坐標系從西南角一直掃描到東北角顿苇,就像我們卷手絹一樣峭咒,還是比較形象的。
有了上面的認識纪岁,我們進一步看看二維的凑队。
如果在在二維空間,有函數(shù) f(x, y) 和 g(x, y)幔翰,他們兩個做乘積漩氨,也就是:
這個式子看上去有點小復(fù)雜,其實就是表示從負無窮到正無窮的全部 s 和 t 值遗增,把 g 在 (x-s, y-t) 上的值乘以 f 在 (s, t) 上的值之后再“加和”到一起叫惊,得到 c 在 (x, y) 上的值。說白了卷積就是一種“加權(quán)求和”:以 f 為權(quán)做修,以 (x, y) 為中心霍狰,把 g 距離中心 (-s, -t) 位置上的值乘上 f 在 (s, t) 的值,最后加到一起饰及。
如果是離散的蔗坯,把積分修改為求和即可:
式子最右邊就是表示跨度德爾塔為1。
尤其需要注意的是 f 與 g 里面的 s 與 t 的正負方向燎含。
舉個例子:
假如現(xiàn)在有一個10*10的圖片宾濒,該圖片是灰度處理過的,也就是黑白圖片屏箍,不是 RGB 三個通道的鼎兽。
在這1010的格子里有對應(yīng)的值,范圍之外全是0铣除,我們令整個圖片叫 G
谚咬。另外還有一個矩陣(一般應(yīng)該是特征矩陣,用來提取大圖的特征)尚粘,我們叫他F
,他的值應(yīng)該是預(yù)先給定好的择卦,這里我們也是假設(shè)一組數(shù)據(jù)填充進來。
接下來郎嫁,我們要做的就是秉继,把 F 進行上下左右反轉(zhuǎn),形成 F‘
泽铛,然后與 G 從00點開始對齊尚辑,進行小格子乘積操作,再求和盔腔。
比如在3**7
這個點進行杠茬,求新得到的該點數(shù)值月褥。
上述操作其實就是對數(shù)字圖像進行離散卷積操作,又叫濾波瓢喉。F 稱作卷積核或濾波器宁赤。不同的 F 有不同的效果。
比如:
經(jīng)過不同的卷積核栓票,可能得到的圖片:
進一步
有了卷積决左,我們可能還要做一些輔助的事,比如步長走贪,補0等佛猛。
比如有一個5乘5的矩陣,都是1坠狡,現(xiàn)在有一個2**2卷積核,值是[-1,0继找,0,-1]擦秽。
現(xiàn)在需要做卷積码荔,每次移動2格,也就是步長是2感挥,開始計算各個小區(qū)塊缩搅,如下圖。
最終結(jié)果是:
-2,-2,-1,
-2,-2,-1,
-1,-1,-1
在移動步長的時候触幼,不足的地方需要補0操作,如果不補0硼瓣,就 dropped,這都是 padding 的策略
多核卷積
一個 G 函數(shù)置谦,可以使用多個 F 函數(shù)做卷積核堂鲤,得到不同的卷積結(jié)果,也就是某張圖片使用多個卷積核媒峡,得到各個不同地方的特征瘟栖。
全卷積
全卷積也叫反卷積,他的步長是1谅阿,是把原始圖片的每個像素點用卷積操作展開半哟。比如下圖,
如果原始圖片的大小是 N1乘N1签餐,核的大小是 N2乘N2寓涨,那么生成的圖片大小是:(N1+N2-1)(N1+N2-1)
池化
池化的操作就是降低維度,我們再對圖片做操作的時候氯檐,由于維度太多戒良,需要降低維度,同時要保持特征部分冠摄。池化的操作也是需要一個矩陣糯崎,也需要步長几缭,原始數(shù)據(jù)經(jīng)過池化操作,矩陣大小明顯變小拇颅,里面的數(shù)值的確定有:取池化范圍的最大值奏司,取池化區(qū)域均值乔询,下圖是一個最大池化的例子
在 TensorFlow 中學(xué)習(xí)卷積
在 TensorFlow 里面已經(jīng)包裝了這些函數(shù)樟插,我們不在需要逐個計算,tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None) 函數(shù)實現(xiàn)了卷積操作竿刁。來看下他的具體參數(shù)含義:
給定一個input的張量[batch, in_height, in_width, in_channels]和一個過濾器 / 內(nèi)核張量 [filter_height, filter_width, in_channels, out_channels]后黄锤,執(zhí)行以下操作:
- 展平filter為一個形狀為[filter_height * filter_width * in_channels, output_channels]的二維矩陣。
- 從input中按照filter大小提取圖片子集形成一個大小為[batch, out_height, out_width, filter_height * filter_width * in_channels]的虛擬張量食拜。
- 循環(huán)每個圖片子集鸵熟,右乘filter矩陣。
舉個例子:
有一個輸入[1,3,3,1],表示一個圖像负甸,33大小流强,1個通道;
filter 是[2,2,1,1]表示過濾器是22大小呻待,輸入輸出通道都是1打月;
步長是1,padding是VALID蚕捉;
這種情況下奏篙,輸出是1x2x2x1,其中2=(3-2)/1+1迫淹,即(圖片大小-filter大小)/步長+1秘通。
input 和 filter 都是4維度
import tensorflow as tf
input = tf.constant([[
[[1],
[2],
[ 3]],
[[4],
[5],
[6 ]],
[[ 7],
[8],
[9]]]],dtype=tf.float32)
filter = tf.constant([[[[1]],
[[2]]],
[[[ 3]],
[[4]]]],dtype=tf.float32)
op = tf.nn.conv2d(input,filter,strides = [1,1,1,1],padding ='VALID')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
result = sess.run(op)
print(result)
輸出結(jié)果是:
[[[[37.]
[47.]]
[[67.]
[77.]]]]
如果 padding(補0操作)是 SAME,也就是和輸入一樣大小敛熬,那么
op = tf.nn.conv2d(input肺稀,filter,strides = [1,1,1,1]应民,padding ='SAME')
得到的結(jié)果1x3x3x1话原。
[[[[37.]
[47.]
[21.]]
[[67.]
[77.]
[33.]]
[[23.]
[26.]
[ 9.]]]]
對于多通道來說,輸入是[1x3x3x2]是3x3圖像有2個通道瑞妇,過濾器是[2x2x2x1]是2x2大小2個輸入1個輸出稿静,步長是1,padding=VALID辕狰,輸出是[1x2x2x1],如圖: