Considérons le code ci-dessous:
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)
La sortie est:
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)
Je sais qu'il ya deux façons de limiter les gradients d'être trop grand. tf.clip_by_value
de limiter chaque dimentions, et tf.clip_by_global_norm
de limiter selon les normes mondiales de gradients.
Cependant, tf.clip_by_value
va lancer un gradient clairsemé en un dense, ce qui augmente de manière significative l'utilisation de mémoire et diminue l'efficacité de calcul, de même que l'avertissement indique, alors que le tf.clip_by_global_norm
seront pas. Même si je peux comprendre pourquoi il a été conçu, comment puis - je limiter la valeur absolut de chaque dimention d'un gradient clairsemé d'être trop grand , sans diminution de l' efficacité?
S'il vous plaît ne me dites pas simplement utiliser tf.clip_by_global_norm
je sais, cela est ok pour la plupart des cas, mais est pas ce que je veux.