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 e VALID . SAME produrrà la stessa lunghezza di input, mentre VALID 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)


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow