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


309

「SAME」とで「有効」パディングの違いは何であるtf.nn.max_poolのはtensorflow

私の意見では、「有効」とは、max poolを実行したときに、エッジの外側にゼロパディングがないことを意味します。

ディープラーニングのたたみ込み演算のガイドによると、プール演算子にはパディングがない、つまりの 'VALID'を使用するだけですtensorflow。しかし、最大プールの「SAME」パディングとはtensorflow何ですか?


3
詳細については、tensorflow.org / api_guides / python /…を確認してください。これが、tfが実行した方法です。
GabrielChu 2018年

3
これは、視覚化によるかなり詳細な回答です。
rbinnun

4
これらの素晴らしいgifをチェックして、パディングとストライドの動作を理解してください。リンク
ディーパック

1
@GabrielChuあなたのリンクは無効になっているようで、一般的な概要にリダイレクトされます。
マット

Tensorflowを2.0にアップグレードすると、Kerasに置き換わります。プール情報はKerasのドキュメントに記載されていると思います。@matt
GabrielChu

回答:


163

わかりやすくするために例を示します。

  • x:形状の入力画像[2、3]、1チャネル
  • valid_pad:2x2カーネル、ストライド2、および有効なパディングを持つ最大プール。
  • same_pad:2x2カーネル、ストライド2、同じパディングを備えた最大プール(これは古典的な方法です)

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

  • 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.]


603

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

  • "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" 左と右に均等にパディングしようとしますが、追加する列の数が奇数の場合、この例のように列を右に追加します(同じロジックが垂直に適用されます:追加の行がある場合があります)下部のゼロの)。

編集

名前について:

  • では"SAME"、あなたが1のストライドを使用する場合、パディング、層の出力があります同じ、その入力として、空間的な次元を。
  • "VALID"パディング、ない「作っアップ」パディング入力がありません。レイヤーは有効な入力データのみを使用します

画像の幅がフィルターの幅の倍数ではない場合、または画像の高さがフィルターの高さの倍数でない場合、「SAME」は「ゼロパディングを使用してフィルターサイズを変更する必要がないことを確認する」を意味しますか? 「?のように、幅に問題がある場合は、「フィルター幅の倍数までゼロを埋め込む」ですか?
StatsSorceress 2017年

2
私自身の副次的な質問への回答:いいえ、それはゼロパディングのポイントではありません。入力(ゼロパディングを含む)を処理するフィルターサイズを選択しますが、フィルターサイズの後にゼロパディングを選択しません。
StatsSorceress 2017

自分の答え@StatsSorceressがわかりません。すべての入力が何らかのフィルターでカバーされるように、(可能な限り対称的に)十分なゼロを追加しているようですが、私は正しいですか?
guillefix

2
正解です。追加するだけです。テンソル値が負になる可能性がある場合、max_poolingのパディングは-infです。
トーン29

ksize = 2、stride = 2、および同じパディングで入力幅が偶数の場合はどうなりますか?...その後、ゼロでパディングされるべきではありませんか?... 、彼らは同じプールを使用しています、maxpoolのstride = 2、ksize = 2 ... maxpooling後、画像の幅が416ピクセルの幅から208ピクセルに減少しました。誰かがこれを明確にできますか?
K.vindi

161

ときstride1(プーリング以外の畳み込みでより一般的な)で、我々は以下の違いを考えることができます。

  • "SAME":出力サイズは入力サイズと同じです。これには、フィルターウィンドウが入力マップの外側にスリップする必要があるため、パディングする必要があります。
  • "VALID":フィルターウィンドウは入力マップ内の有効な位置に留まるため、出力サイズはだけ縮小しfilter_size - 1ます。パディングは発生しません。

65
これは最終的に役に立ちます。この時点まで、と思われたSAMEVALID同様に呼ばれている可能性がありfoobar
omatai

7
「出力サイズは入力サイズと同じ」は、ストライド長が1の場合にのみ当てはまると思います
omsrisagar

92

TensorFlowコンボリューションの例では、との違いについての概要与えSAMEとしVALID

  • ための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]))

46

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

以下は、p=12次元テンソルに適用されたゼロパディングの例です。 ここに画像の説明を入力してください


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

  • 有効なパディング。最も簡単なケースは、パディングがないことを意味します。データはそのままにしておきます。
  • 同じパディングは、HALFパディングと呼ばれることもあります。これはSAMEと呼ばれます。ストライド= 1のたたみ込み(またはプーリング)では、入力と同じサイズの出力を生成する必要があるためです。サイズのカーネルのため、それはハーフと呼ばれていますk ここに画像の説明を入力してください
  • FULLパディングは、パディングされた要素のみを畳み込むことのない最大のパディングです。サイズがカーネルの場合k、このパディングはと同じk - 1です。

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


32

簡単な説明

VALID:パディングを適用しないでください。つまり、入力画像が指定したフィルターとストライドで完全にカバーされるように、すべての寸法が有効であると想定します。

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

