Risposte:
Non esiste un .dot_product
metodo nativo . Tuttavia, un prodotto punto tra due vettori viene semplicemente sommato in base all'elemento, quindi il seguente esempio funziona:
import tensorflow as tf
# Arbitrarity, we'll use placeholders and allow batch size to vary,
# but fix vector dimensions.
# You can change this as you see fit
a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))
c = tf.reduce_sum( tf.multiply( a, b ), 1, keep_dims=True )
with tf.Session() as session:
print( c.eval(
feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
) )
L'output è:
[[ 20.]
[ 92.]]
Un'altra opzione che vale la pena provare è [tf.einsum][1]
: è essenzialmente una versione semplificata della notazione di Einstein .
Di seguito insieme agli esempi di Neil e Dumkar:
import tensorflow as tf
a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))
c = tf.einsum('ij,ij->i', a, b)
with tf.Session() as session:
print( c.eval(
feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
) )
Il primo argomento einsum
è un'equazione che rappresenta gli assi da moltiplicare e sommare. Le regole di base per un'equazione sono:
Nel nostro caso, ij,ij->i
significa che i nostri input saranno 2 matrici di forma uguale (i,j)
e il nostro output sarà un vettore di forma (i,)
.
Una volta capito, scoprirai che einsum
generalizza un numero enorme di altre operazioni:
X = [[1, 2]]
Y = [[3, 4], [5, 6]]
einsum('ab->ba', X) == [[1],[2]] # transpose
einsum('ab->a', X) == [3] # sum over last dimension
einsum('ab->', X) == 3 # sum over both dimensions
einsum('ab,bc->ac', X, Y) == [[13,16]] # matrix multiply
einsum('ab,bc->abc', X, Y) == [[[3,4],[10,12]]] # multiply and broadcast
Sfortunatamente, einsum
subisce un notevole aumento delle prestazioni rispetto a una moltiplicazione + riduzione manuale. Laddove le prestazioni sono fondamentali, consiglio vivamente di attenersi alla soluzione di Neil.
Prendere la diagonale di tf.tensordot fa anche quello che vuoi, se imposti l'asse su es
[[1], [1]]
Ho adattato l'esempio di Neil Slater:
import tensorflow as tf
# Arbitrarity, we'll use placeholders and allow batch size to vary,
# but fix vector dimensions.
# You can change this as you see fit
a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))
c = tf.diag_part(tf.tensordot( a, b, axes=[[1],[1]]))
with tf.Session() as session:
print( c.eval(
feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
) )
che ora dà anche:
[ 20. 92.]
Questo potrebbe non essere ottimale per matrici di grandi dimensioni (vedere la discussione qui )
reduce_sum
)