卷積的過程
卷積實際上就是兩個矩陣對位相乘,然後再把積求和的一個過程
im2col
caffe裏的卷積運算實際上是把待輸入圖像和卷積核都轉換成矩陣,然後通過矩陣的乘法一步得出來的。這裏列舉一個例子,假設我們待輸入圖像是 55
的一張圖
爲了方便看清位置,我們就用12345來表示圖像的值。
我們選擇 33
的卷積核
然後和圖像對位相乘,也就是卷積核的 1
的位置的值和圖像的 1
的位置的值相乘,卷積核的 2
的位置的值和圖像的 2
的位置的值相乘。。。
這樣就完成了卷積的第一步。
原圖轉化成矩陣
那麼如果我們把第一次的這9個值寫成一列的話就是:
那麼這9個值就對應的是我們原圖上的這9個格子
卷積核每往後移動一步,就把新的9個值加在右邊。
最後一列一列的加,把整張圖所有的計算要用到的數據都寫過去,到時候可以直接用個矩陣的乘法一步到位了,做好以後效果如圖
卷積核轉化成矩陣
接下來我們把卷積核也這樣轉化成矩陣,就可以直接用一個矩陣乘法一步到位了。
因爲卷積覈對圖像來說是左乘,所以卷積核要按行寫。
因爲核的值是固定的,所以實際上它只有一行,就是這樣。
然後它將來要和剛剛生成的那個原圖轉化後的矩陣相乘的,可以驗證一下它的行數等於那個矩陣的列數,這是必然的,因爲我們那個原圖的轉化矩陣就是根據卷積核的大小寫的,所以尺寸肯定是匹配的。
矩陣乘法求卷積結果
然後這兩個矩陣直接做矩陣的乘法就可以了,我們想想矩陣的乘法不就是做這個事的嗎,先乘後加。
最後就得出了一行九列的乘法結果
將計算矩陣轉回特徵圖
因爲卷積之後得到的結果應該是一個特徵圖,而不會是這樣一個行矩陣,所以我們還是要把他轉換回去,那麼根據計算好的尺寸,變回它應有的大小
多通道的輸入
如果是RGB3個通道的卷積,在caffe裏面是3個通道卷積的結果再疊加起來,既然是加法,那麼我們就可以直接在原圖轉化矩陣把每個通道往下疊加,就像這樣。
這樣的話,矩陣乘法他就能自動把每個通道全部加起來了。但是我們光乘號右邊的矩陣行變多了,那麼左邊矩陣的列也應該變多,所以我們把卷積核也這樣複製一下。
就像這樣,然後再乘,得出來的結果還是和剛纔一樣的形狀,因爲輸入多通道只是把結果相加,並不改變形狀,這樣保證了輸出的通道數不變。
多通道的輸出
如果我們也想要多通道的輸出該怎麼辦呢?比方說我們要從3通道的輸入卷積之後生成4通道的輸出,那是不是要循環4次這種操作呢?答案是否定的,我們只需要把這4個卷積核按行寫在下面就可以了。
我們這裏先假設這4個卷積核是一樣的,那麼我們直接把卷積核的行復製成4行就可以了,當然,實際生產中這4個核肯定是不一樣的,不然幹嘛要輸出4個通道呢
最後的結果也變成了4行了
再看看全部的過程
我們最後再把這個矩陣轉回featuremap該有的形狀就可以了。這樣就是caffe做卷積的全部流程,把圖都轉成一個矩陣,這樣直接做一次矩陣乘法就可以了。再gpu這種設備上,犧牲一點內存,使所有計算單元執行同樣的計算這樣效率是最高的。