У меня есть сверточная нейронная сеть, которую я недавно реорганизовал, чтобы использовать API-интерфейс Tensorflow Estimator, в основном следуя этот учебник. Однако во время обучения метрики, которые я добавил в EstimatorSpec, не отображаются на Tensorboard и, похоже, не оцениваются в tfdbg, несмотря на то, что область имени и метрики присутствуют на графике, написанном в Tensorboard.
Соответствующие биты для model_fn
следующие:
...
predictions = tf.placeholder(tf.float32, [num_classes], name = "predictions")
...
with tf.name_scope("metrics"):
predictions_rounded = tf.round(predictions)
accuracy = tf.metrics.accuracy(input_y, predictions_rounded, name='accuracy')
precision = tf.metrics.precision(input_y, predictions_rounded, name='precision')
recall = tf.metrics.recall(input_y, predictions_rounded, name='recall')
if mode == tf.estimator.ModeKeys.PREDICT:
spec = tf.estimator.EstimatorSpec(mode=mode,
predictions=predictions)
elif mode == tf.estimator.ModeKeys.TRAIN:
...
# if we're doing softmax vs sigmoid, we have different metrics
if cross_entropy == CrossEntropyType.SOFTMAX:
metrics = {
'accuracy': accuracy,
'precision': precision,
'recall': recall
}
elif cross_entropy == CrossEntropyType.SIGMOID:
metrics = {
'precision': precision,
'recall': recall
}
else:
raise NotImplementedError("Unrecognized cross entropy function: {}\t Available types are: SOFTMAX, SIGMOID".format(cross_entropy))
spec = tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train_op,
eval_metric_ops=metrics)
else:
raise NotImplementedError('ModeKey provided is not supported: {}'.format(mode))
return spec
У кого-нибудь есть мысли о том, почему они не пишутся? Я использую Tensorflow 1.7 и Python 3.5. Я пробовал добавлять их явно через tf.summary.scalar
, и хотя они попадают в Tensorboard таким образом, они никогда не обновляются после первого прохода по графику.
В API метрик есть изюминка, возьмем для примера tf.metrics.accuracy
(все tf.metrics.*
работают одинаково). Это возвращает 2 значения, метрику accuracy
и upate_op
, это похоже на вашу первую ошибку. У вас должно получиться что-то вроде этого:
accuracy, update_op = tf.metrics.accuracy(input_y, predictions_rounded, name='accuracy')
accuracy
- это именно то значение, которое вы ожидаете вычислить, однако обратите внимание, что вы можете захотеть вычислить точность для нескольких вызовов sess.run
, например, когда вы вычисляете точность большого набора тестов, который не умещается в памяти. Здесь на помощь приходит update_op
, он накапливает результаты, так что, когда вы запрашиваете accuracy
, он дает вам текущий счет.
update_op
не имеет зависимостей, поэтому вам нужно либо запустить его явно в sess.run
, либо добавить зависимость. Например, вы можете установить его в зависимости от функции стоимости, чтобы при вычислении функции стоимости вычислялся update_op
(в результате чего текущий счет для точности обновлялся):
with tf.control_dependencies(cost):
tf.group(update_op, other_update_ops, ...)
Вы можете сбросить значение метрики с помощью инициализатора локальной переменной:
sess.run(tf.local_variables_initializer())
Вам нужно будет повысить точность тензорной доски с помощью tf.summary.scalar(accuracy)
, как вы упомянули, что пытались (хотя, похоже, вы добавляли не то).
Ах ... в каждом уроке они либо используют стандартную оценку, либо просто делают то, что я там написал, и больше не упоминают об этом. Выполнение этого вручную с помощью tf.summary.scalar - я знал о кортежах, но я рад, что вы упомянули об этом для потомков - и управляющие зависимости работали, большое вам спасибо!