tensorflow
Med hjälp av 1D-upplösning
Sök…
Grundläggande exempel
Uppdatering: TensorFlow stöder nu 1D-upplösning sedan version r0.11 med tf.nn.conv1d
.
Tänk på ett grundläggande exempel med en inmatning av längd 10
och dimension 16
. Batchstorleken är 32
. Vi har därför en platshållare med inmatningsform [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
Vi skapar sedan ett filter med bredd 3, och vi tar 16
kanaler som ingång, och sänder också 16
kanaler.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Slutligen tillämpar vi tf.nn.conv1d
med ett steg och en stoppning:
- steg : heltal
s
- stoppning : detta fungerar som i 2D, du kan välja mellan
SAME
ochVALID
.SAME
kommer att mata ut samma ingångslängd, medanVALID
inte lägger till noll stoppning.
För vårt exempel tar vi ett steg på 2 och en giltig stoppning.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
Utgångsformen ska vara [batch_size, 4, 16]
.
Med padding="SAME"
skulle vi ha fått en utgångsform av [batch_size, 5, 16]
.
För tidigare versioner av TensorFlow kan du bara använda 2D-rullningar medan du ställer in höjden på ingångarna och filtren till 1
.
Matematik bakom 1D-upplösning med avancerade exempel i TF
`För att beräkna 1D-upplösning för hand skjuter du kärnan över ingången, beräknar de elementvisa multiplikationerna och summerar dem.
Det enklaste sättet är att stoppa = 0, steg = 1
Så om din input = [1, 0, 2, 3, 0, 1, 1]
och kernel = [2, 1, 3]
resultatet av upplösningen [8, 11, 7, 9, 4]
, vilket är beräknas på följande sätt:
- 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
TFs konv1d- funktion beräknar invändningar i partier, så för att göra detta i TF måste vi tillhandahålla data i rätt format (doc förklarar att input ska vara i [batch, in_width, in_channels]
, det förklarar också hur kärnan ska se ut tycka om). Så
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)
vilket ger dig samma svar som vi beräknade tidigare: [ 8. 11. 7. 9. 4.]
Konvolution med stoppning
Polstring är bara ett fint sätt att berätta lägga till och bero på dina input med något värde. I de flesta fall är detta värde 0, och det är därför folk ofta kallar det nollstopp. TF stöder 'VALID' och 'SAME' nollpolstring, för en godtycklig polstring måste du använda tf.pad () . "Giltig" stoppning betyder ingen polstring alls, där samma innebär att utgången har samma storlek på ingången. Låt oss beräkna upplösningen med padding=1
på samma exempel (märker att för vår kärna är detta "SAME" stoppning). För att göra detta lägger vi bara till vår matris med 1 noll i början / slutet: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Här kan du märka att du inte behöver beräkna om allt igen: alla element förblir desamma förutom den första / sista som är:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Så resultatet är [1, 8, 11, 7, 9, 4, 3]
vilket är detsamma som beräknats med TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Konvolution med steg
Med steg går du att hoppa över element medan du glider. I alla våra tidigare exempel glider vi ett element, nu kan du skjuta s
element i taget. Eftersom vi kommer att använda ett tidigare exempel finns det ett trick: att glida med n
element motsvarar att glida med 1 element och välja varje n-th-element.
Så om vi använder vårt tidigare exempel med padding=1
och ändrar stride
till 2, tar du bara föregående resultat [1, 8, 11, 7, 9, 4, 3]
och lämnar varje 2: e element, vilket kommer att resultera i [1, 11, 9, 3]
. Du kan göra detta i TF på följande sätt:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)