La multiplication des tenseurs rares avec eux-mêmes ou avec des tenseurs denses ne semble pas fonctionner dans TensorFlow. L'exemple suivant
from __future__ import print_function
import tensorflow as tf
x = tf.constant([[1.0,2.0],
[3.0,4.0]])
y = tf.SparseTensor(indices=[[0,0],[1,1]], values=[1.0,1.0], shape=[2,2])
z = tf.matmul(x,y)
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print(sess.run([x, y, z]))
échoue avec le message d'erreur
TypeError: Input 'b' of 'MatMul' Op has type string that does not match type
float32 of argument 'a'
Les deux tenseurs ont des valeurs de type float32, comme on peut le constater en les évaluant sans la multiplication op. La multiplication de y avec lui-même renvoie un message d'erreur similaire. Multipiquer x avec lui-même fonctionne bien.
La multiplication à usage général pour tf.SparseTensor
n'est actuellement pas implémentée dans TensorFlow. Cependant, il existe trois solutions partielles, et la bonne à choisir dépendra des caractéristiques de vos données:
Si vous avez un tf.SparseTensor
et un tf.Tensor
, vous pouvez utiliser tf.sparse_tensor_dense_matmul()
pour les multiplier. Ceci est plus efficace que l'approche suivante si l'un des tenseurs est trop grand pour tenir en mémoire lorsqu'il est densifié: la documentation fournit davantage d'indications sur la manière de choisir entre ces deux méthodes. Notez qu’il accepte un tf.SparseTensor
comme argument first. Pour résoudre votre problème exact, vous devrez utiliser les arguments adjoint_a
et adjoint_b
et transposer le résultat.
Si vous avez deux tenseurs rares et que vous devez les multiplier, le moyen le plus simple (sinon le plus performant) est de les convertir en dense et d'utiliser tf.matmul
:
a = tf.SparseTensor(...)
b = tf.SparseTensor(...)
c = tf.matmul(tf.sparse_tensor_to_dense(a, 0.0),
tf.sparse_tensor_to_dense(b, 0.0),
a_is_sparse=True, b_is_sparse=True)
Notez que les arguments optionnels a_is_sparse
et b_is_sparse
signifient que "a
(ou b
) a une représentation dense mais qu'un grand nombre de ses entrées sont nulles", ce qui déclenche l'utilisation d'un algorithme de multiplication différent.
Pour le cas particulier de vecteur épars par multiplication de matrice dense (potentiellement grande et fragmentée) et que les valeurs dans le vecteur sont 0 ou 1, l'opérateur tf.nn.embedding_lookup
peut être plus approprié. Ce tutoriel explique dans quels cas vous pouvez utiliser des incorporations et comment appeler l'opérateur plus en détail.
Pour le cas particulier de matrice _ épars par une matrice dense (potentiellement volumineuse et fragmentée), tf.nn.embedding_lookup_sparse()
peut convenir. Cette fonction accepte un ou deux objets tf.SparseTensor
, sp_ids
représentant les valeurs non nulles et le sp_weights
facultatif représentant leurs valeurs (leur valeur par défaut étant égale à un).
Récemment, on a ajouté tf.sparse_tensor_dense_matmul(...)
qui permet de multiplier une matrice creuse par une matrice dense.
http://www.tensorflow.org/versions/r0.9/api_docs/python/sparse_ops.html#sparse_tensor_dense_matmul
Il paraît que
tf.sparse_matmul(
a,
b,
transpose_a=None,
transpose_b=None,
a_is_sparse=None,
b_is_sparse=None,
name=None
)
n'est pas pour la multiplication de deux SparseTensors
.
a
et b
sont Tensors
pas SparseTensors
. Et j'ai essayé ça, ça ne marche pas avec SparseTensors
.
Pour rendre la réponse plus complète:
tf.sparse_matmul(
a,
b,
transpose_a=None,
transpose_b=None,
a_is_sparse=None,
b_is_sparse=None,
name=None
)
existe aussi: