tensorflow의 tf.nn.max_pool에서 'SAME'과 'VALID'패딩의 차이점은 무엇입니까?


309

'SAME'과의 '유효'패딩의 차이 무엇입니까 tf.nn.max_pool의는 tensorflow?

내 의견으로는, 'VALID'는 우리가 최대 풀을 할 때 가장자리 외부에 패딩이 없다는 것을 의미합니다.

딥 러닝을위한 컨볼 루션 산술 가이드 에 따르면 풀 연산자에는 패딩이 없을 것입니다 tensorflow. 그러나 max pool의 'SAME'패딩은 tensorflow무엇입니까?


3
자세한 내용은 tensorflow.org/api_guides/python/… 을 확인 하십시오. 이것이 tf가 수행 한 방식입니다.
GabrielChu


4
패딩과 보폭이 어떻게 작동하는지 이해하려면이 놀라운 GIF를 확인하십시오. 링크
Deepak

1
@GabrielChu 링크가 종료 된 것으로 보이며 이제 일반 개요로 리디렉션됩니다.
matt

Tensorflow를 2.0으로 업그레이드하면 Keras로 대체되며 Keras 설명서에서 풀링 정보를 찾을 수 있다고 생각합니다. @matt
GabrielChu

답변:


163

더 명확하게하기 위해 예를 들어 보겠습니다.

  • x: 형상 [2, 3], 1 채널의 입력 이미지
  • valid_pad: 2x2 커널, 스트라이드 2 및 VALID 패딩이있는 최대 풀.
  • same_pad: 2x2 커널, 스트라이드 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.]


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" 왼쪽과 오른쪽으로 고르게 패딩하려고하지만 추가 할 열의 수가 홀수 인 경우이 예와 같이 오른쪽에 여분의 열을 추가합니다 (동일한 논리가 수직으로 적용됨 : 여분의 행이있을 수 있음) 맨 아래에 0).

편집 :

이름에 관하여 :

  • 으로 "SAME"는 (1)의 보폭을 사용하는 경우 패딩 레이어의 출력은 것 같은 그 입력으로 공간 치수.
  • "VALID"패딩을 사용하면 "만들기"패딩 입력이 없습니다. 레이어는 유효한 입력 데이터 만 사용 합니다 .

"SAME"는 "이미지 너비가 필터 너비의 배수가 아니거나 이미지 높이가 필터 높이의 배수가 아닌 경우 필터 크기를 변경할 필요가 없도록 제로 패딩 사용"을 의미합니다. "? 너비가 문제인 경우 "필터 너비의 배수까지 0을 갖는 패드"와 같이?
StatsSorceress가

2
내 자신의 측면 질문에 대답 : 아니오, 제로 패딩의 요점이 아닙니다. 입력에 사용할 필터 크기 (제로 패딩 포함)를 선택하지만 필터 크기 다음에는 제로 패딩을 선택하지 않습니다.
StatsSorceress 1

본인의 답변 @StatsSorceress 이해하지 못합니다. 모든 입력이 일부 필터에 의해 커버되도록 충분한 제로를 (가능한 한 대칭으로) 충분히 추가하는 것 같습니다. 맞습니까?
guillefix

2
좋은 대답은 다음과 같습니다 -inf. 텐서 값이 음수 일 수있는 경우 max_pooling의 패딩은입니다 .
Tones29

ksize = 2, stride = 2이고 SAME 패딩을 사용하면 입력 너비가 짝수 인 경우 어떻게됩니까? 최대 풀링 이미지 너비가 416 픽셀 너비에서 208 픽셀로 감소한 후 maxpool에 대해 stride = 2, ksize = 2 인 SAME 패드를 사용하고 있습니다. 누구든지 이것을 명확히 할 수 있습니까?
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 하이퍼 큐브를 상수로 둘러 쌉니다. 대부분의 경우이 상수는 0이며이를 제로 패딩이라고합니다.

다음은 p=12 차원 텐서에 적용된 제로 패딩의 예입니다 . 여기에 이미지 설명을 입력하십시오


커널에 임의의 패딩을 사용할 수 있지만 일부 패딩 값은 다른 패딩보다 자주 사용됩니다.

  • 유효한 패딩 . 가장 쉬운 경우는 패딩이 전혀 없다는 것을 의미합니다. 데이터를 그대로 유지하십시오.
  • 동일한 패딩은 종종 HALF 패딩 이라고도 합니다. stride = 1의 컨볼 루션 (또는 풀링)의 경우 입력과 동일한 크기의 출력을 생성해야하므로 SAME 이라고 합니다. 크기가 큰 커널의 경우 HALF 라고 합니다.k 여기에 이미지 설명을 입력하십시오
  • FULL 패딩 은 최대 패딩으로 패딩 된 요소에 대해서만 컨벌루션이 발생하지 않습니다. 크기가 큰 커널의 k경우이 패딩은 같습니다 k - 1.

TF에서 임의의 패딩을 사용하려면 tf.pad()


32

빠른 설명

VALID: 패딩을 적용하지 마십시오. 즉, 입력 이미지가 필터로 완전히 덮이고 지정한 간격을 갖도록 모든 치수가 유효 하다고 가정 합니다.

