當前位置: 首頁>>技術問答>>正文


TensorFlow的tf.nn.max_pool中’SAME’和’VALID’填充有什麽區別?

tensorflowtf.nn.max_pool中’SAME’和’VALID’填充有什麽區別?

在我看來,’VALID’意味著做最大池時,邊外沒有零填充。

根據A guide to convolution arithmetic for deep learning,它表示池化操作符中沒有填充,即隻使用tensorflow的’VALID’。但是什麽是tensorflow中最大池的’SAME’填充?

最佳解決方案

我舉一個例子來說明一點:

  • x:shape[2,3],1通道的輸入圖像

  • valid_pad:具有2×2內核,步幅2和VALID填充的最大池化。

  • same_pad:最大池化,2×2內核,步幅2和SAME填充(這是經典的方法)

輸出形狀為:

  • valid_pad:這裏沒有填充,所以輸出形狀為[1,1]

  • same_pad:在這裏,我們將圖像填充到形狀[2,4](使用-inf,然後應用最大池化),因此輸出形狀為[1,2]


x = tf.constant([[1., 2., 3.],
                 [4., 5., 6.]])

x = tf.reshape(x, [1, 2, 3, 1])  # give a shape accepted by tf.nn.max_pool

valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')

valid_pad.get_shape() == [1, 1, 1, 1]  # valid_pad is [5.]
same_pad.get_shape() == [1, 1, 2, 1]   # same_pad is  [5., 6.]

次佳解決方案

如果你喜歡ascii art:

  • "VALID" =沒有填充:

       inputs:         1  2  3  4  5  6  7  8  9  10 11 (12 13)
                      |________________|                dropped
                                     |_________________|
    
  • "SAME" =零填充:

                   pad|                                      |pad
       inputs:      0 |1  2  3  4  5  6  7  8  9  10 11 12 13|0  0
                   |________________|
                                  |_________________|
                                                 |________________|
    

在這個例子中:

  • 輸入寬度= 13

  • 過濾寬度= 6

  • 步幅= 5

注意:

  • "VALID"隻丟棄最右邊的列(或最底部的行)。

  • "SAME"嘗試向左和向右均勻填充,但如果要添加的列數是奇數,它將向右添加額外的列,如本示例中的情況(相同的邏輯垂直應用:可能有一個額外的底部的一排零)。

第三種解決方案

TensorFlow Convolution示例概述了SAMEVALID之間的差異:

  • 對於SAME填充,輸出高度和寬度計算如下:

out_height = ceil(float(in_height)/float(strides [1]))

out_width = ceil(float(in_width)/float(strides [2]))

  • 對於VALID填充,輸出高度和寬度計算如下:

out_height = ceil(float(in_height – filter_height + 1)/float(strides [1]))

out_width = ceil(float(in_width – filter_width + 1)/float(strides [2]))

第四種方案

stride為1時(更常見的是卷積而不是合並),我們可以想到以下區別:

  • "SAME":輸出大小與輸入大小相同。這需要過濾器窗口在輸入映射外滑動,因此需要填充。

  • "VALID":過濾器窗口保持在輸入映射內的有效位置,因此輸出大小會縮小filter_size - 1。沒有填充。

第五種方案

填充是一種增加輸入數據大小的操作。在一維數據的情況下,您隻需在數組中附加/前置一個常數,使用這些常數在2維度環繞矩陣中。在n-dim中,您可以使用常量包圍n-dim超立方體。在大多數情況下,此常數為零,稱為zero-padding。

以下是zero-padding與p=1應用於2-d張量的示例:

python,tensorflow,deep-learning


您可以為內核使用任意填充,但某些填充值的使用頻率高於其他填充值:

  • 有效填充。最簡單的情況,意味著根本沒有填充。隻需保留您的數據即可。

  • SAME填充有時稱為HALF填充。它被稱為SAME,因為對於stride = 1的卷積(或用於匯集),它應該產生與輸入相同大小的輸出。它被稱為HALF,因為對於大小為k的內核

  • FULL填充是最大填充,不會導致僅填充元素的卷積。對於大小為k的內核,此填充等於k - 1


要在TF中使用任意填充,可以使用tf.pad()

第六種方案

填充有三種選擇:有效(無填充),相同(或一半),填充。你可以在這裏找到解釋(在Theano):http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html

  • 有效或無填充:

有效填充不涉及零填充,因此它僅覆蓋有效輸入,不包括人工生成的零。如果步幅s = 1,則輸出的長度是((輸入的長度) – (k-1))對於內核大小k。

  • 相同或半填充:

當s = 1時,相同的填充使輸出的大小與輸入的大小相同。如果s = 1,則填充的零的數量是(k-1)。

  • 全填充:

完整填充意味著內核在整個輸入上運行,因此在最後,內核可能隻滿足一個輸入和零。如果s = 1,填充的零的數量是2(k-1)。如果s = 1,則輸出長度為((輸入長度​​)+(k-1))。

因此,填充數量:(有效)< =(相同)< =(完整)

第七種方案

快速解釋

VALID:不要應用任何填充,即假設所有尺寸都有效,以便輸入圖像完全被過濾器覆蓋並按指定步幅覆蓋。

SAME:將填充應用於輸入(如果需要),以便輸入圖像被過濾器完全覆蓋並按指定步幅。對於步幅1,這將確保輸出圖像大小與輸入相同。

注意

  • 這同樣適用於coov圖層和最大池化圖層

  • 術語”valid”有點用詞不當,因為如果丟棄部分圖像,事情就不會變成”invalid”。有時你甚至可能想要那樣。這可能應該被稱為”NO_PADDING”。

  • 術語”same”也是用詞不當,因為當輸出維數與輸入維度相同時,它隻對1的步幅有意義。例如,對於2的步幅,輸出尺寸將是一半。這可能應該被稱為”AUTO_PADDING”。

  • SAME(即auto-pad模式)中,Tensorflow將嘗試在左右兩側均勻分布填充。

  • VALID中(即無填充模式),如果過濾器和步幅未完全覆蓋輸入圖像,則Tensorflow將向右和/或底部單元格下降。

第八種方案

我從官方tensorflow docs https://www.tensorflow.org/api_guides/python/nn#Convolution引用這個答案對於’SAME’填充,輸出高度和寬度計算如下:

out_height = ceil(float(in_height) / float(strides[1]))
out_width  = ceil(float(in_width) / float(strides[2]))

並且頂部和左側的填充計算如下:

pad_along_height = max((out_height - 1) * strides[1] +
                    filter_height - in_height, 0)
pad_along_width = max((out_width - 1) * strides[2] +
                   filter_width - in_width, 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left

對於’VALID’填充,輸出高度和寬度計算如下:

out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))

並且填充值始終為零。

max pooling

參考資料

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/3881.html,未經允許,請勿轉載。