Tensorflow: почему не работает расчет затрат вне графика

#python #tensorflow

#python #tensorflow

Вопрос:

У меня есть стандартный цикл эксперимента, который выглядит следующим образом:

 cross_entropy_target = tf.reduce_mean(tf.reduce_mean(tf.square(target_pred - target)))
cost = cross_entropy_target
opt_target = tf.train.AdamOptimizer(learning_rate=0.00001).minimize(cost)
for epoch in range(num_epochs):
    for mini_batch in range(num_samples / batch_size):
        mb_train_x, mb_train_target = get_mini_batch_stuffs()
        sess.run(opt_target, feed_dict={x: mb_train_x, target: mb_train_target})
  

Это выполняется и сходится к хорошей потере прогноза. Теперь тот же код с небольшой модификацией:

 cross_entropy_target = tf.reduce_mean(tf.reduce_mean(tf.square(target_pred - target)))
cross_entropy_target_variable = tf.Variable(0.0)
cost = cross_entropy_target_variable
opt_target = tf.train.AdamOptimizer(learning_rate=0.00001).minimize(cost)
for epoch in range(num_epochs):
    for mini_batch in range(num_samples / batch_size):
        mb_train_x, mb_train_target = get_mini_batch_stuffs()
        new_target_cost = sess.run(cross_entropy_target, feed_dict={x: mb_train_x, time: mb_train_time, target: mb_train_target})
        sess.run(tf.assign(cross_entropy_target_variable, new_target_cost))
        sess.run(opt_target, feed_dict={x: mb_train_x, target: mb_train_target})
  

Теперь вместо cross_entropy_target того, чтобы вычисляться как часть opt_target графика, я предварительно вычисляю его, присваиваю его переменной tensorflow и ожидаю, что она будет использовать это значение. Это вообще не работает. Выходные данные сети никогда не меняются.

Я бы ожидал, что эти два фрагмента кода будут иметь эквивалентные результаты. В обоих случаях для заполнения значений и используется прямая target target_pred передача, которая затем сводится к скалярному значению cross_entropy_target . Это скалярное значение используется для информирования о величине и направлении обновлений градиента в оптимизаторе .minimize() .

В этом игрушечном примере нет никакого преимущества в том, что я вычисляю cross_entropy_target «вне графика», а затем присваиваю его встроенному графику tf.Variable для использования в opt_target прогоне. Однако у меня есть реальный вариант использования, когда моя функция затрат очень сложна, и я не смог определить ее в терминах существующих тензорных преобразований Tensorflow. В любом случае, я хотел бы понять, почему использование a tf.Variable для стоимости оптимизатора является неправильным использованием.

Интересная странность, которая может быть побочным продуктом решения этой проблемы: если я установлю cross_entropy_target_variable = tf.Variable(0.0, trainable=False) , запуск opt_target приведет к сбою. Для этого требуется, чтобы значение затрат можно было изменять. Действительно, распечатка его значения до и после запуска opt_target приводит к разным значениям:

cross_entropy_target before = 0.345796853304
cross_entropy_target after = 0.344796866179

Почему запуск minimize() изменяет значение переменной стоимости?

Ответ №1:

В вашей tf.train.AdamOptimizer( строке он просматривает cost , что есть cross_entropy_target , что является tf.Variable операцией, и создает оптимизатор, который ничего не делает, поскольку cross_entropy_target не зависит ни от каких переменных. cross_entropy Последующее изменение цели не имеет никакого эффекта, поскольку оптимизатор уже создан.

Комментарии:

1. Имеет смысл, спасибо. Мое императивное мышление противоречит подходу tensorflow, основанному на графах. Интересно, смогу ли я достичь своей цели с помощью заполнителя, в котором я указываю стоимость затрат. В противном случае мне, возможно, придется сдаться и реализовать некоторые пользовательские операции на C , что в любом случае является правильным и эффективным способом сделать это.

2. Кстати, я создал оболочку, которая позволяет вам использовать TensorFlow в обязательном порядке — github.com/yaroslavvb/imperative

3. К сожалению, использование заполнителя для значения затрат приводит к тому же сбою, что и использование необучаемой переменной для значения затрат. Я буду работать над чтением minimize() кода, чтобы понять, почему. Ваш императивный tensorflow супер крутой, я попробую!