回顧圖像的卷積神經網絡的計算,關於圖像卷積前后大小改變的一個很重要的公式:輸入:w1*h1*c1,卷積核的超參數:卷積核的數量:K;卷積核的大小:F;卷積的步長:S;卷積的零填充:P,卷積后的大小是多少呢?寬度:w2=(w1-F+2P)/S+1,高度同理,而通道數等於卷積核的數量K,所以卷積后圖像的大小為:w2*h2*K。什么時候會用到P呢,就是當我們想要得到輸出的大小,無法直接實現時,就會使用P來幫忙。
在tensorflow中有專門的用來做填充的函數:tf.pad()。參考了https://blog.csdn.net/qq_40994943/article/details/85331327,作者:路上病人。如要轉載望注明出處。
二維tensor
tf.pad( tensor,paddings, mode='CONSTANT',name=None)
輸入參數:tensor是待填充的張量,
paddings代表每一維填充多少行/列,它的維度一定要和tensor的維度是一樣的,這里的維度不是傳統上數學維度,如[[2,3,4],[4,5,6]]是一個2乘3的矩陣,但它依然是二維的,所以pad只能是[[1,2],[1,2]]這種。
mode 可以取三個值,分別是"CONSTANT" ,“REFLECT”,“SYMMETRIC”。
mode=“CONSTANT” 填充0
mode="REFLECT"映射填充,上下(1維)填充順序和paddings是相反的,左右(零維)順序補齊
mode="SYMMETRIC"對稱填充,上下(1維)填充順序是和paddings相同的,左右(零維)對稱補齊
這么聽起來好復雜的樣子,看看代碼就懂了。
代碼一:
t=[[2,3,4],[5,6,7]] print(tf.pad(t,[[1,2],[1,2]],"CONSTANT")))
結果是:
[[0, 0, 0, 0, 0, 0], [0, 2, 3, 4, 0, 0], [0, 5, 6, 7, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]
注意維數和paddings參數,首先輸入的張量是一個二維的,所以填充后的張量也一定是二維的,同時思考一下一個二維的tensor給它周圍填0,能怎么填呢?無外乎就是上下左右嘛,參數是一個2*2的列表,列表里的第一行[1,2]表示填充行,第一個數代表上面填充1行,第二個數代表下面填充2行,列表的第二行[1,2]就是用來填充列的,第一個數代表左邊填充1列,第二個數代表右邊填充2列。因為mode="constant"所以都填充0。
代碼二:
t=[[2,3,4],[5,6,7]] print(tf.pad(t,[[1,1],[2,2]],"REFLECT")))
結果是
[[7, 6, 5, 6, 7, 6, 5], [4, 3, 2, 3, 4, 3, 2], [7, 6, 5, 6, 7, 6, 5], [4, 3, 2, 3, 4, 3, 2]]
你一下就能懂這個例子主要是來說明當mode="reflect"時,如何填充張量,仔細看結果,能看出填充效果使得張量是相互交錯的,沒錯reflect就是反射和輝映的意思,所以就是交相輝映。那么具體是如何實現的呢?(是為了方便理解記憶如下分析,具體是先填充列還是行,我也不知道....-_-!)張量首先是進行行的交錯填充,填充的行數如上所說不再贅述,填充后的效果如下,
[[5, 6, 7], [ 2, 3, 4], [ 5, 6, 7], [ 2, 3, 4]]
然后再進行列的交錯填充,最終就是填充運行后的結果了。
代碼三:
t=[[2,3,4],[5,6,7]] print(tf.pad(t,[[1,1],[2,2]],"SYMMETRIC")))
結果:
[[3, 2, 2, 3, 4, 4, 3], [3, 2, 2, 3, 4, 4, 3], [6, 5, 5, 6, 7, 7, 6], [6, 5, 5, 6, 7, 7, 6]]
不多說空話,直接分析,當mode="symmetric",這個單詞的意思就是對稱的意思,所以填充后的張量是能夠上下對稱,左右對稱的。同上分析,先行后列。
三維tensor
但是當我們在實際代碼中,我們通常是對一個batch的三維圖像進行填充,但是我們並不會進行多的填充,僅僅是在三維圖像中同時分別填充每一層,寫代碼時得注意到上面所說的paddings的維數一定要與張量的維數相等,所以我們的實際代碼如下:
padded_input = tf.pad(batch_input, [[0, 0], [1, 1], [1, 1], [0, 0]], mode="CONSTANT")
paddings中除了關於圖像的height,weight需要填充,其他參數用零代替。