成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Tensorflow卷積實現原理+手寫python代碼實現卷積教程

瀏覽:159日期:2022-07-24 17:57:19

從一個通道的圖片進行卷積生成新的單通道圖的過程很容易理解,對于多個通道卷積后生成多個通道的圖理解起來有點抽象。本文以通俗易懂的方式講述卷積,并輔以圖片解釋,能快速理解卷積的實現原理。最后手寫python代碼實現卷積過程,讓Tensorflow卷積在我們面前不再是黑箱子!

注意:

本文只針對batch_size=1,padding=’SAME’,stride=[1,1,1,1]進行實驗和解釋,其他如果不是這個參數設置,原理也是一樣。

1 Tensorflow卷積實現原理

先看一下卷積實現原理,對于in_c個通道的輸入圖,如果需要經過卷積后輸出out_c個通道圖,那么總共需要in_c * out_c個卷積核參與運算。參考下圖:

Tensorflow卷積實現原理+手寫python代碼實現卷積教程

如上圖,輸入為[h:5,w:5,c:4],那么對應輸出的每個通道,需要4個卷積核。上圖中,輸出為3個通道,所以總共需要3*4=12個卷積核。對于單個輸出通道中的每個點,取值為對應的一組4個不同的卷積核經過卷積計算后的和。

接下來,我們以輸入為2個通道寬高分別為5的輸入、3*3的卷積核、1個通道寬高分別為5的輸出,作為一個例子展開。

2個通道,5*5的輸入定義如下:

#輸入,shape=[c,h,w]input_data=[ [[1,0,1,2,1], [0,2,1,0,1], [1,1,0,2,0], [2,2,1,1,0], [2,0,1,2,0]], [[2,0,2,1,1], [0,1,0,0,2], [1,0,0,2,1], [1,1,2,1,0], [1,0,1,1,1]], ]

對于輸出為1通道map,根據前面計算方法,需要2*1個卷積核。定義卷積核如下:

#卷積核,shape=[in_c,k,k]=[2,3,3]weights_data=[ [[ 1, 0, 1], [-1, 1, 0], [ 0,-1, 0]], [[-1, 0, 1], [ 0, 0, 1], [ 1, 1, 1]] ]

上面定義的數據,在接下來的計算對應關系將按下圖所描述的方式進行。

Tensorflow卷積實現原理+手寫python代碼實現卷積教程

由于Tensorflow定義的tensor的shape為[n,h,w,c],這里我們可以直接把n設為1,即batch size為1。還有一個問題,就是我們剛才定義的輸入為[c,h,w],所以需要將[c,h,w]轉為[h,w,c]。轉換方式如下,注釋已經解釋很詳細,這里不再解釋。

def get_shape(tensor): [s1,s2,s3]= tensor.get_shape() s1=int(s1) s2=int(s2) s3=int(s3) return s1,s2,s3def chw2hwc(chw_tensor): [c,h,w]=get_shape(chw_tensor) cols=[] for i in range(c): #每個通道里面的二維數組轉為[w*h,1]即1列 line = tf.reshape(chw_tensor[i],[h*w,1]) cols.append(line) #橫向連接,即將所有豎直數組橫向排列連接 input = tf.concat(cols,1)#[w*h,c] #[w*h,c]-->[h,w,c] input = tf.reshape(input,[h,w,c]) return input

同理,Tensorflow使用卷積核的時候,使用的格式是[k,k,in_c,out_c]。而我們在定義卷積核的時候,是按[in_c,k,k]的方式定義的,這里需要將[in_c,k,k]轉為[k,k,in_c],由于為了簡化工作量,我們規定輸出為1個通道,即out_c=1。所以這里我們可以直接簡單地對weights_data調用chw2hwc,再在第3維度擴充一下即可。

接下來,貼出完整的代碼:

