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"
패딩을 사용하면 "메이크업"패딩 입력이 없습니다. 레이어는 유효한 입력 데이터 만 사용 합니다 .
때 stride
1 (풀링 이상의 회선 더 일반), 우리는 다음과 같은 구별 생각할 수 있습니다 :
"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=1
2 차원 텐서에 적용된 제로 패딩의 예입니다 .
커널에 임의의 패딩을 사용할 수 있지만 일부 패딩 값은 다른 패딩보다 자주 사용됩니다.
- 유효한 패딩 . 가장 쉬운 경우는 패딩이 전혀 없다는 것을 의미합니다. 데이터를 그대로 유지하십시오.
- 동일한 패딩은 때때로 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 경계'를 추가하여 입력 크기로 유지됩니다.
이 직관적 인 설명이 도움이 되길 바랍니다.
'development' 카테고리의 다른 글
채색 된 루비 출력 (0) | 2020.03.31 |
---|---|
색상 색조 UIButton 이미지 (0) | 2020.03.31 |
노드 0.12에`node-sass`를 다시 설치 하시겠습니까? (0) | 2020.03.31 |
Blob URL은 무엇이며 왜 사용됩니까? (0) | 2020.03.31 |
PHP에서 적절한 리포지토리 패턴 디자인? (0) | 2020.03.31 |