web-dev-qa-db-ja.com

Tensorflowのtf.nn.max_poolの 'SAME'と 'VALID'のパディングの違いは何ですか?

tensorflowname__のtf.nn.max_poolにおける 'SAME'と 'VALID'のパディングの違いは何ですか?

私の考えでは、「有効」とは、最大プールを行うときに、境界の外側にゼロの埋め込みがないことを意味します。

ディープラーニングのための畳み込み演算の手引き によると、プール演算子にはパディングがない、つまりtensorflowname__の 'VALID'だけを使用するということです。しかし、tensorflowname__の最大プールの「同じ」パディングは何ですか?

221
karl_TUM

明確にするために例を挙げます。

  • x:形状[2、3]の入力画像、1チャンネル
  • valid_pad:2x2カーネルの最大プール、ストライド2および有効なパディング。
  • same_pad:2x2カーネルの最大プール、ストライド2および同じパディング(これは クラシック への道です)

出力形状は以下のとおりです。

  • valid_pad:ここではパディングはないので、出力形状は[1、1]です。
  • same_pad:ここでは、画像を[2、4]の形にパディングし(-infを付けてからmax poolを適用)、出力の形は[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.]

120

あなたがアスキーアートが好きなら:

  • パディングなしの"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"は左右に均等に埋めようとしますが、追加する列の数が奇数の場合は、この例のように右側に余分な列が追加されます(同じロジックが垂直方向にも適用されます。下部にゼロの行)。
479
MiniQuark

strideが1(プーリングよりも畳み込みで一般的)の場合、以下の区別が考えられます。

  • "SAME":出力サイズは入力サイズと同じ 同じ です。これは、フィルタウィンドウが入力マップの外側にずれることを必要とし、それ故、パディングする必要がある。
  • "VALID":フィルタウィンドウは入力マップ内の valid の位置にあるため、出力サイズはfilter_size - 1だけ縮小されます。パディングは発生しません。
120
YvesgereY

TensorFlow畳み込み の例は、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]))
    
76
RoyaumeIX

パディングは、入力データのサイズを増やすための操作です。 1次元データの場合は、配列に定数を追加/追加するだけです。2次元では、マトリックスをこれらの定数で囲みます。 n-dimでは、n-dimハイパーキューブを定数で囲みます。ほとんどの場合、この定数はゼロであり、ゼロ詰めと呼ばれます。

これは、2次元テンソルにp=1を適用したゼロ詰めの例です。 enter image description here


カーネルには任意のパディングを使用できますが、いくつかのパディング値は他のものよりも頻繁に使用されます。

  • 有効なパディング 。最も簡単なケースは、パディングがまったくないことを意味します。データをそのままにしてください。
  • 同じパディング 時々 HALFパディングと呼ばれる 。これはSAMEと呼ばれます。ストライド= 1の畳み込み(またはプーリング)では、入力と同じサイズの出力が生成されるためです。これはHALFと呼ばれます。サイズがkのカーネルの場合 enter image description here
  • FULLパディング は、パディングされた要素だけでは畳み込みにならない最大パディングです。サイズがkのカーネルの場合、このパディングはk - 1と等しくなります。

TFで任意のパディングを使用するには、 tf.pad() を使用します。

43
Salvador Dali

簡単な説明

VALID:パディングを適用しません。つまり、入力画像がフィルタで完全に覆われ、指定した値に移動するように、すべての次元が valid であると仮定します。

SAME:入力画像がフィルタで完全に覆われ、指定した幅に移動するように、(必要に応じて)入力にパディングを適用します。ストライド1では、これにより、出力イメージのサイズが入力と同じ 同じ になります。

ノート

  • これは、convレイヤとmax poolレイヤにも同じように適用されます。
  • 画像の一部をドロップしても物事が「無効」になることはないので、「有効」という用語はちょっとした誤称です。いつかあなたはそれさえ欲しいかもしれません。これはおそらくNO_PADDINGと呼ばれるべきです。
  • 「同じ」という用語は、出力次元が入力次元と同じ場合に1のストライドに対してのみ意味があるため、誤称です。例えば2のストライドの場合、出力寸法は半分になります。これはおそらくAUTO_PADDINGと呼ばれるべきです。
  • SAME(つまり自動埋め込みモード)では、Tensorflowは左右両方に均等にパディングを広げようとします。
  • VALID(つまり、パディングモードなし)では、あなたのフィルタとストライドが入力画像を完全にカバーしていない場合、Tensorflowは右および/または下のセルをドロップします。
22
Shital Shah

パディングには3つの選択肢があります。有効(パディングなし)、同じ(または半分)、フルです。あなたはここで(Theanoで)説明を見つけることができます: http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html

  • 有効なパディングまたはパディングなし

有効なパディングはゼロパディングを含まないので、それは有効な入力のみをカバーし、人為的に生成されたゼロは含みません。出力の長さは、ストライドs = 1の場合、カーネルサイズkに対して((入力の長さ) - (k-1))です。

  • 同じまたは半パディング:

同じパディングは、s = 1のとき、出力のサイズを入力のサイズと同じにします。 s = 1の場合、埋められるゼロの数は(k-1)です。

  • フルパディング:

フルパディングとは、カーネルが入力全体にわたって実行されることを意味します。したがって、最後に、カーネルは1つの入力のみを満たし、それ以外はゼロを満たすことがあります。 s = 1の場合、埋められるゼロの数は2(k-1)です。 s = 1の場合、出力の長さは((入力の長さ)+(k-1))になります。

したがって、パディングの数:(有効)<=(同じ)<=(フル)

11

私は公式のテンソルフロードキュメントからこの答えを引用しています 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]))

パディング値は常にゼロです。

9
Vaibhav Dixit

説明 ここ そしてTristanの回答をフォローしているうちに、私は通常これらの素早い関数をサニティチェックに使います。

# a function to help us stay clean
def getPaddings(pad_along_height,pad_along_width):
    # if even.. easy..
    if pad_along_height%2 == 0:
        pad_top = pad_along_height / 2
        pad_bottom = pad_top
    # if odd
    else:
        pad_top = np.floor( pad_along_height / 2 )
        pad_bottom = np.floor( pad_along_height / 2 ) +1
    # check if width padding is odd or even
    # if even.. easy..
    if pad_along_width%2 == 0:
        pad_left = pad_along_width / 2
        pad_right= pad_left
    # if odd
    else:
        pad_left = np.floor( pad_along_width / 2 )
        pad_right = np.floor( pad_along_width / 2 ) +1
        #
    return pad_top,pad_bottom,pad_left,pad_right

# strides [image index, y, x, depth]
# padding 'SAME' or 'VALID'
# bottom and right sides always get the one additional padded pixel (if padding is odd)
def getOutputDim (inputWidth,inputHeight,filterWidth,filterHeight,strides,padding):
    if padding == 'SAME':
        out_height = np.ceil(float(inputHeight) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth) / float(strides[2]))
        #
        pad_along_height = ((out_height - 1) * strides[1] + filterHeight - inputHeight)
        pad_along_width = ((out_width - 1) * strides[2] + filterWidth - inputWidth)
        #
        # now get padding
        pad_top,pad_bottom,pad_left,pad_right = getPaddings(pad_along_height,pad_along_width)
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'total pad along height' , pad_along_height
        print 'total pad along width' , pad_along_width
        print 'pad at top' , pad_top
        print 'pad at bottom' ,pad_bottom
        print 'pad at left' , pad_left
        print 'pad at right' ,pad_right

    Elif padding == 'VALID':
        out_height = np.ceil(float(inputHeight - filterHeight + 1) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth - filterWidth + 1) / float(strides[2]))
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'no padding'


# use like so
getOutputDim (80,80,4,4,[1,1,1,1],'SAME')
5
ahmedhosny

パディングのオン/オフ入力の有効サイズを決定します。

VALID:埋め込みなし。畳み込み演算などは、「有効」な場所、つまりテンソルの境界に近すぎない場所でのみ実行されます。
3 x 3のカーネルと10 x 10のイメージでは、境界の内側の8 x 8領域で畳み込みを実行します。

SAME:パディングが提供されています。あなたの操作が近隣を参照するときはいつでも(どんなに大きくても)、その近隣が元のテンソルの外側に広がるときゼロ値が提供され、その操作が境界値に対しても働くことを可能にします。
3 x 3のカーネルと10 x 10のイメージでは、10 x 10の領域全体で畳み込みを実行します。

4
Laine Mikael

_ valid _ padding:これはパディングが0の場合です。混乱がないことを願っています。

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
print (valid_pad.get_shape()) # output-->(1, 2, 1, 1)

_ same _ padding: official docs に記載されているように、2つの条件を別々に考慮する必要があるため、これは最初から理解するのが難しいです。

として入力を取りましょう  として出力 、パディングとして 、のように歩きます  カーネルサイズ  (1次元のみが考慮されます)

ケース01: 

ケース02:  : 

パディングに使用できる最小値を計算します。の値から  既知であり、の値  この式を使って見つけることができます 

この例を考えましょう。

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
print (same_pad.get_shape()) # --> output (1, 2, 2, 1)

ここでxの次元は(3,4)です。それから水平方向が取られれば(3):

垂直方向をとる場合(4):

これがTFで _ same _ paddingが実際にどのように機能するかを理解するのに役立つことを願っています。

2
GPrathap

General Formula

ここで、WおよびHは入力の幅および高さ、Fはフィルタ寸法、Pはパディングサイズ(すなわちパディングされる行または列の数)である。

同じパディングの場合:

SAME Padding

有効なパディングの場合:

VALID padding

0
Shivam Kushwaha