import tensorflow as tfimport numpy as npinput_data=[ [[1,0,1,2,1], [0,2,1,0,1], [1,1,0,2,0], [2,2,1,1,0], [2,0,1,2,0]], [[2,0,2,1,1], [0,1,0,0,2], [1,0,0,2,1], [1,1,2,1,0], [1,0,1,1,1]], ]weights_data=[ [[ 1, 0, 1], [-1, 1, 0], [ 0,-1, 0]], [[-1, 0, 1], [ 0, 0, 1], [ 1, 1, 1]] ]def get_shape(tensor): [s1,s2,s3]= tensor.get_shape() s1=int(s1) s2=int(s2) s3=int(s3) return s1,s2,s3def chw2hwc(chw_tensor): [c,h,w]=get_shape(chw_tensor) cols=[] for i in range(c): #每個通道里面的二維數組轉為[w*h,1]即1列 line = tf.reshape(chw_tensor[i],[h*w,1]) cols.append(line) #橫向連接,即將所有豎直數組橫向排列連接 input = tf.concat(cols,1)#[w*h,c] #[w*h,c]-->[h,w,c] input = tf.reshape(input,[h,w,c]) return inputdef hwc2chw(hwc_tensor): [h,w,c]=get_shape(hwc_tensor) cs=[] for i in range(c): #[h,w]-->[1,h,w] channel=tf.expand_dims(hwc_tensor[:,:,i],0) cs.append(channel) #[1,h,w]...[1,h,w]---->[c,h,w] input = tf.concat(cs,0)#[c,h,w] return inputdef tf_conv2d(input,weights): conv = tf.nn.conv2d(input, weights, strides=[1, 1, 1, 1], padding=’SAME’) return convdef main(): const_input = tf.constant(input_data , tf.float32) const_weights = tf.constant(weights_data , tf.float32 ) input = tf.Variable(const_input,name='input') #[2,5,5]------>[5,5,2] input=chw2hwc(input) #[5,5,2]------>[1,5,5,2] input=tf.expand_dims(input,0) weights = tf.Variable(const_weights,name='weights') #[2,3,3]-->[3,3,2] weights=chw2hwc(weights) #[3,3,2]-->[3,3,2,1] weights=tf.expand_dims(weights,3) #[b,h,w,c] conv=tf_conv2d(input,weights) rs=hwc2chw(conv[0]) init=tf.global_variables_initializer() sess=tf.Session() sess.run(init) conv_val = sess.run(rs) print(conv_val[0]) if __name__==’__main__’: main()

上面代碼有幾個地方需要提一下,

由于輸出通道為1,因此可以對卷積核數據轉換的時候直接調用chw2hwc,如果輸入通道不為1,則不能這樣完成轉換。

輸入完成chw轉hwc后,記得在第0維擴充維數,因為卷積要求輸入為[n,h,w,c]

為了方便我們查看結果,記得將hwc的shape轉為chw

執行上面代碼,運行結果如下:

[[ 2. 0. 2. 4. 0.] [ 1. 4. 4. 3. 5.] [ 4. 3. 5. 9. -1.] [ 3. 4. 6. 2. 1.] [ 5. 3. 5. 1. -2.]]

這個計算結果是怎么計算出來的?為了讓大家更清晰的學習其中細節,我特地制作了一個GIF圖,看完這個圖后,如果你還看不懂卷積的計算過程,你可以來打我。。。。

Tensorflow卷積實現原理+手寫python代碼實現卷積教程

2 手寫Python代碼實現卷積

自己實現卷積時,就無須將定義的數據[c,h,w]轉為[h,w,c]了。

import numpy as npinput_data=[ [[1,0,1,2,1], [0,2,1,0,1], [1,1,0,2,0], [2,2,1,1,0], [2,0,1,2,0]], [[2,0,2,1,1], [0,1,0,0,2], [1,0,0,2,1], [1,1,2,1,0], [1,0,1,1,1]] ]weights_data=[ [[ 1, 0, 1], [-1, 1, 0], [ 0,-1, 0]], [[-1, 0, 1], [ 0, 0, 1], [ 1, 1, 1]] ]#fm:[h,w]#kernel:[k,k]#return rs:[h,w] def compute_conv(fm,kernel): [h,w]=fm.shape [k,_]=kernel.shape r=int(k/2) #定義邊界填充0后的map padding_fm=np.zeros([h+2,w+2],np.float32) #保存計算結果 rs=np.zeros([h,w],np.float32) #將輸入在指定該區域賦值,即除了4個邊界后,剩下的區域 padding_fm[1:h+1,1:w+1]=fm #對每個點為中心的區域遍歷 for i in range(1,h+1): for j in range(1,w+1): #取出當前點為中心的k*k區域 roi=padding_fm[i-r:i+r+1,j-r:j+r+1] #計算當前點的卷積,對k*k個點點乘后求和 rs[i-1][j-1]=np.sum(roi*kernel) return rs def my_conv2d(input,weights): [c,h,w]=input.shape [_,k,_]=weights.shape outputs=np.zeros([h,w],np.float32) #對每個feature map遍歷,從而對每個feature map進行卷積 for i in range(c): #feature map==>[h,w] f_map=input[i] #kernel ==>[k,k] w=weights[i] rs =compute_conv(f_map,w) outputs=outputs+rs return outputsdef main(): #shape=[c,h,w] input = np.asarray(input_data,np.float32) #shape=[in_c,k,k] weights = np.asarray(weights_data,np.float32) rs=my_conv2d(input,weights) print(rs) if __name__==’__main__’: main()

