Рассмотрим код ниже:
import tensorflow as tf
inputs=tf.placeholder(tf.int32, [None])
labels=tf.placeholder(tf.int32, [None])
with tf.variable_scope('embedding'):
embedding=tf.get_variable('embedding', shape=[2000000, 300], dtype=tf.float32)
layer1=tf.nn.embedding_lookup(embedding, inputs)
logits=tf.layers.dense(layer1, 2000000)
loss=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits)
cost=tf.reduce_sum(loss)
optimizer=tf.train.GradientDescentOptimizer(0.01)
grads, vars=zip(*optimizer.compute_gradients(cost))
for g in grads:
print(0, g)
grads1=[tf.clip_by_value(g, -100, 100) for g in grads]
for g in grads1:
print(1, g)
grads2, _=tf.clip_by_global_norm(grads, 10)
for g in grads2:
print(2, g)
Вывод:
0 IndexedSlices(indices=Tensor("gradients/embedding_lookup_grad/Reshape_1:0", shape=(?,), dtype=int32), values=Tensor("gradients/embedding_lookup_grad/Reshape:0", shape=(?, 300), dtype=float32), dense_shape=Tensor("gradients/embedding_lookup_grad/ToInt32:0", shape=(2,), dtype=int32))
0 Tensor("gradients/dense/MatMul_grad/tuple/control_dependency_1:0", shape=(300, 2000000), dtype=float32)
0 Tensor("gradients/dense/BiasAdd_grad/tuple/control_dependency_1:0", shape=(2000000,), dtype=float32)
C:\Python\Python36\lib\site-packages\tensorflow\python\ops\gradients_impl.py:97: UserWarning: Converting sparse IndexedSlices to a dense Tensor with 600000000 elements. This may consume a large amount of memory.
num_elements)
1 Tensor("clip_by_value:0", shape=(?, 300), dtype=float32)
1 Tensor("clip_by_value_1:0", shape=(300, 2000000), dtype=float32)
1 Tensor("clip_by_value_2:0", shape=(2000000,), dtype=float32)
2 IndexedSlices(indices=Tensor("gradients/embedding_lookup_grad/Reshape_1:0", shape=(?,), dtype=int32), values=Tensor("clip_by_global_norm/clip_by_global_norm/_0:0", shape=(?, 300), dtype=float32), dense_shape=Tensor("gradients/embedding_lookup_grad/ToInt32:0", shape=(2,), dtype=int32))
2 Tensor("clip_by_global_norm/clip_by_global_norm/_1:0", shape=(300, 2000000), dtype=float32)
2 Tensor("clip_by_global_norm/clip_by_global_norm/_2:0", shape=(2000000,), dtype=float32)
Я знаю, что есть два способа ограничить слишком большие градиенты. tf.clip_by_value
для ограничения каждого размера и tf.clip_by_global_norm
для ограничения в соответствии с нормами глобальных градиентов.
Тем не менее, tf.clip_by_value
преобразует разреженный градиент в плотный, что значительно увеличивает использование памяти и снижает эффективность вычислений, как указывает предупреждение, а tf.clip_by_global_norm
- нет. Хотя я могу понять, почему это разработано, как я могу ограничить абсолютное значение каждого измерения разреженного градиента слишком большим без снижения эффективности?
Пожалуйста, не говорите мне, просто используйте tf.clip_by_global_norm
, я знаю, что это нормально для большинства случаев, но это не то, что я хочу.