tensorflow
1D convolution gebruiken
Zoeken…
Basis voorbeeld
Update: TensorFlow ondersteunt nu 1D convolution sinds versie r0.11, met behulp van tf.nn.conv1d
.
Beschouw een eenvoudig voorbeeld met een invoer van lengte 10
en dimensie 16
. De batchgrootte is 32
. We hebben daarom een tijdelijke aanduiding met invoervorm [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
We maken vervolgens een filter met breedte 3 en we nemen 16
kanalen als invoer en voeren ook 16
kanalen uit.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Ten slotte passen we tf.nn.conv1d
met een stap en een opvulling:
- pas : geheel getal
s
- opvulling : dit werkt zoals in 2D, u kunt kiezen tussen
SAME
enVALID
.SAME
zal dezelfde inputlengte uitvoeren, terwijlVALID
geenVALID
toevoegt.
Voor ons voorbeeld nemen we een pas van 2 en een geldige opvulling.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
De uitvoervorm moet [batch_size, 4, 16]
.
Met padding="SAME"
zouden we een outputvorm hebben van [batch_size, 5, 16]
.
Voor eerdere versies van TensorFlow kunt u gewoon 2D-convoluties gebruiken terwijl u de hoogte van de ingangen en de filters instelt op 1
.
Wiskunde achter 1D-convolutie met geavanceerde voorbeelden in TF
`Om 1D convolutie met de hand te berekenen, schuif je je kernel over de invoer, bereken je de elementgewijze vermenigvuldigingen en som je ze op.
De eenvoudigste manier is om padding = 0, stride = 1
Dus als uw input = [1, 0, 2, 3, 0, 1, 1]
en kernel = [2, 1, 3]
het resultaat van de convolutie [8, 11, 7, 9, 4]
, dat is op de volgende manier berekend:
- 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
De conv1d- functie van TF berekent convoluties in batches, dus om dit in TF te doen, moeten we de gegevens in het juiste formaat leveren (doc legt uit dat invoer in [batch, in_width, in_channels]
, het legt ook uit hoe de kernel eruit moet zien Leuk vinden). Zo
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)
waarmee u hetzelfde antwoord krijgt dat we eerder hebben berekend: [ 8. 11. 7. 9. 4.]
Convolution met vulling
Opvulling is gewoon een chique manier om toe te voegen dat uw invoer iets waardevols is. In de meeste gevallen is deze waarde 0, en daarom noemen mensen het meestal zero-padding. TF ondersteunt 'VALID' en 'SAME' zero-padding, voor een willekeurige padding moet je tf.pad () gebruiken . 'GELDIGE' opvulling betekent helemaal geen opvulling, waarbij hetzelfde betekent dat de uitvoer dezelfde grootte van de invoer zal hebben. Laten we de convolutie met padding=1
volgens hetzelfde voorbeeld berekenen (merk op dat dit voor onze kernel 'SAME' padding is). Om dit te doen voegen we gewoon onze array toe met 1 nul aan het begin / einde: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Hier merk je dat je niet alles opnieuw hoeft te berekenen: alle elementen blijven hetzelfde behalve de eerste / laatste die zijn:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Het resultaat is dus [1, 8, 11, 7, 9, 4, 3]
wat hetzelfde is als berekend met TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Convolutie met passen
Met Strides kunt u elementen overslaan terwijl u schuift. In al onze voorgaande voorbeelden geschoven we 1 element, nu kun je schuiven s
elementen tegelijk. Omdat we een eerder voorbeeld zullen gebruiken, is er een truc: glijden door n
elementen komt overeen met glijden met 1 element en het selecteren van elk n-de element.
Dus als we ons vorige voorbeeld met padding=1
en de stride
wijzigen naar 2, neem je gewoon het vorige resultaat [1, 8, 11, 7, 9, 4, 3]
en laat je elk 2-de element, wat resulteert in [1, 11, 9, 3]
. U kunt dit op de volgende manier in TF doen:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)