Подтвердить что ты не робот

Тонко-плотное градиентное объяснение?

Недавно я реализовал модель, и когда я ее запустил, я получил это предупреждение:

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

С некоторыми подобными настройками параметров (встраивание мерностей) внезапно модель смехотворно медленна.

  • Что означает это предупреждение? Похоже, что что-то, что я сделал, привело к тому, что все градиенты были плотными, и поэтому backprop выполняет плотные вычисления матрицы.
  • Если это проблема с моделью, которая вызывает это, как я могу ее идентифицировать и исправить?
4b9b3361

Ответ 1

Это предупреждение печатается, когда разреженный tf.IndexedSlices объект неявно преобразуется в плотный tf.Tensor. Обычно это происходит, когда один op (обычно tf.gather()) backpropagates разреженный градиент, но тот, который его получает, не имеет специализированной функции градиента, которая может обрабатывать разреженные градиенты. В результате TensorFlow автоматически уплотняет tf.IndexedSlices, что может оказать разрушительное воздействие на производительность, если тензор большой.

Чтобы устранить эту проблему, следует попытаться убедиться, что вход params в tf.gather() (или входы params в tf.nn.embedding_lookup()) a tf.Variable. Переменные могут получать разреженные обновления напрямую, поэтому преобразование не требуется. Хотя tf.gather()tf.nn.embedding_lookup()) принимают произвольные тензоры в качестве входных данных, это может привести к более сложному графику backpropagation, что приведет к неявному преобразованию.

Ответ 2

Плотный тензор можно рассматривать как стандартный массив python. Редкую можно рассматривать как совокупность индексов и значений, например.

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

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

Итак, если вы видите, что у вас много пустых записей, разреженный массив будет намного эффективнее плотного. Но если все записи заполнены, плотность намного эффективнее. В вашем случае где-нибудь в графе тензорного потока разреженный массив преобразуется в плотный один из неопределенных размеров. Предупреждение просто говорит, что возможно, что вы можете тратить много памяти, как это. Но это может быть не проблема, если разреженный массив не слишком большой/уже довольно плотный.

Если вы хотите диагностировать его, я бы посоветовал называть ваши различные тензорные объекты, тогда он будет печатать точно, какие из них используются в этом преобразовании, и вы можете решить, что вы можете настроить, чтобы удалить его.

Ответ 3

Полностью согласен с ответом mrry.

На самом деле я отправлю еще одно решение этой проблемы.

Вы можете использовать tf.dynamic_partition() вместо tf.gather(), чтобы устранить предупреждение.

Пример кода ниже:

# 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

Надеюсь, это поможет вам.