2015-11-20 3 views
21

Я изучаю учебник TensorFlow «MNIST For ML Beginners», и я хочу распечатать потерю обучения после каждого этапа обучения.Печать потерь во время обучения TensorFlow

Мой цикл обучения в настоящее время выглядит следующим образом:

for i in range(100): 
    batch_xs, batch_ys = mnist.train.next_batch(100) 
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 

Теперь train_step определяется как:

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 

Где cross_entropy это потеря, которую я хочу, чтобы распечатать:

cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) 

Одним из способов распечатать это будет явное вычисление cross_entropy в тренировочном цикле:

for i in range(100): 
    batch_xs, batch_ys = mnist.train.next_batch(100) 
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) 
    print 'loss = ' + str(cross_entropy) 
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 

теперь у меня есть два вопроса относительно этого:

  1. Учитывая, что cross_entropy уже вычислен в процессе sess.run(train_step, ...), кажется неэффективным вычислить его дважды, требуя в два раза больше передние проходы всех данных обучения. Есть ли способ получить доступ к значению cross_entropy, когда он был вычислен во время sess.run(train_step, ...)?

  2. Как я могу распечатать tf.Variable? Использование str(cross_entropy) дает мне ошибку ...

Спасибо!

ответ

32

Вы можете получить значение cross_entropy, добавив его в список аргументов до sess.run(...). Например, ваш for -loop можно переписать следующим образом:

for i in range(100): 
    batch_xs, batch_ys = mnist.train.next_batch(100) 
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) 
    _, loss_val = sess.run([train_step, cross_entropy], 
          feed_dict={x: batch_xs, y_: batch_ys}) 
    print 'loss = ' + loss_val 

Такой же подход может быть использован для печати текущее значение переменной. Скажем, в дополнение к стоимости cross_entropy, вы хотите, чтобы напечатать значение tf.Variable называется W, вы можете сделать следующее:

for i in range(100): 
    batch_xs, batch_ys = mnist.train.next_batch(100) 
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) 
    _, loss_val, W_val = sess.run([train_step, cross_entropy, W], 
            feed_dict={x: batch_xs, y_: batch_ys}) 
    print 'loss = %s' % loss_val 
    print 'W = %s' % W_val 
+3

Спасибо. Поэтому каждый раз, когда я вызываю 'sess.run ([train_step, cross_entropy])', он все равно только вычисляет «cross_entropy» один раз, правильно? Он не делает дополнительный проход вперед для каждой из переменных, которые я передаю? – Karnivaurus

+2

Правильно - он выполняет тот же самый подграф (поскольку «cross_entropy' уже вычисляется как часть этапа обучения) и просто добавляет дополнительный узел, чтобы вернуть значение« cross_entropy »обратно в вашу программу Python. – mrry

+0

Спасибо.Как побочный пункт, после обновления моего кода, как вы предложили, значение 'cross_entropy', в среднем, уменьшается по циклу. Однако иногда это фактически увеличивается с одной итерации обучения на другую. Это происходит для ряда ступенчатых размеров в градиентном спуске. Ожидается ли это? Разве потеря никогда не будет уменьшаться после каждой итерации, потому что вы перемещаете грузы в направлении, которое должно уменьшить эту потерю? График потери против итерации находится здесь: http://i.stack.imgur.com/f8B80.png – Karnivaurus

3

Вместо того, чтобы просто запускать training_step, запустите также узел cross_entropy, чтобы его значение было возвращено вам. Помните, что:

var_as_a_python_value = sess.run(tensorflow_variable) 

даст вам то, что вы хотите, так что вы можете сделать это:

[_, cross_entropy_py] = sess.run([train_step, cross_entropy], 
           feed_dict={x: batch_xs, y_: batch_ys}) 

обоим запустить обучение и вытащить значение перекрестной энтропии, как она была вычислена во время итерация. Обратите внимание, что я включил оба аргумента в sess.run и возвращаемые значения в список, чтобы оба произошли.

Смежные вопросы