tensorflow
Utilizzo della convoluzione 1D
Ricerca…
Esempio di base
Aggiornamento: TensorFlow ora supporta la convoluzione 1D dalla versione r0.11, utilizzando tf.nn.conv1d
.
Considera un esempio di base con un input di lunghezza 10
e dimensione 16
. La dimensione del batch è 32
. Abbiamo quindi un segnaposto con forma di input [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
Creiamo quindi un filtro con larghezza 3 e prendiamo 16
canali come input e produciamo anche 16
canali.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Infine applichiamo tf.nn.conv1d
con una falcata e una spaziatura:
- falcata : intero
s
- padding : funziona come in 2D, puoi scegliere tra
SAME
eVALID
.SAME
produrrà la stessa lunghezza di input, mentreVALID
non aggiungerà padding zero.
Per il nostro esempio prendiamo un passo di 2 e un riempimento valido.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
La forma di output dovrebbe essere [batch_size, 4, 16]
.
Con padding="SAME"
, avremmo avuto una forma di output di [batch_size, 5, 16]
.
Per le versioni precedenti di TensorFlow, è possibile utilizzare solo le convoluzioni 2D mentre si imposta l'altezza degli input e i filtri su 1
.
Matematica dietro la convoluzione 1D con esempi avanzati in TF
`Per calcolare la convoluzione 1D a mano, fai scorrere il tuo kernel sull'input, calcola le moltiplicazioni elementali e sommale.
Il modo più semplice è per padding = 0, stride = 1
Quindi se il tuo input = [1, 0, 2, 3, 0, 1, 1]
e kernel = [2, 1, 3]
il risultato della convoluzione è [8, 11, 7, 9, 4]
, che è calcolato nel modo seguente:
- 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
La funzione conv1d di TF calcola le convoluzioni in batch, quindi per fare ciò in TF, dobbiamo fornire i dati nel formato corretto (doc spiega che l'input dovrebbe essere in [batch, in_width, in_channels]
, spiega anche come dovrebbe apparire il kernel piace). Così
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)
che ti darà la stessa risposta che abbiamo calcolato in precedenza: [ 8. 11. 7. 9. 4.]
Convoluzione con imbottitura
Il riempimento è solo un modo ingegnoso per dire appendere e anteporre il tuo contributo con un certo valore. Nella maggior parte dei casi questo valore è 0, ed è per questo che la maggior parte delle volte le persone lo chiamano zero padding. Supporto TF 'VALID' e 'SAME' zero padding, per un padding arbitrario devi usare tf.pad () . Il padding 'VALID' non significa nessuna padding, dove lo stesso significa che l'output avrà le stesse dimensioni dell'input. Calcoliamo la convoluzione con padding=1
sullo stesso esempio (nota che per il nostro kernel questo è il riempimento 'SAME'). Per fare questo aggiungiamo semplicemente il nostro array con 1 zero all'inizio / fine: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Qui puoi notare che non è necessario ricalcolare tutto: tutti gli elementi rimangono gli stessi eccetto il primo / ultimo che sono:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Quindi il risultato è [1, 8, 11, 7, 9, 4, 3]
che è lo stesso calcolato con TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Convoluzione con passi da gigante
Le falcate ti consentono di saltare gli elementi durante lo scorrimento. In tutti i nostri esempi precedenti abbiamo fatto scorrere 1 elemento, ora puoi scorrere gli elementi s
alla volta. Perché useremo un esempio precedente, c'è un trucco: lo scorrimento di n
elementi equivale a scorrere di 1 elemento e selezionare ogni n-esimo elemento.
Quindi, se usiamo il nostro esempio precedente con padding=1
e cambiate stride
su 2, prendete semplicemente il risultato precedente [1, 8, 11, 7, 9, 4, 3]
e lasciamo ogni elemento 2-nd, che si tradurrà in [1, 11, 9, 3]
. Puoi farlo in TF nel modo seguente:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)