2016-07-06 23 views
13

Ho alcuni dati rappresentati da input_x. È un tensore di dimensioni sconosciute (dovrebbe essere immesso in batch) e ogni articolo è di dimensioni n. input_x è sottoposto a tf.nn.embedding_lookout, pertanto lo embed ora ha le dimensioni dove è la dimensione di incorporamento e ? si riferisce alla dimensione del batch sconosciuto.Tensorflow - matmul della matrice di input con dati batch

Questo è descritto qui:

input_x = tf.placeholder(tf.int32, [None, n], name="input_x") 
embed = tf.nn.embedding_lookup(W, input_x) 

Ora sto cercando di moltiplicare ogni campione nei miei dati di input (che ora è una matrice embedding) da una variabile di matrice, U, e io non riesco per ottenere come farlo.

Ho provato a utilizzare tf.matmul ma dà un errore a causa della mancata corrispondenza delle forme. Ho poi provato la seguente, espandendo la dimensione di U e applicando batch_matmul (I provato anche la funzione dalla tf.nn.math_ops., il risultato era lo stesso):

U = tf.Variable(...)  
U1 = tf.expand_dims(U,0) 
h=tf.batch_matmul(embed, U1) 

Questo passa la compilazione iniziale, ma poi quando i dati effettiva è applicata, ottengo il seguente errore:

In[0].dim(0) and In[1].dim(0) must be the same: [64,58,128] vs [1,128,128]

so anche perché questo sta accadendo - ho replicato la dimensione di U ed è ora 1, ma la dimensione minibatch, 64, doesn' t in forma

Come posso eseguire la moltiplicazione della matrice sul mio input per tensostruttura in modo corretto (per dimensioni del lotto sconosciute)?

+0

Giusto per aggiungere una cosa. Dovrai aggiungere l'inizializzatore alla funzione di scansione, alla dimensione dell'output delle tue due moltiplicazioni di matrice, U * x –

+0

