guide - tensorflow playground
¿Tensorflow explicación de gradiente denso? (3)
Esta advertencia se imprime cuando un objeto
tf.IndexedSlices
disperso se convierte implícitamente en un
tf.Tensor
denso.
Esto suele suceder cuando una
tf.gather()
(generalmente
tf.gather()
) propaga un gradiente disperso, pero la operación que lo recibe no tiene una función de gradiente especializada que pueda manejar gradientes dispersos.
Como resultado, TensorFlow densifica automáticamente
tf.IndexedSlices
, lo que puede tener un efecto devastador en el rendimiento si el tensor es grande.
Para solucionar este problema, debe intentar asegurarse de que la entrada de
tf.gather()
para
tf.gather()
(o las entradas de
tf.nn.embedding_lookup()
para
tf.nn.embedding_lookup()
) sea una
tf.Variable
.
Las variables pueden recibir las actualizaciones dispersas directamente, por lo que no se necesita conversión.
Aunque
tf.gather()
(y
tf.nn.embedding_lookup()
) aceptan tensores arbitrarios como entradas, esto puede conducir a un gráfico de retropropagación más complicado, lo que resulta en una conversión implícita.
Recientemente implementé un modelo y cuando lo ejecuté recibí esta advertencia:
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. "
Con algunas configuraciones de parámetros similares (incrustando dimensionalidades) de repente el modelo es ridículamente lento.
- ¿Qué implica esta advertencia? Parece que algo que he hecho ha causado que todos los gradientes sean densos, por lo que backprop está haciendo cálculos de matriz densos
- Si es que hay un problema con el modelo que está causando esto, ¿cómo puedo identificarlo y solucionarlo?
Totalmente de acuerdo con la respuesta de
mrry
.
En realidad, publicaré otra solución para este problema.
Puede usar
tf.dynamic_partition()
lugar de
tf.gather()
para eliminar la advertencia.
El código de ejemplo está debajo:
# 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
Espero que esto pueda ayudarte.
Un Tensor denso puede considerarse como una matriz de Python estándar. Uno escaso puede considerarse como una colección de índices y valores, por ejemplo
# dense
array = [''a'', None, None, ''c'']
# sparse
array = [(0, ''a''), (3, ''c'')]
Entonces, como puede ver si tiene muchas entradas vacías, una matriz dispersa será mucho más eficiente que una densa. Pero si se completan todas las entradas, denso es mucho más eficiente. En su caso, en algún lugar del gráfico de flujo de tensor, una matriz dispersa se está convirtiendo en una densa de tamaño indeterminado. La advertencia solo dice que es posible que pueda desperdiciar mucha memoria como esta. Pero podría no ser un problema en absoluto si la matriz dispersa no es demasiado grande / ya es bastante densa.
Si desea diagnosticarlo, le aconsejaría que nombrara sus diversos objetos tensoriales, luego imprimirá exactamente cuáles se están utilizando en esta conversión y podrá determinar qué podría ajustar para eliminarlo.