一般我們認(rèn)為在計(jì)算卷積時(shí)渤愁,是卷積核與圖像中每個(gè)mxm大小的圖像塊做element-wise相乘慕趴,然后得到的結(jié)果相加得到一個(gè)值漾峡,然后再移動(dòng)一個(gè)stride攻旦,做同樣的運(yùn)算,直到整副輸入圖像遍歷完生逸,上述過程得到的值就組成了輸出特征牢屋。但是這樣運(yùn)算比較慢且预,我們用的深度學(xué)習(xí)框架可不是這么實(shí)現(xiàn)的。因此烙无,我們來學(xué)習(xí)一下tensorflow和pytorch中是如何實(shí)現(xiàn)卷積操作的锋谐。
1、tf.nn.conv2d()
def conv2d(input,filter,strides,padding,use_cudnn_on_gpu=True,data_format="NHWC",dilations=[1,1,1,1],name=None):
給定 4-D input 和 filter tensors計(jì)算2-D卷積.
其中截酷,input tensor 的 shape是: [B, H, W, C]
filter / kernel tensor 的 shape是:? [filter_height, filter_width, in_channels, out_channels]
這個(gè)op是這樣執(zhí)行的:
將filter 展開為一個(gè) shape 為[filter_height * filter_width * in_channels, out_channels] 大小的2-D 矩陣涮拗。
從 input tensor按照每個(gè)filter位置上提取圖像patches來構(gòu)成一個(gè)虛擬的shape大小為[batch, out_height, out_width,filter_height * filter_width * in_channels]的tensor 。
ps:把輸入圖像要經(jīng)行卷積操作的這一區(qū)域展成列向量的操作通常稱為im2col
對(duì)每個(gè)patch, 右乘以 filter matrix.得到[batch, out_height, out_width,out_channels]大小的輸出迂苛。
其中三热,out_height和out_width是根據(jù)輸入尺寸等參數(shù)計(jì)算好的,不會(huì)計(jì)算的自行補(bǔ)充學(xué)習(xí)吧三幻。
詳細(xì)來說就漾,使用默認(rèn)的NHWC形式,
# 個(gè)人理解相當(dāng)于在input每個(gè)卷積核的位置上(包含了同一位值對(duì)應(yīng)的不同channel)提取的patches展開之后念搬,與展開的filter kernel相乘抑堡。
看圖很清楚,示意圖參考[3].
2朗徊、torch.nn.Conv2d()
pytorch源碼里面說的就沒有tf里說的清楚了首妖,點(diǎn)不動(dòng)
其中,\star是2D的cross-correlation_(互相關(guān)運(yùn)算符)荣倾, N是batch_size。
互相關(guān)函數(shù)是許多機(jī)器學(xué)習(xí)的庫中都會(huì)有實(shí)現(xiàn)的一個(gè)函數(shù)骑丸,和卷積運(yùn)算幾乎一樣但是沒有進(jìn)行核的翻轉(zhuǎn)舌仍。
參考資料:
[1]、https://github.com/tensorflow/tensorflow
[2]通危、https://buptldy.github.io/2016/10/01/2016-10-01-im2col/
[3]铸豁、https://blog.csdn.net/mieleizhi0522/article/details/80412804