tensorflow
1D 컨볼 루션 사용하기
수색…
기본 예제
업데이트 : TensorFlow 지금 사용 버전 r0.11 이후 1D 컨볼 루션을 지원 tf.nn.conv1d
.
길이가 10
이고 차원이 16
기본 예제를 고려하십시오. 배치 크기는 32
입니다. 따라서 우리는 입력 모양 [batch_size, 10, 16]
가진 자리 표시자를 가지고 있습니다.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
폭 3의 필터를 만들고 16
채널을 입력으로 사용하고 16
채널을 출력합니다.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
마지막으로 tf.nn.conv1d
에 스트라이드와 패딩을 적용합니다.
- 보폭 : 정수
s
- 패딩 : 2D와 마찬가지로 작동합니다.
SAME
과VALID
중에서 선택할 수 있습니다.SAME
은 동일한 입력 길이를 출력하지만VALID
는 제로 패딩을 추가하지 않습니다.
예를 들어, 우리는 2의 보폭과 유효한 패딩을 취합니다.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
출력 형태는 [batch_size, 4, 16]
이어야합니다.
padding="SAME"
일 경우 출력 형태는 [batch_size, 5, 16]
됩니다.
이전 버전의 TensorFlow에서는 2D 콘볼 루션을 사용하면서 입력 및 필터의 높이를 1
설정할 수있었습니다.
TF의 고급 예제를 사용한 1D 컨볼 루션 뒤의 수학
`손으로 1D 컨볼 루션을 계산하려면, 커널을 입력 위에 밀어 넣고, 원소와 같은 곱셈을 계산하여 합산하십시오.
가장 쉬운 방법은 패딩 = 0, 스트라이드 = 1
따라서 input = [1, 0, 2, 3, 0, 1, 1]
과 kernel = [2, 1, 3]
이면 결과는 [8, 11, 7, 9, 4]
입니다. 다음과 같은 방식으로 계산됩니다.
- 8 = 1 * 2 + 0 * 1 + 2 * 3
- 11 = 0 * 2 + 2 * 1 + 3 * 3
- 7 = 2 * 2 + 3 * 1 + 0 * 3
- 9 = 3 * 2 + 0 * 1 + 1 * 3
- 4 = 0 * 2 + 1 * 1 + 1 * 3
TF의 conv1d 함수는 일괄 처리로 회선을 계산하므로 TF에서이를 수행하려면 올바른 형식으로 데이터를 제공해야합니다 (doc은 입력이 [batch, in_width, in_channels]
에 있어야한다고 설명하고 커널이 어떻게 표시되는지 설명합니다). 처럼). 그래서
import tensorflow as tf
i = tf.constant([1, 0, 2, 3, 0, 1, 1], dtype=tf.float32, name='i')
k = tf.constant([2, 1, 3], dtype=tf.float32, name='k')
print i, '\n', k, '\n'
data = tf.reshape(i, [1, int(i.shape[0]), 1], name='data')
kernel = tf.reshape(k, [int(k.shape[0]), 1, 1], name='kernel')
print data, '\n', kernel, '\n'
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'VALID'))
with tf.Session() as sess:
print sess.run(res)
이전에 우리가 계산 한 것과 같은 대답을 줄 것입니다 : [ 8. 11. 7. 9. 4.]
패딩과 컨볼 루션
패딩은 덧붙여 말하면서 약간의 가치를 부여하는 멋진 방법 일뿐입니다. 대부분의 경우이 값은 0이며, 이것이 대부분 사람들이 0으로 채우는 이름입니다. TF는 tf.pad () 를 사용해야하는 임의의 패딩에 대해 'VALID'및 'SAME'제로 패딩을 지원합니다. 'VALID'패딩은 패딩을 전혀 의미하지 않으며, 동일한 것은 출력의 입력 크기가 동일 함을 의미합니다. 같은 예에서 padding=1
컨볼 루션을 계산해 봅시다 (우리 커널의 경우 'SAME'패딩입니다). 이것을하기 위해 처음 / 끝에 input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
배열을 추가합니다.
여기서 모든 것을 다시 계산할 필요가 없다는 것을 알 수 있습니다 : 모든 요소는 첫 번째 / 마지막 요소를 제외하고는 동일하게 유지됩니다.
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
결과는 [1, 8, 11, 7, 9, 4, 3]
이며 이것은 TF로 계산 한 것과 같습니다 :
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
보폭이있는 회선
스트라이드를 사용하면 슬라이딩하면서 요소를 건너 뛸 수 있습니다. 앞의 모든 예제에서 우리는 1 개의 요소를 미끄러 뜨 렸습니다. 이제는 한 번에 s
요소를 밀어 넣을 수 있습니다. 앞의 예제를 사용할 것이기 때문에 트릭이 있습니다. n
요소로 밀어 내기는 1 개의 요소로 슬라이딩하고 n 번째의 모든 요소를 선택하는 것과 같습니다.
따라서 이전 예제를 padding=1
하고 stride
를 2로 변경하면 이전 결과 [1, 8, 11, 7, 9, 4, 3]
를 취하고 각 2-nd 요소를 남겨 둡니다. [1, 11, 9, 3]
. 다음과 같은 방법으로 TF에서이 작업을 수행 할 수 있습니다.
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)