Réponses:
Il n'y a pas de .dot_product
méthode native . Cependant, un produit scalaire entre deux vecteurs est simplement additionné par multiplication élément par élément, de sorte que l'exemple suivant fonctionne:
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]] }
) )
La sortie est:
[[ 20.]
[ 92.]]
Une autre option qui mérite d'être étudiée est [tf.einsum][1]
- c'est essentiellement une version simplifiée de la notation Einstein .
À suivre avec les exemples de Neil et 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]] }
) )
Le premier argument de einsum
est une équation représentant les axes à multiplier et à additionner. Les règles de base d'une équation sont:
Dans notre cas, cela ij,ij->i
signifie que nos entrées seront 2 matrices de forme égale (i,j)
, et notre sortie sera un vecteur de forme (i,)
.
Une fois que vous aurez compris, vous constaterez que einsum
généralisent un grand nombre d'autres opérations:
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
Malheureusement, einsum
prend un coup de performance assez lourd par rapport à une multiplication + réduction manuelle. Lorsque les performances sont critiques, je recommanderais certainement de rester avec la solution de Neil.
Prendre la diagonale de tf.tensordot fait aussi ce que vous voulez, si vous définissez par exemple
[[1], [1]]
J'ai adapté l'exemple de 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]] }
) )
qui donne désormais également:
[ 20. 92.]
Cela pourrait cependant être sous-optimal pour les grandes matrices (voir la discussion ici )
reduce_sum
)