development

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

big-blog 2020. 3. 31. 08:18
반응형

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


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

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

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


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

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


아스키 아트를 좋아한다면 :

  • "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"패딩을 사용하면 "메이크업"패딩 입력이 없습니다. 레이어는 유효한 입력 데이터 만 사용 합니다 .

stride1 (풀링 이상의 회선 더 일반), 우리는 다음과 같은 구별 생각할 수 있습니다 :

  • "SAME": 출력 크기는 입력 크기 와 동일 합니다. 이를 위해서는 필터 창이 입력 맵 밖으로 미끄러 져 들어가야하므로 패딩이 필요합니다.
  • "VALID": 필터 창이 입력 맵 내 에서 유효한 위치에 유지 되므로 출력 크기가로 줄어 듭니다 filter_size - 1. 패딩이 발생하지 않습니다.

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

패딩은 입력 데이터의 크기를 늘리는 작업입니다. 1 차원 데이터의 경우 상수로 배열을 추가 / 추가하고 2 차원에서는 이러한 상수로 행렬을 둘러 쌉니다. n-dim에서는 n-dim 하이퍼 큐브를 상수로 둘러 쌉니다. 대부분의 경우이 상수는 0이며이를 제로 패딩이라고합니다.

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


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

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

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


빠른 설명

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

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

노트

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

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

패딩 값은 항상 0입니다.


패딩에는 유효 (패딩 없음), 동일 (또는 절반), 전체의 세 가지 선택이 있습니다. 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))입니다.

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


여기 설명 과 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')

유효한 패딩 : 패딩이없는 것입니다. 혼란이 없기를 바랍니다.

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 패딩이 실제로 어떻게 작동 하는지 이해하는 데 도움이 되기를 바랍니다.


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

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

SAME:패딩이 제공됩니다. 작업이 이웃을 참조 할 때마다 (큰 크기에 상관없이) 해당 이웃이 원래 텐서 외부로 확장되어 해당 작업이 경계 값에서도 작동 할 수 있도록 0이 제공됩니다.
3x3 커널과 10x10 이미지를 사용하면 전체 10x10 영역에서 컨볼 루션을 수행하게됩니다.


일반 식

여기서 W와 H는 입력의 너비와 높이이고, F는 필터 크기이며, P는 패딩 크기입니다 (즉, 채워질 행 또는 열 수).

같은 패딩의 경우 :

같은 패딩

유효한 패딩의 경우 :

유효한 패딩


요약하면 '유효한'패딩은 패딩이 없음을 의미합니다. 컨볼 루션 레이어의 출력 크기는 입력 크기 및 커널 크기에 따라 줄어 듭니다.

반대로 '동일한'패딩은 패딩을 사용하는 것을 의미합니다. 컨볼 루션 레이어의 출력 크기는 컨볼 루션을 계산할 때 입력 데이터 주위에 일정한 수의 '0 경계'를 추가하여 입력 크기로 유지됩니다.

이 직관적 인 설명이 도움이 되길 바랍니다.

참고 URL : https://stackoverflow.com/questions/37674306/what-is-the-difference-between-same-and-valid-padding-in-tf-nn-max-pool-of-t

반응형