#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 супер крутой, я попробую!