代碼無須太多解釋,直接看注釋。然后跑出來的結果如下:

[[ 2. 0. 2. 4. 0.] [ 1. 4. 4. 3. 5.] [ 4. 3. 5. 9. -1.] [ 3. 4. 6. 2. 1.] [ 5. 3. 5. 1. -2.]]

對比發現,跟Tensorflow的卷積結果是一樣的。

3 小結

本文中,我們學習了Tensorflow的卷積實現原理,通過也通過python代碼實現了輸出通道為1的卷積,其實輸出通道數不影響我們學習卷積原理。后面如果有機會的話,我們去實現一個更加健全,完整的卷積。

以上這篇Tensorflow卷積實現原理+手寫python代碼實現卷積教程就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Python 編程
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
中文一区二区在线观看| 国产精品分类| 成人午夜视频福利| 美女尤物久久精品| 亚洲欧洲国产日韩| 韩国三级中文字幕hd久久精品| 91一区二区在线观看| 欧美一区二区三区播放老司机| 麻豆精品视频在线观看免费 | 精品国产一区二区三区久久影院| 精品一区二区三区蜜桃| 欧美中文一区二区三区| 全部av―极品视觉盛宴亚洲| 久久久久国内| 亚洲一区二区精品久久av| 亚洲日产国产精品| 中文字幕一区免费在线观看| 91免费看片在线观看| 久久综合激情| 亚洲欧美区自拍先锋| 欧美在线精品一区| 精品国产91亚洲一区二区三区婷婷| 国内外成人在线| 欧美日韩和欧美的一区二区| 免费精品视频在线| 色一情一伦一子一伦一区| 日韩精品五月天| 麻豆九一精品爱看视频在线观看免费| 亚洲va韩国va欧美va| 一本一道综合狠狠老| 青青草国产精品亚洲专区无| 欧美色图免费看| 国产麻豆精品一区二区| 欧美一级一级性生活免费录像| 国产91在线|亚洲| 久久综合久久99| 欧美另类视频在线| 国产精品久久久久影院色老大| 亚洲一二区在线| 亚洲美女屁股眼交| 国产伦精品一区二区三区照片91 | 国产伦精品一区| 亚洲成人免费观看| 久久久国产精品一区二区三区| 日本成人中文字幕| 欧美日韩五月天| 国产一区二区h| 精品毛片乱码1区2区3区| 午夜久久黄色| 亚洲婷婷在线视频| 一本色道亚洲精品aⅴ| 国产一区二区导航在线播放| 久久久久国产精品麻豆ai换脸 | 狠狠色综合色综合网络| 色噜噜偷拍精品综合在线| 日本不卡不码高清免费观看| 欧美性xxxxx极品少妇| 国产成人在线网站| 337p日本欧洲亚洲大胆色噜噜| 欧美区高清在线| 亚洲激情五月婷婷| 在线免费精品视频| 风间由美一区二区av101| 欧美高清在线一区二区| 日韩午夜免费视频| 美国av一区二区| 精品对白一区国产伦| 亚洲国产高清视频| 日本在线不卡视频一二三区| 精品女同一区二区| 在线国产精品一区| 亚洲欧洲精品一区二区精品久久久| 亚洲你懂的在线视频| 国产精品乱码一区二区三区| 日韩在线播放一区二区| 日韩视频一区二区三区在线播放| 91视频国产观看| 一区二区三区精品在线观看| 欧美三级视频在线观看| 972aa.com艺术欧美| 一区二区成人在线| 这里只有精品电影| 好看的日韩av电影| 91蜜桃免费观看视频| 久久久精品综合| 国产精品久久久久久久久婷婷 | 国产在线精品一区二区三区不卡| 久久九九久精品国产免费直播| 亚洲欧美日韩精品综合在线观看| 国产毛片精品一区| 亚洲欧洲另类国产综合| 精品视频免费看| 欧美日韩天堂| 美女网站视频久久| 国产欧美日韩麻豆91| 玖玖玖国产精品| 欧美一区二区三区四区在线观看地址| 亚洲精品美国一| 7777精品伊人久久久大香线蕉超级流畅| 午夜欧美精品| 精品一区二区三区欧美| 中文字幕视频一区二区三区久| 欧美日韩免费视频| 亚洲视频精品| 色吧成人激情小说| 中文字幕亚洲成人| 欧美日韩1234| 亚洲精品裸体| 成人免费av在线| 亚洲综合激情小说| 日韩精品一区二区三区四区| 国产精品腿扒开做爽爽爽挤奶网站| 精品一区二区三区在线播放视频| 国产精品久久久久久久久免费丝袜| 欧美性感一类影片在线播放| 亚洲电影在线| 懂色av一区二区夜夜嗨| 亚洲动漫第一页| 久久久精品黄色| 欧美日韩一卡二卡三卡| 亚洲三级影院| av成人免费在线观看| 奇米色777欧美一区二区| 中文字幕亚洲区| 日韩一级二级三级| 久久久999| 欧美日韩国产不卡在线看| 韩国一区二区三区| 亚洲成av人片| 亚洲天堂精品在线观看| 精品国产乱码久久久久久牛牛| 久久综合九色综合久99| 亚洲午夜在线观看| 成人爱爱电影网址| 蜜桃在线一区二区三区| 亚洲精品欧美激情| 欧美激情艳妇裸体舞| 日韩午夜在线观看| 在线观看日韩一区| 国产农村妇女毛片精品久久莱园子| 欧美在线免费一级片| 国产剧情一区二区| 日韩影院在线观看| 亚洲精选一二三| 中文字幕乱码一区二区免费| 日韩欧美亚洲另类制服综合在线| 欧美综合一区二区| 久久国产高清| 一区二区av| 亚洲午夜精品国产| 欧美影视一区| 大陆成人av片| 国产一区二区福利| 免费观看一级特黄欧美大片| 亚洲一卡二卡三卡四卡无卡久久| 亚洲欧美在线另类| 中文字幕欧美激情一区| 日韩精品专区在线影院观看| 欧美福利视频一区| 欧美日韩亚洲综合一区| 色999日韩国产欧美一区二区| 国产一区二区久久久| 亚洲黄色影片| 亚洲一二三区精品| 欧美日韩在线观看一区二区三区| 97久久超碰国产精品电影| 国产91色综合久久免费分享| 国产精品99久久久久久宅男| 精品亚洲porn| 久久99精品国产.久久久久久| 美腿丝袜亚洲综合| 免费成人结看片| 亚洲成在人线在线播放| 亚洲精品福利视频网站| 国产精品天天看| 亚洲国产成人一区二区三区| 国产丝袜在线精品| 亚洲精品一区二区三区福利| 精品毛片乱码1区2区3区| 欧美成人激情免费网| 精品久久国产字幕高潮| 精品久久久三级丝袜| 日韩欧美一区在线| 日韩免费视频一区二区| 日韩免费性生活视频播放| 精品少妇一区二区三区在线视频| 日韩欧美亚洲另类制服综合在线| 欧美精品xxxxbbbb| 欧美在线观看18| 欧美日韩精品欧美日韩精品| 欧美欧美欧美欧美| 欧美一区欧美二区| 日韩精品一区二区三区视频播放 | 91精品国产综合久久婷婷香蕉| 欧美日韩三级视频| 欧美高清视频在线高清观看mv色露露十八| 欧美老女人第四色| 欧美videossexotv100| 国产亚洲美州欧州综合国| 亚洲影院理伦片|