tensorflow
TF의 고급 예제를 사용한 2D 컨볼 루션 뒤의 수학
수색…
소개
2D 컨볼 루션은 1D 컨볼 루션을 계산하는 것과 비슷한 방식으로 계산됩니다. 커널을 입력 위에 밀어 넣고 요소 별 곱셈을 계산하여 합계합니다. 그러나 여러분의 커널 / 입력이 배열이 아닌, 여기서는 행렬입니다.
패딩 없음, 스트라이드 = 1
이것은 가장 쉬운 계산법과 함께 가장 기본적인 예제입니다. input
과 kernel
이 다음과 kernel
가정 해 보겠습니다.
커널을 컴파일하면 다음과 같은 결과를 얻게됩니다 : 이는 다음과 같은 방식으로 계산됩니다.
- 14 = 4 * 1 + 3 * 0 + 1 * 1 + 2 * 2 + 1 * 1 + 0 * 0 + 1 * 0 + 2 * 0 + 4 * 1
- 6 = 3 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 0 * 1 + 1 * 0 + 2 * 0 + 4 * 0 + 1 * 1
- 6 = 2 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 2 * 1 + 4 * 0 + 3 * 0 + 1 * 0 + 0 * 1
- 12 = 1 * 1 + 0 * 0 + 1 * 1 + 2 * 2 + 4 * 1 + 1 * 0 + 1 * 0 + 0 * 0 + 2 * 1
TF의 conv2d 함수는 일괄 처리로 회선을 계산하고 약간 다른 형식을 사용합니다. 입력의 경우 커널의 [batch, in_height, in_width, in_channels]
은 [filter_height, filter_width, in_channels, out_channels]
입니다. 따라서 올바른 형식으로 데이터를 제공해야합니다.
import tensorflow as tf
k = tf.constant([
[1, 0, 1],
[2, 1, 0],
[0, 0, 1]
], dtype=tf.float32, name='k')
i = tf.constant([
[4, 3, 1, 0],
[2, 1, 0, 1],
[1, 2, 4, 1],
[3, 1, 0, 2]
], dtype=tf.float32, name='i')
kernel = tf.reshape(k, [3, 3, 1, 1], name='kernel')
image = tf.reshape(i, [1, 4, 4, 1], name='image')
그 후에 컨볼 루션은 다음과 같이 계산됩니다.
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "VALID"))
# VALID means no padding
with tf.Session() as sess:
print sess.run(res)
우리가 손으로 계산 한 것과 동등합니다.
일부 패딩, 스트라이드 = 1
패딩은 말하기의 단지 멋진 이름입니다. 입력 행렬을 일정하게 둘러싸십시오. 대부분의 경우 상수는 0이므로 사람들이 0으로 채우는 이유입니다. 따라서 원래 입력에서 1의 패딩을 사용하려면 ( padding=0, strides=1
첫 번째 예제를 확인하십시오.) 행렬은 다음과 같습니다.
회선의 값을 계산하려면 동일한 슬라이딩을 수행하십시오. 이 경우 중간에있는 많은 값을 다시 계산할 필요가 없습니다 (이전 예제와 동일 할 것입니다. 아이디어는 간단하므로 여기에 모든 계산을 표시하지 않습니다.) 결과는 다음과 같습니다.
어디에
- 5 = 0 * 1 + 0 * 0 + 0 * 1 + 0 * 2 + 4 * 1 + 3 * 0 + 0 * 0 + 0 * 1 + 1 * 1
- ...
- 6 = 4 * 1 + 1 * 0 + 0 * 1 + 0 * 2 + 2 * 1 + 0 * 0 + 0 * 0 + 0 * 0 + 0 * 1
TF는 conv2d 함수에서 임의의 패딩을 지원하지 않으므로 지원되지 않는 패딩이 필요한 경우 tf.pad ()를 사용 하십시오 . 운좋게도 우리의 입력에 대해 패딩 'SAME'은 패딩 = 1과 같을 것입니다. 따라서 이전 예제에서 거의 변경하지 않아도됩니다.
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "SAME"))
# 'SAME' makes sure that our output has the same size as input and
# uses appropriate padding. In our case it is 1.
with tf.Session() as sess:
print sess.run(res)
답은 손으로 계산 한 것과 같은지 확인할 수 있습니다.
패딩과 스트라이드 (가장 일반적인 경우)
이제 우리는 이전에 설명한 패딩 된 예제에 strided convolution을 적용하고 p = 1, s = 2
컨볼 루션을 계산할 것입니다.
이전에 strides = 1
을 사용했을 때 우리의 슬라이딩 윈도우는 1 위치 씩 움직였습니다. strides = s
는 s
위치만큼 이동합니다 ( s^2
요소를 더 적게 계산해야합니다. 그러나 우리의 경우에는 바로 가기를 취할 수 있고 우리는 이미 s = 1
대한 값을 계산했기 때문에 우리의 경우 두 번째 요소를 잡을 수 있습니다.
따라서 해가 s = 1
경우
s = 2
경우 다음과 같습니다.
이전 행렬에서 값 14, 2, 12, 6의 위치를 확인하십시오. 코드에서 수행해야 할 유일한 변경 사항은 폭과 높이 치수 (2-nd, 3-rd)에 대해 strides를 1에서 2로 변경하는 것입니다.
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 2, 2, 1], "SAME"))
with tf.Session() as sess:
print sess.run(res)
그건 그렇고, 우리가 다른 차원에서 다른 진보를 사용하는 것을 막을 수있는 방법은 없습니다.