卷積操作
這個不難理解。我們知道圖像在計算機(jī)中是由一個個的像素組成的,可以用矩陣表示。
假設(shè)一個5x5的輸入圖像,我們定義一個3x3的矩陣(其中的數(shù)值是隨機(jī)生成的)
然后我們拿這個卷積核,在輸入圖像里面,選定左上角那個3x3的矩陣,用卷積核與這個矩陣對應(yīng)的位置相乘,然后得到的9個數(shù),這9個數(shù)再相加,最終得到一個結(jié)果。
然后把卷積核往右邊挪動一格,繼續(xù)重復(fù)上述計算,再得到一個數(shù)字。
那么算完了,繼續(xù)往右邊挪,再算
三次計算得到的值是
然后往下挪一格,繼續(xù)重復(fù)上述操作,直到我們把整個5x5的輸入圖像全部計算完,得到了9個計算結(jié)果
這就是我們卷積的結(jié)果,這整個操作就是卷積操作。
那么有幾個問題:
-
Q1:每次往右挪動只能是1格嗎?
-
A1:不是,挪動1格,就是步長為1,如果我們設(shè)置步長為2,那就每次挪動2格,stride步長由我們設(shè)置
-
Q2:卷積核里面的數(shù)值是怎么設(shè)置的?
-
A2:初始是隨機(jī)生成的(后面會學(xué)習(xí)更新)
-
Q3:所以經(jīng)過卷積之后,圖像一定變小了?
-
A3:不是的,上面的例子,5x5的輸入,卷積之后得到3x3,那么我們?nèi)绻o5x5的圖像填充一圈,就變成了7x7的圖像了,再去拿這個卷積核進(jìn)行卷積,就會得到5x5的輸出。實際中,我們也確實是這么做的,有一個參數(shù)padding即表示是否填充,我們可以設(shè)置填充的范圍,以及填充的值,一般填充0。
順便補(bǔ)充一個公式: 假設(shè)輸入圖片為 H x W 卷積核大小為FxF,步長stride=S,padding設(shè)置為P(填充的像素數(shù)) 則輸出圖像的大小=(H - F +2P)/S +1
那么,了解了整個卷積的過程,下面這個圖就能看懂了。
這個圖表示的是輸入圖像為5x5,卷積核為3x3,步長為1,padding=1,所以得到的輸出是5x5
實際操作
卷積的流程是上面講的那樣,實際寫代碼的時候,我們可以不用那么麻煩,每一步都自己實現(xiàn)。
框架已經(jīng)幫我們封裝好的對應(yīng)的函數(shù),我們只需要調(diào)用函數(shù),傳給他相關(guān)參數(shù)即可。
我們以pytorch框架為例(tensorflow也差不多)
Conv2d操作時我們需要設(shè)置以下參數(shù):
我們解釋幾個常用的:
- in_channels:輸入的通道數(shù)
- out_channels:輸出的通道數(shù)
- kernel_size:卷積核的大小,類型為int 或者元組,當(dāng)卷積是方形的時候,只需要一個整數(shù)邊長即可,卷積不是方形,要輸入一個元組表示高和寬。(卷積核不需要你設(shè)置,只需要給定大小,里面的值是隨機(jī)生成的)
- stride:步長(就是每次挪動幾個像素,默認(rèn)是1)
- padding:填充幾圈,默認(rèn)是0,不填充(填充的值為0)
- dilation:控制卷積核之間的間距(設(shè)置這個可以做空洞卷積)
- groups:控制輸入和輸出之間的連接
- bias:偏置,是否將一個 學(xué)習(xí)到的 bias 增加輸出中,默認(rèn)是True
- padding_mode:設(shè)置填充的模式
filter與kernel
這里重點解釋以下通道數(shù)的問題:
假設(shè)一張圖片是6x6的,通道數(shù)是1(如黑白圖像),卷積核大小3x3,步長為1,不填充(padding為0)
我們暫時不考慮out_channels的設(shè)置問題,待會再說
也就是說現(xiàn)在的參數(shù)設(shè)置是:in_channels=1
kernel_size=3
stride=1
padding=0
這我們都能算出來,輸出圖像是4x4的,我畫了個示意圖,可以看下:
那我們也知道,rgb圖像是三通道的,那么假如上圖是個rgb圖像呢,輸出結(jié)果是多少呢
也就是說參數(shù)設(shè)置是:in_channels=3
kernel_size=3
stride=1
padding=0
如圖:我們的輸出結(jié)果依然是1通道的。
可以看到,這里的卷積核變了,變成了三個疊加。
有些同學(xué)就是只明白上面那個單通道的卷積操作,但是不明白這個多通道的卷積操作。
當(dāng)你輸入圖像是三通道的時候,卷積核就也是三通道的。
其實關(guān)鍵點就在于in_channels
,in_channels
是輸入的通道數(shù),同時它也是濾波器(filter)的通道數(shù)。kernel
我們叫做卷積核,大小是3x3
而如果輸入是三通道圖像的話,那我們的卷積核也會是三通道的
我們把單層的卷積核叫kernel
多層疊起來這個叫filter
濾波器
注意:**這樣解釋并非正確,只是方便理解。**至于kernel和filter的具體含義,有歷史原因,這些術(shù)語也是從其他學(xué)科流傳借鑒下來的,而目學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)也并不需要細(xì)究kernel和filter具體指代什么,只要理解這都是卷積核就行了。
當(dāng)你輸入圖像是三通道的時候,卷積核就也是三通道的。
他們之間的運算是由這個新的卷積核(有27個數(shù)),去和輸入圖像的對應(yīng)位置做運算。
27個數(shù)分別與輸入圖像中的27個數(shù)字對應(yīng)相乘,然后再相加,得到一個數(shù),重復(fù)這個計算,把整個輸入圖像都走一遍,就得到16個數(shù)。
如圖:
所以運算出來的也是一維的結(jié)果,也就是單通道的結(jié)果。
所以,kernel
和filter
的概念就明白了。kernel
: 內(nèi)核是一個2維矩陣,長 × 寬。filter
:濾波器是一個三維立方體,長× 寬 × 深度, 其中深度便是由 多少張內(nèi)核構(gòu)成。
可以說kernel 是filter 的基本元素, 多張kernel 組成一個filter。
其實本質(zhì)上kernel和filter都是卷積核而已,只不過一個對應(yīng)單通道,一個對應(yīng)多通道
所以filter
是幾維的取決于輸入通道數(shù)
那么有兩個問題:
一個filter 中應(yīng)該包含多少張 kernel 呢?
答案是:由輸入的通道數(shù)in_channels
來確定
一層中應(yīng)該有多少個filter呢?
答案是:看我們想要提取多少個特征,一個filter 負(fù)責(zé)提取某一種特征,我們想輸出多少個特征就設(shè)置多少個filter。
那么設(shè)置filter的參數(shù)是什么呢?
就是前面我們沒說的out_channels
不要忘了,out_channels
也是可以人為設(shè)置的,上面那個圖,一個filter運算得到的結(jié)果是單通道的,假如你設(shè)置out_channels=2
那么就會得到輸出通道為2。如圖所示:
所以??偨Y(jié)一下就是。filter
有幾個決定了輸出的通道數(shù)
我們寫代碼的時候,不需要指定filter的數(shù)量,而是直接指定輸出通道即可,所以輸出通道是我們的超參數(shù)。in_channels
決定了filter的通道數(shù),out_channels
的設(shè)置決定了filter的數(shù)量,這一層卷積得到的結(jié)果的out_channels
就是下一層的in_channels
。
所以,out_channels
和in_channels
是沒有關(guān)系的。
1x1的卷積層
1x1的卷積層是特殊的卷積層
卷積核的高和寬都等于1,意味著它不會識別空間信息,因為他每次只看一個空間像素所以不會去識別通道中的空間信息
但是我們經(jīng)常用它來合并通道
它輸出的值等價于將對應(yīng)的輸入位置上的不同通道上的值做加權(quán)和1x1卷積核
的作用就是去融合不同通道的信息可以認(rèn)為是不做空間的匹配,只是在輸入層直接做輸入通道和輸出通道的融合,等價于將整個輸入拉成一個向量,通道數(shù)等于feature的數(shù)量1x1的卷積層
就等價于一個全連接層,不做任何的控制信息,因為全連接層不考慮空間信息它只考慮在特征維度(也就是輸入通道維數(shù))的融合
可視化的例子
我們可以用一個實際的網(wǎng)絡(luò)LeNET5來看一下我們剛才的解釋。
這個輸入一張32x32的手寫數(shù)字圖片
6@28x28代表:第一卷積層的輸出通道是6,輸出大小為28x28
第二個是池化層,通道數(shù)不變,還是6,大小減半,變成了14x14
第三個還是卷積層,16通道,大小10x10
然后第四個是池化層,16通道,大小5x5
最后跟兩個全連接層
最后是輸出結(jié)果。
LeNET5第一層是一個卷積層,其輸入數(shù)據(jù)是32x32x1,卷積核大小5x5,步長=1,padding=0,輸出為6 @ 28×28
那么,這里輸入是單通道的,也就是in_channels=1
,那么filter的深度也就是1了,但是輸出通道要求是6,也就是out_channels=6
也就是需要6個filter,最終得到6個28x28的圖像。
如圖:這是整個LeNET5的網(wǎng)絡(luò)可視化模型,藍(lán)色的那個是32x32的,經(jīng)過卷積,得到了下一層,也就是黃色的那一層,你可以看到,黃色的那一層是一個立方體,我們可以把他展開看看
可以看到:展開后確實就是6個28x28的結(jié)果
這個可視化的網(wǎng)站地址是:https://tensorspace.org/index.html
池化
明白了卷積操作,池化就簡單多了。池化操作就是用一個kernel,比如3x3的,就去輸入圖像上對應(yīng)3x3的位置上,選取這九個數(shù)字中最大的作為輸出結(jié)果。這就叫最大池化。
輸出通道=輸入通道
(輸入多通道的時候,就是每個通道都池化就好了)
全連接
全連接層一般在卷積神經(jīng)網(wǎng)絡(luò)的末尾。他的輸入呢是前面卷積池化得到的結(jié)果,把結(jié)果“展平”,就是把得到的結(jié)果矩陣,平鋪為一個列向量。那么全連接如何對這個列向量運算呢?
如圖,假設(shè)左邊的x1,x2,x3就是我們展平后得到的向量,那么我們用
x
1
×
w
11
+
x
2
×
w
21
+
x
3
×
w
31
=
b
1
x_1 \times w_ {11} +x_2 \times w_{21} + x_3 \times w_{31} = b_1
x1?×w11?+x2?×w21?+x3?×w31?=b1?
同理,b2也是這么算出來的。這個計算過程可以表示為矩陣運算文章來源:http://www.zghlxwxcb.cn/news/detail-755358.html
那么這個運算中,只要我們增加w矩陣的列數(shù),就可以得到不同的結(jié)果數(shù)量。比如w設(shè)置為3x3的,那就會得到1x3的結(jié)果。所以呢,全連接層輸出一列向量,最終得到的結(jié)果數(shù)量是我們可以定義的。
那么這么做有什么意義呢?
全連接層(fully connected layers,F(xiàn)C)在整個卷積神經(jīng)網(wǎng)絡(luò)中起到“分類器”的作用。如果說卷積層、池化層和激活函數(shù)層等操作是將原始數(shù)據(jù)映射到隱層特征空間的話,全連接層則起到將學(xué)到的“分布式特征表示”映射到樣本標(biāo)記空間的作用。
這么做可以減少特征位置對分類帶來的影響,本來feature map是一個矩陣,所以特征的位置對分類是有影響的,比如識別圖像里面的貓,貓在圖像的左上角,那么左上角就可以檢測到,右下角就檢測不到,但是呢,我們那這個二維的矩陣,通過全連接層,整合成一個值輸出,這個值就是對貓的預(yù)測概率,不論貓在哪,只要概率大,就是有貓。這樣做忽略了空間結(jié)構(gòu)特征,增強(qiáng)了魯棒性。文章來源地址http://www.zghlxwxcb.cn/news/detail-755358.html
到了這里,關(guān)于神經(jīng)網(wǎng)絡(luò)必備基礎(chǔ)知識:卷積、池化、全連接(通道數(shù)問題、kernel與filter的概念)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!