Como restringir o valor absoluto de cada dimention de um gradiente escassa de ser demasiado grande?

votos
0

Considere o código abaixo:

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)

A saída é:

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)

Eu sei que existem duas formas de restringir gradientes de ser muito grande. tf.clip_by_valuepara restringir cada dimensões, e tf.clip_by_global_normpara restringir de acordo com gradientes normas globais.

No entanto, tf.clip_by_valueserá fundido um gradiente escasso em um um denso, o que aumenta significativamente o uso de memória e diminui a eficiência de cálculo, tal como o aviso indica, enquanto tf.clip_by_global_normnão. Embora eu possa entender por que este é concebido, como posso restringir o valor absoluto de cada dimention de um gradiente escassa de ser muito grande, sem diminuir a eficiência?

Por favor, não me diga que é só usar tf.clip_by_global_norm, eu sei que isso é ok para a maioria dos casos, mas não é o que eu quero.

Publicado 02/09/2018 em 05:04
fonte usuário
Em outras línguas...                            


1 respostas

votos
0

Agora eu usar isso, ele funciona bem.

grads=[tf.IndexedSlices(tf.clip_by_value(g.values, -max_grad_value, max_grad_value), g.indices, g.dense_shape) if isinstance(g, tf.IndexedSlices) else tf.clip_by_value(g, -max_grad_value, max_grad_value) for g in grads]
Respondeu 18/10/2018 em 06:20
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more