卷積和轉置卷積,都涉及到padding, 那麼添加padding 的具體方式,就會影響到計算結果,因此搞清除tensorflow中卷積和轉置卷積的具體實現有助於模型的靈活部署應用。ide
舉例說明:部署
X: 1 2 3 4 5 input
6 7 8 9 10tensorflow
11 12 13 14 15擴展
16 17 18 19 20di
21 22 23 24 25 co
w: 1 1 1 1模型
1 2 1 1
1 1 3 1
1 1 1 4
如對於:tf.nn.conv2(X,w,stride=[1,1],padding='SAME')
須要在X 中添加3 行 3列, 那麼在tensorflow 中的添加方式以下:
left_w = 3/2 up_h =3/2
right_w = 3-left_w down_h = 3- up_h
也即: 添加padding 時如左右、上下不能呢個平均分配,則左邊<=右邊,上邊<=下邊
故,卷積後的 (0,0)位置的值爲, 1*2 + 2*1+ 3*1+ 6*1+7*3+8*1+11*1+12*1+14*4
X: 1 2 3 4 5 w: 1 1 1 1
6 7 8 9 10 1 2 1 1
11 12 13 14 15 1 2 3 1
16 17 18 19 20
21 22 23 24 25
tf.nn.conv2d_transpose(X,W,tf.stack([10,10]),strides=[2,2],padding="SAME")
一、對X擴展,
strides=[2,2] 故擴展後的 X 爲:(shape:10X10)
1 0 2 0 3 0 4 0 5 0
0 0 0 0 0 0 0 0 0 0
6 0 7 0 8 0 9 0 10 0
. . . . . . . . . .
. . . . . . . . . .
二、加padding,因爲padding = "SAME" 因此須要加 3行 3列
對X 擴展再加padding 後的 高和寬爲:
H = X.H * stride + (w.H-1)
W = X.W*stride + (w.W-1)
l_h = ceil(((w.H - 1)*1.0 + (stride - 1)) / 2.0); // 向上取整數
l_h = l_h>(w.H - 1) ? (w.H - 1) : l_h; // 在左邊添加padding 的列數
up_w = ceil(((w.W - 1)*1.0 + (stride - 1)) / 2.0) // 向上取整數
up_w = up_w>(w.W - 1) ? (w.W - 1) : up_h; // 在上邊添加padding 的行數
說明:
input.shape: 5X5 ; stride = 3 ; w.shape =5*5 padding = "SAME" 時
擴展後,input.shape = 15*15 , 其中 最右邊擴展2列, 最下邊擴展2行
加padding後, input.shape = 19*19, 其中在最左邊擴展3列, 最上邊擴展3行; 最右邊再擴展1列,最下邊再擴展1行
卷積(步長爲1)後 , output .shape = 15*15
三、卷積
tensorflow 中conv2d_transpose對卷積的實現有別於conv2, 至關於將 w 進行reverse 後進行卷積。