tensorflow
1D畳み込みの使用
サーチ…
基本的な例
アップデート: TensorFlowはtf.nn.conv1dを使用してバージョン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では、入力とフィルタの高さを1
設定して2D畳み込みを使用することができます。
TFの高度な例を用いた1D畳み込みの背後にある数学
`1D畳み込みを手で計算するには、カーネルを入力に滑り込ませ、要素ごとの乗算を計算して合計します。
最も簡単な方法は、パディング= 0、ストライド= 1
あなたのinput = [1, 0, 2, 3, 0, 1, 1]
kernel = [2, 1, 3]
input = [1, 0, 2, 3, 0, 1, 1]
とkernel = [2, 1, 3]
2、1、3 kernel = [2, 1, 3]
の場合、畳み込みの結果は[8, 11, 7, 9, 4]
8,11,7,9,4 [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です。このため、ほとんどの場合、人々がゼロパディングという名前を付けています。 TFは、 tf.pad()を使用する必要がある任意のパディングに対して、 'VALID'と 'SAME'ゼロパディングをサポートします。 「VALID」パディングはパディングを全く意味しません。同じことは、出力が同じサイズの入力を持つことを意味します。同じ例で、 padding=1
畳み込みを計算してみましょう(私たちのカーネルは 'SAME'パディングです)。これを行うために、開始点/終了点に1のゼロを持つ配列を追加するだけです: 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]
1、8、11、7、9、4、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
要素のスライドとn番目の要素ごとの選択と同じです。
したがって、前の例をpadding=1
で使用してstride
を2に変更すると、以前の結果[1, 8, 11, 7, 9, 4, 3]
stride
を取り、各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)