Произошла ошибка градиента при расчете двух вложений в активном режиме
Когда я попытался переписать проект dynet с tenorflow в активном режиме, произошла следующая ошибка:
tensorflow.python.framework.errors_impl.InvalidArgumentError: cannot compute ConcatV2 as input #1 was expected to be a float tensor but is a int32 tensor [Op:ConcatV2] name: concat
Я попытался определить местонахождение ошибки и упростить код, а затем обнаружил, что при вычислении двух вложений в одном динамическом графике в режиме ожидания возникнет ошибка.
Нет ошибки при добавлении двух вложений в режиме статического графа.
with tf.Graph().as_default():
emb = tf.keras.layers.Embedding(10000, 50)
emb2 = tf.keras.layers.Embedding(10000, 50)
y_ = emb(tf.constant(100)) + emb2(tf.constant(100))
y = tf.ones((1, 50))
loss = tf.reduce_sum(y - y_)
optimizer = tf.train.MomentumOptimizer(0.2,0.5).minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
sess.run(fetches=[loss, optimizer])
Но когда я запускаю следующий код в нетерпеливом режиме, произошла ошибка.
tfe.enable_eager_execution()
def loss(y):
emb = tf.keras.layers.Embedding(10000,50)
emb2 = tf.keras.layers.Embedding(10000,50)
y_ = emb(tf.constant(100)) + emb2(tf.constant(100))
return tf.reduce_sum(y - y_)
y = tf.ones((1, 50))
grads = tfe.implicit_gradients(loss)(y)
tf.train.MomentumOptimizer(0.2, 0.5).apply_gradients(grads)
Что не так с кодом в режиме ожидания, и как я могу рассчитать два встраивания в режиме ожидания?
1 ответ
Здесь происходит две вещи:
Я думаю, что это ошибка, представленная в стремлении к исполнению, я подал https://github.com/tensorflow/tensorflow/issues/18180 для этого. Я не думаю, что это существует в версии 1.6, так что, возможно, вы могли бы попробовать это в промежуточный период.
Тем не менее, я заметил, что вы определяете
Embedding
слой объекта внутри вашей функции потерь. Это означает, что каждый вызовloss
создает новыйEmbedding
что, вероятно, не то, что вы хотите. Вместо этого вы, вероятно, захотите реструктурировать свой код следующим образом:emb = tf.keras.layers.Embedding (10000,50) emb2 = tf.keras.layers.Embedding (10000,50)
def loss (y): y_ = emb (tf.constant (100)) + emb2 (tf.constant (100)) return tf.reduce_sum (y - y_)
При энергичном исполнении владение параметрами становится более "питоническим", в том смысле, что параметры, связанные с Embedding
объект (emb
а также emb2
) имеют время жизни объекта, который их создал.
Надеюсь, это поможет.