TensorFlow dense gradient explication?

j'ai récemment implémenté un modèle et quand je l'ai lancé j'ai reçu cet avertissement:

UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. 
This may consume a large amount of memory.
"Converting sparse IndexedSlices to a dense Tensor of unknown shape. "

avec des paramètres similaires (dimensionnalités imbriquées) soudainement le modèle est ridiculement lent.

  1. que signifie cet avertissement? Il semble que quelque chose que j'ai fait a causé tous les gradients d'être dense et donc rétroprop fait des calculs de matrice dense
  2. S'il y a un problème avec le modèle qui cause ça, Comment puis-je l'identifier et le réparer?
46
demandé sur m-ric 2016-03-09 16:03:35

3 réponses

cet avertissement est imprimé quand un objet clairsemé tf.IndexedSlices est implicitement converti en un objet dense tf.Tensor . Cela se produit généralement lorsqu'une opération (généralement tf.gather() ) backpropagate un gradient clairsemé, mais l'op qui le reçoit n'a pas une fonction de gradient spécialisée qui peut gérer des gradients clairsemés. En conséquence, TensorFlow densifie automatiquement le tf.IndexedSlices , qui peut avoir un effet dévastateur sur les performances si le tenseur est grande.

pour corriger ce problème, vous devriez essayer de vous assurer que l'entrée params à tf.gather() (ou les entrées params à tf.nn.embedding_lookup() ) est un tf.Variable . Les Variables peuvent recevoir les mises à jour éparses directement, donc aucune conversion n'est nécessaire. Bien que tf.gather() (et tf.nn.embedding_lookup() ) accepte des tenseurs arbitraires comme entrées, cela peut conduire à une plus compliquée graphique de rétropropagation, résultant en une conversion implicite.

44
répondu mrry 2016-03-09 16:13:17

un tenseur dense peut être considéré comme un tableau standard de python. Une série d'indices et de valeurs, par exemple

# dense
array = ['a', None, None, 'c']

# sparse
array = [(0, 'a'), (3, 'c')]

Donc, comme vous pouvez le voir si vous avez beaucoup de vide entrées d'un tableau fragmenté sera beaucoup plus efficace qu'une dense. Mais si toutes les entrées sont remplies, denses est de loin plus efficace. Dans votre cas, quelque part dans le graphique de flux tensoriel, un tableau clairsemé est converti en un tableau dense de taille indéterminée. Le avertissement n'est qu'en disant: il est possible que vous pouvez perdre beaucoup de mémoire comme ça. Mais il ne pourrait pas être un problème si le tableau fragmenté n'est pas trop grand/déjà assez dense.

si vous voulez le diagnostiquer, je vous conseillerais de nommer vos divers objets tensoriels, puis il imprimera exactement ceux qui sont utilisés dans cette conversion et vous pouvez travailler sur ce que vous pourriez être en mesure de régler pour l'enlever.

16
répondu Daniel Slater 2017-05-17 15:00:21

entièrement d'accord avec la réponse de mrry .

en fait, je vais poster une autre solution pour ce problème.

vous pouvez utiliser tf.dynamic_partition() au lieu de tf.gather() pour éliminer l'avertissement.

l'exemple de code est le suivant:

# Create the cells for the RNN network
lstm = tf.nn.rnn_cell.BasicLSTMCell(128)

# Get the output and state from dynamic rnn
output, state = tf.nn.dynamic_rnn(lstm, sequence, dtype=tf.float32, sequence_length = seqlen)

# Convert output to a tessor and reshape it
outputs = tf.reshape(tf.pack(output), [-1, lstm.output_size])

# Set partions to 2
num_partitions = 2

# The partitions argument is a tensor which is already fed to a placeholder.
# It is a 1-D tensor with the length of batch_size * max_sequence_length.
# In this partitions tensor, you need to set the last output idx for each seq to 1 and 
# others remain 0, so that the result could be separated to two parts,
# one is the last outputs and the other one is the non-last outputs.
res_out = tf.dynamic_partition(outputs, partitions, num_partitions)

# prediction
preds = tf.matmul(res_out[1], weights) + bias

J'espère que cela pourrait vous aider.

7
répondu AI_ROBOT 2018-05-12 08:44:56