web-dev-qa-db-fra.com

La multiplication de tenseurs clairsemés est-elle implémentée dans TensorFlow?

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.

21
chris

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).

27
mrry

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

https://github.com/tensorflow/tensorflow/issues/1241

12
momeara

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.

1
chunyang.wen

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:

https://www.tensorflow.org/api_docs/python/tf/sparse_matmul

0
pcejrowski