ノート

  • これは、コンバージョンレイヤーと最大プールレイヤーに同様に適用されます
  • 「有効」という用語は、イメージの一部をドロップしても物事が「無効」にならないため、少し誤った名称です。時々あなたはそれを望みさえするかもしれません。これはおそらくNO_PADDING代わりに呼び出されるべきでした。
  • 「同じ」という用語は、出力次元が入力次元と同じである場合にストライドが1の場合にのみ意味があるため、誤称でもあります。たとえば、ストライドが2の場合、出力ディメンションは半分になります。これはおそらくAUTO_PADDING代わりに呼び出されるべきでした。
  • SAME(つまり、自動パッドモード)、Tensorflowは左右両方に均等に拡散されたパディングにしようとします。
  • ではVALID、あなたのフィルターとストライドがフルカバーの入力画像をしない場合(すなわち無パディングモード)、Tensorflowは右および/または下のセルをドロップします。

19

私は公式のtensorflowドキュメント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]))

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


1
率直に言って、これは周りの唯一の有効で完全な答えであり、1のストライドに限定されません。そして、必要なのはドキュメントからの引用だけです。+1
P-Gn 2018年

1
特にあなたが指しているリンクが機能しなくなり、Googleがtfウェブサイトからその情報を消去したように見えるので、この回答を見つけるのに非常に役立ちます。
ダニエル

12

パディングには、有効(パディングなし)、同じ(または半分)、フルの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))です。

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


8

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

VALID:パディングなし。たたみ込みなどの操作は、「有効」な場所、つまりテンソルの境界に近すぎない場所でのみ実行されます。
カーネルが3x3で画像が10x10の場合、境界内の8x8領域で畳み込みを実行します。

SAME:パディングが提供されます。操作が近傍を参照する場合は(大きさに関係なく)、近傍が元のテンソルの外側にある場合はゼロ値が提供され、その操作が境界値でも機能できるようになります。
カーネルが3x3でイメージが10x10の場合、10x10の領域全体でたたみ込みを実行します。


8

有効なパディング:これはゼロパディングです。混乱がないことを願っています。

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)

同じ パディング:これは、公式ドキュメントで言及されているように2つの条件を個別に考慮する必要があるため、最初は理解するのが難しいです。

入力を、出力を、パディングを、ストライドをとして、カーネルサイズをとしてみましょう(単一の次元のみが考慮されます)

ケース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パディングがどのように機能するかを理解するのに役立つことを願っています。


7

ここでの説明と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')

6

要約すると、「有効な」パディングはパディングがないことを意味します。畳み込み層の出力サイズは、入力サイズとカーネルサイズに応じて縮小します。

逆に、「同じ」パディングはパディングを使用することを意味します。ストライドが1に設定されている場合、畳み込みを計算するときに、入力データの周囲に特定の数の「0ボーダー」を追加することにより、畳み込み層の出力サイズが入力サイズとして維持されます。

この直感的な説明がお役に立てば幸いです。


5

一般式

ここで、WとHは入力の幅と高さ、Fはフィルターの次元、Pはパディングサイズ(つまり、パディングされる行または列の数)です。

同じパディングの場合:

同じパディング

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

有効なパディング


2

YvesgereYの素晴らしい答えを補完して、この視覚化は非常に役立つことがわかりました。

視覚化のパディング

パディング ' 有効 'は最初の図です。フィルターウィンドウは画像内にとどまります。

同じ」のパディングは3番目の図です。出力は同じサイズです。


この記事でそれを見つけました。


0

Tensorflow 2.0互換性のある回答:「有効な」および「同じ」パディングについての詳細な説明は上記で提供されています。

ただし、Tensorflow 2.x (>= 2.0)コミュニティのために、では、さまざまなプーリング機能とそれぞれのコマンドを指定します。

1.xの関数

tf.nn.max_pool

tf.keras.layers.MaxPool2D

Average Pooling => None in tf.nn, tf.keras.layers.AveragePooling2D

2.xの機能

tf.nn.max_pool2.xのに使用している場合tf.compat.v1.nn.max_pool_v2またはtf.compat.v2.nn.max_pool1.xから2.xのに移行した場合、

tf.keras.layers.MaxPool2D 2.xおよび

tf.compat.v1.keras.layers.MaxPool2Dまたはtf.compat.v1.keras.layers.MaxPooling2Dまたは tf.compat.v2.keras.layers.MaxPool2Dまたはtf.compat.v2.keras.layers.MaxPooling2D、1.xから2.xに移行した場合。

Average Pooling => tf.nn.avg_pool2dまたはtf.keras.layers.AveragePooling2D、TF 2.xおよび

tf.compat.v1.nn.avg_pool_v2or tf.compat.v2.nn.avg_poolまたはtf.compat.v1.keras.layers.AveragePooling2Dor tf.compat.v1.keras.layers.AvgPool2Dまたはtf.compat.v2.keras.layers.AveragePooling2Dor tf.compat.v2.keras.layers.AvgPool2D、1.xから2.xに移行した場合。

Tensorflow 1.xから2.xへの移行の詳細については、この移行ガイドをご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.