SAME: 입력 이미지가 필터로 완전히 덮이고 지정한 범위를 넓히도록 입력 (필요한 경우)에 패딩을 적용합니다. 보폭 1의 경우 출력 이미지 크기가 입력 과 동일 합니다.

노트

  • 이는 같은 방식으로 최대 풀 레이어뿐만 아니라 전환 레이어에도 적용됩니다.
  • "유효한"이라는 용어는 이미지의 일부를 떨어 뜨릴 경우 사물이 "유효하지 않음"이기 때문에 약간 잘못되었습니다. 때때로 당신은 그것을 원할 수도 있습니다. 이것은 아마도 NO_PADDING대신 호출되었을 것입니다 .
  • "같은"이라는 용어는 출력 차원이 입력 차원과 같을 때 보폭 1에만 의미가 있기 때문에 잘못된 이름이기도합니다. 보폭이 2 인 경우 예를 들어 출력 치수가 절반이됩니다. 이것은 아마도 AUTO_PADDING대신 호출되었을 것입니다 .
  • 에서 SAME모두 왼쪽과 오른쪽에 (즉, 자동 패드 모드), Tensorflow 고르게 확산 패딩을 시도합니다.
  • 에서 VALID필터와 보폭 전체 커버 입력 이미지를하지 않는 경우 (즉, 패딩 모드), Tensorflow 오른쪽 및 / 또는 하단 세포 떨어질 것이다.

19

공식 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]))

패딩 값은 항상 0입니다.


1
솔직히 이것은 1의 보폭에 국한되지 않고 유일하게 유효하고 완전한 대답입니다. 그리고 필요한 것은 문서의 인용문입니다. +1
P-Gn

1
특히 당신이 가리키는 링크가 더 이상 작동하지 않으며 Google이 tf 웹 사이트에서 해당 정보를 삭제 한 것처럼 보이기 때문에이 답변을 얻는 데 매우 유용합니다!
다니엘

12

패딩에는 유효 (패딩 없음), 동일 (또는 절반), 전체의 세 가지 선택이 있습니다. http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html 에서 설명을 Theano에서 찾을 수 있습니다.

  • 유효 또는 비 패딩 :

유효한 패딩에는 제로 패딩이 포함되지 않으므로 인위적으로 생성 된 0은 포함하지 않고 유효한 입력 만 포함합니다. 보폭 s = 1 인 경우 커널 크기 k에 대한 출력 길이는 ((입력 길이)-(k-1))입니다.

  • 같거나 반 여백 :

패딩이 동일하면 s = 1 일 때 출력 크기가 입력 크기와 동일합니다. s = 1 인 경우 채워지는 0의 수는 (k-1)입니다.

  • 전체 패딩 :

전체 패딩은 커널이 전체 입력을 실행한다는 것을 의미하므로 끝에서 커널은 하나의 입력 만 충족하고 0은 그렇지 않을 수 있습니다. 채워진 0의 수는 s = 1 인 경우 2 (k-1)입니다. s = 1 인 경우 출력 길이는 ((입력 길이) + (k-1))입니다.

따라서 패딩 수 : (유효한) <= (같은) <= (전체)


8

패딩 온 / 오프. 입력의 유효 크기를 결정합니다.

VALID:패딩이 없습니다. 컨볼 루션 등 ops는 "유효한"위치, 즉 텐서의 경계에 너무 가까이 있지 않은 위치에서만 수행됩니다.
3x3 커널과 10x10 이미지를 사용하면 테두리 내부의 8x8 영역에서 컨볼 루션을 수행하게됩니다.

SAME:패딩이 제공됩니다. 작업이 이웃을 참조 할 때마다 (큰 크기에 상관없이) 해당 이웃이 원래 텐서 외부로 확장되어 해당 작업이 경계 값에서도 작동 할 수 있도록 0 값이 제공됩니다.
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)

동일한 패딩 : 공식 문서 에서 언급 한 것처럼 두 가지 조건을 별도로 고려해야하기 때문에 처음에는 이해하기 까다 롭습니다 .

입력을 , 출력을 , 패딩을 , 보폭을 , 커널 크기를 단일 차원으로 간주합니다.

사례 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의 훌륭한 답변을 보완 하면서이 시각화가 매우 유용하다는 것을 알았습니다.

패딩 시각화

' 유효한 ' 패딩 이 첫 번째 숫자입니다. 필터 창은 이미지 안에 유지됩니다.

패딩 ' 동일 '은 세 번째 숫자입니다. 출력은 같은 크기입니다.


기사 에서 찾았습니다 .


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, 2.X. 1.x에 마이그레이션 경우

Average Pooling => tf.nn.avg_pool2d또는 tf.keras.layers.AveragePooling2DTF 2.x에서 사용되는 경우

tf.compat.v1.nn.avg_pool_v2또는 tf.compat.v2.nn.avg_pool또는 tf.compat.v1.keras.layers.AveragePooling2D또는 tf.compat.v1.keras.layers.AvgPool2D또는 tf.compat.v2.keras.layers.AveragePooling2D또는 tf.compat.v2.keras.layers.AvgPool2D, 2.X. 1.x에 마이그레이션 경우

Tensorflow 1.x에서 2.x 로의 마이그레이션에 대한 자세한 정보는이 마이그레이션 안내서 를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.