Attualmente [tf.matmul] (http://stackoverflow.com/a/43829731/1090562) è il diritto modo di fare moltiplicazione batch. –

risposta

10

Il matmul operation funziona solo su matrici (tensioni 2D). Ecco due approcci principali per fare ciò, entrambi suppongono che U sia un tensore 2D.

  1. Fetta embed in tensori 2D e moltiplicare ciascuna con U singolarmente. Questo è probabilmente più facile da fare utilizzando tf.scan() come questo:

    h = tf.scan(lambda a, x: tf.matmul(x, U), embed) 
    
  2. D'altra parte se l'efficienza è importante, può essere meglio per rimodellare embed di essere un tensore 2D così la moltiplicazione può essere fatto con un solo matmul come questo:

    embed = tf.reshape(embed, [-1, m]) 
    h = tf.matmul(embed, U) 
    h = tf.reshape(h, [-1, n, c]) 
    

    dove c è il numero di colonne in U. L'ultimo risagoma farà in modo che h sia un tensore 3D in cui la dimensione 0 corrisponde al lotto, proprio come l'originale x_input e embed.

+0

Grazie! Mi interessa per l'efficienza. Quanto dovrei evitare l'opzione 1, o il tensorflow (con GPU ecc.) Lo fa in modo efficiente più o meno? Sull'opzione 2, perdo un po 'della struttura della matrice in questo modo, giusto? Sono sorpreso che non ci sia supporto per questa operazione. Non è un'operazione comune? – yoki

+0

@yoki A meno che non abbia fatto un errore, i risultati dei due approcci dovrebbero essere completamente identici dopo la seconda risagoma nell'opzione 2. Ho incluso principalmente l'opzione 1 perché potrebbe essere più facile capire come e perché funziona. Non penso che quello che stai facendo sia molto comune al di fuori delle reti ricorrenti. (Che è uno degli usi principali di 'scan'.) Ho notato che esiste un'operazione [' batch_matmul'] (https://www.tensorflow.org/versions/master/api_docs/python/math_ops.html#batch_matmul) che potresti anche usare, ma dovresti creare molte copie della matrice 'U' per usarlo. – Styrke

+1

@yoki In realtà ora che ci sto pensando, la cosa che stai cercando di fare probabilmente non fa davvero la differenza. Poiché la moltiplicazione della matrice è associativa, si otterrebbe lo stesso risultato moltiplicando 'W' con' U' prima di eseguire la ricerca incorporata e quindi cercare gli embeddings in quel prodotto. Quindi, a meno che tu non stia facendo qualcosa di esotico che non conosco, l'approccio più efficace sarebbe semplicemente definire una singola matrice che rappresenta 'WU' invece di definirli entrambi e poi moltiplicarli insieme. – Styrke

4

Come risposto @Stryke, ci sono due modi per raggiungere questo: 1. Scansione e 2. Rimodellare

  1. tf.scan richiede funzioni lambda e viene generalmente utilizzato per operazioni ricorsive.Alcuni esempi per lo stesso sono qui: https://rdipietro.github.io/tensorflow-scan-examples/

  2. Personalmente preferisco rimodellare, poiché è più intuitivo. Se stai provando a matrice moltiplicare ogni matrice nel tensore 3D per la matrice che è il tensore 2D, come Cijl = Aijk * Bkl, puoi farlo con una semplice rimodellatura.

    A' = tf.reshape(Aijk,[i*j,k]) 
    C' = tf.matmul(A',Bkl) 
    C = tf.reshape(C',[i,j,l]) 
    
37

risposte precedenti sono obsoleti. Attualmente tf.matmul() tensori di supporto con rango> 2:

The inputs must be matrices (or tensors of rank > 2, representing batches of matrices), with matching inner dimensions, possibly after transposition.

anche tf.batch_matmul() è stato rimosso e tf.matmul() è il modo giusto di fare la moltiplicazione batch. L'idea principale può essere compreso dal seguente codice:

import tensorflow as tf 
batch_size, n, m, k = 10, 3, 5, 2 
A = tf.Variable(tf.random_normal(shape=(batch_size, n, m))) 
B = tf.Variable(tf.random_normal(shape=(batch_size, m, k))) 
tf.matmul(A, B) 

Ora si riceverà un tensore della forma (batch_size, n, k). Ecco cosa sta succedendo qui. Si supponga di avere batch_size di matrici nxm e batch_size di matrici mxk. Ora per ogni coppia di essi viene calcolato nxm X mxk che fornisce una matrice nxk. Avrai batch_size di loro.

noti che qualcosa di simile è valido anche:

A = tf.Variable(tf.random_normal(shape=(a, b, n, m))) 
B = tf.Variable(tf.random_normal(shape=(a, b, m, k))) 
tf.matmul(A, B) 

e vi darà una forma (a, b, n, k)

+1

Qual è il modo corretto di farlo se, come nella domanda, vuoi moltiplicare una matrice con molte altre? Devi replicare (affiancare) la matrice singola batch_sizetimes o c'è un modo migliore? – KarlSt

+1

@KarlSt Sulla base dei miei esperimenti, questo non funziona quando le prime dimensioni N-2 non corrispondono. Chiaramente, la versione numpy di questo comando supporta la trasmissione, ma penso che l'unico modo per farlo in TF sia quello di affiancare le singole dimensioni di batch_size.Ho persino provato a suonare trucchi di trasposizione (quindi sembra che la matrice sia [batch_size, n, m] e la seconda matrice è [1, m, k]), senza fortuna. Non sono sicuro che possa essere chiamato un bug, ma chiaramente, questo dovrebbe essere implementato in TF dal momento che è un'operazione così comune. – sirgogo

+0

Ho trovato un modo migliore qui: https://groups.google.com/a/tensorflow.org/forum/#!topic/discuss/4tgsOSxwtkY È possibile aggiungere le due dimensioni non utilizzate nella moltiplicazione con la risagoma, moltiplicare le due matrici, quindi richiamare nuovamente la forma per ottenere la forma desiderata. Questo è equivalente a fare moltiplicazione batch. – KarlSt