2015-12-05 39 views
16

Sto lavorando alla reimplementazione di this paper e l'operazione di chiave è un prodotto di tensione bilineare. Non so cosa significhi, ma la carta ha una bella grafica, che capisco.Prodotto tensore bilineare in TensorFlow

enter image description here

il funzionamento dei tasti è E_1 * W * E_2, e voglio sapere come implementarlo in tensorflow, perché il resto dovrebbe essere facile.

Fondamentalmente, in 3D tensore W, fetta in matrici, e per la fetta j'th (matrice), moltiplicarlo su ciascun lato E_1 e E_2, causando uno scalare, che è il jth voce nel vettore risultante (l'output di questa operazione).

Così voglio eseguire un prodotto di E_1, un d-dimensionale vettore, W, d x D x k tensore e E_2, un'altra d-dimensionale vettore. Potrebbe questo prodotto essere espresso in modo conciso in TensorFlow come lo è ora, o dovrei definire il mio op in qualche modo?

modifiche PRIMA

Perché non moltiplicare questi tensori lavoro, e c'è qualche modo per definire più esplicitamente in modo che funzioni?

>>> import tensorflow as tf 
>>> tf.InteractiveSession() 
>>> a = tf.ones([3, 3, 3]) 
>>> a.eval() 
array([[[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]], 

     [[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]], 

     [[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]]], dtype=float32) 
>>> b = tf.ones([3, 1, 1]) 
>>> b.eval() 
array([[[ 1.]], 

     [[ 1.]], 

     [[ 1.]]], dtype=float32) 
>>> 

Il messaggio di errore è

ValueError: Shapes TensorShape([Dimension(3), Dimension(3), Dimension(3)]) and TensorShape([Dimension(None), Dimension(None)]) must have the same rank 

ATTUALMENTE

scopre che moltiplicare due tensori 3D non funziona neanche con tf.matmul, così, ma tf.batch_matmul fa. tf.batch_matmul eseguirà anche tensori e matrici 3D. Poi ho provato 3D e un vettore:

ValueError: Dimensions Dimension(3) and Dimension(1) are not compatible 
+0

è possibile farlo con una semplice rimodella. – mdaoust

+0

Hai finito per implementare la carta? – Apurv

risposta

12

È possibile farlo con una semplice rimodellazione. Per la prima delle due moltiplicazioni della matrice, hai k * d, lunghezza d vettori per dotare il prodotto con.

Questo dovrebbe essere vicina:

temp = tf.matmul(E1,tf.reshape(Wddk,[d,d*k])) 
result = tf.matmul(E2,tf.reshape(temp,[d,k])) 
+3

non esiste un modo "più pulito" per farlo?Mi disturba esteticamente che dovrei fare tutte queste rimodulazioni, ma se è quello che devo fare ... Come vengono implementate le rimodifiche in tensorflow? Spostano tutti i valori intorno o è solo uno schema per leggere i valori? –

+0

Penso che probabilmente cambino semplicemente lo 'schema' aka strides, come in numpy. Questo è [super-potente] (http://scikit-image.org/docs/dev/api/skimage.util.html#view-as-windows). Accennano a questo nei documenti per [conv2d] (https://www.tensorflow.org/versions/master/api_docs/python/nn.html#conv2d). Non credo ci sia un modo più semplice per dirlo fino a [216] (https://github.com/tensorflow/tensorflow/issues/216) o [175] (https://github.com/tensorflow/tensorflow/ issues/175) sono corretti. 'einsum ('i, j, ijk', E, E, W)'! – mdaoust

+1

Risaie in TensorFlow riutilizzano gli stessi dati senza una copia. Ma TensorFlow non usa le falcate: i tensori sono sempre memorizzati in ordine di fila maggiore. – shoyer

0

È possibile eseguire un tensore rango 3 e una moltiplicazione vettore tra W e e2 che produce una matrice 2D e poi moltiplicare il risultato con e1. La seguente funzione fa uso del prodotto tensoriale e contrazione di un tensore per definire il prodotto (ad esempio W * e3)

import sympy as sp 

def tensor3_vector_product(T, v): 
    """Implements a product of a rank 3 tensor (3D array) with a 
     vector using tensor product and tensor contraction. 

    Parameters 
    ---------- 
    T: sp.Array of dimensions n x m x k 

    v: sp.Array of dimensions k x 1 

    Returns 
    ------- 
    A: sp.Array of dimensions n x m 

    """ 
    assert(T.rank() == 3) 
    # reshape v to ensure a 1D vector so that contraction do 
    # not contain x 1 dimension 
    v.reshape(v.shape[0],) 
    p = sp.tensorproduct(T, v) 
    return sp.tensorcontraction(p, (2, 3)) 

È possibile verificare questa moltiplicazione utilizzando gli esempi forniti nel ref. La suddetta funzione contrae il secondo e il terzo asse, nel tuo caso penso che dovresti contrarre (1, 2) perché W è definito come d x d x k e non k x d x d come nel mio caso.

Problemi correlati