在Tensorflow中添加整个训练/测试数据集准确性的摘要

5
我正在尝试使用Tensorboard来可视化我的训练过程。我的目的是,当每个epoch完成时,我想使用整个验证数据集测试网络的准确性,并将此准确性结果存储到一个summary文件中,以便在Tensorboard中进行可视化。
我知道Tensorflow有`summary_op`来实现这一点,但是似乎只能在运行代码`sess.run(summary_op)`时对一个batch进行操作。我需要计算整个数据集的准确率。怎么办?
是否有任何示例可以做到这一点?
3个回答

9

定义一个接受占位符的tf.scalar_summary

accuracy_value_ = tf.placeholder(tf.float32, shape=())
accuracy_summary = tf.scalar_summary('accuracy', accuracy_value_)

然后计算整个数据集的准确性(定义一个程序,计算数据集中每个批次的准确性并提取平均值),并将其保存到一个Python变量中,我们称之为va

一旦您获得了va的值,只需运行accuracy_summary操作,将accuracy_value_占位符作为输入:

sess.run(accuracy_summary, feed_dict={accuracy_value_: va})

1
我非常喜欢这个提出的解决方案,因为这正是我想要实现的,而不是流媒体指导我去做的。 - Tosha
我很高兴它有帮助! - nessuno
但在某些情况下,整个数据集的准确性并不精确地等于每个批次的平均准确性,例如,有1000个数据,而batch_size=128。最后一个批次的大小不是128,因此不能简单地应用平均值。 - huangbiubiu
1
@HuangYuheng 在这种情况下,您可以使用加权平均值:通过使用用于计算准确性的元素数量对每次迭代的准确性进行加权,然后除以权重之和(这将是完整数据集的长度)。 - Rohan Saxena
@nessuno,感谢您的回答,我相信它非常接近我想要的。然而,对于训练和验证,摘要值来自不同的计算路径,例如,在训练中,该值应直接为损失而不是占位符。那么,我如何使用单个节点进行摘要操作,但它可以处理两种计算方式? - C. Wang
不,如果您定义此节点接受占位符,则在想要写入它时必须向该占位符提供一个值。如果选择此选项,则首先必须执行 loss_value = sess.run(loss),然后使用 loss_value 填充占位符 accuracy_value。 - nessuno

0

我实现了一个简单的单层模型来对MNIST数据集进行分类,并在Tensorboard中可视化验证准确性,这对我很有效。

import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
import os

# number of epoch
num_epoch = 1000
model_dir = '/tmp/tf/onelayer_model/accu_info'
# mnist dataset location, change if you need
data_dir = '../data/mnist'

# load MNIST dataset without one hot
dataset = read_data_sets(data_dir, one_hot=False)

# Create placeholder for input images X and labels y
X = tf.placeholder(tf.float32, [None, 784])
# one_hot = False
y = tf.placeholder(tf.int32)

# One layer model graph
W = tf.Variable(tf.truncated_normal([784, 10], stddev=0.1))
b = tf.Variable(tf.constant(0.1, shape=[10]))
logits = tf.nn.relu(tf.matmul(X, W) + b)

init = tf.initialize_all_variables()

cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, y)
# loss function
loss = tf.reduce_mean(cross_entropy)
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

_, top_1_op = tf.nn.top_k(logits)
top_1 = tf.reshape(top_1_op, shape=[-1])
correct_classification = tf.cast(tf.equal(top_1, y), tf.float32)
# accuracy function
acc = tf.reduce_mean(correct_classification)

# define info that is used in SummaryWritter
acc_summary = tf.scalar_summary('valid_accuracy', acc)
valid_summary_op = tf.merge_summary([acc_summary])

with tf.Session() as sess:
    # initialize all the variable
    sess.run(init)

    print("Writing Summaries to %s" % model_dir)
    train_summary_writer = tf.train.SummaryWriter(model_dir, sess.graph)

    # load validation dataset
    valid_x = dataset.validation.images
    valid_y = dataset.validation.labels

    for epoch in xrange(num_epoch):
        batch_x, batch_y = dataset.train.next_batch(100)
        feed_dict = {X: batch_x, y: batch_y}
        _, acc_value, loss_value = sess.run(
            [train_op, acc, loss], feed_dict=feed_dict)
        vsummary = sess.run(valid_summary_op,
                            feed_dict={X: valid_x,
                                       y: valid_y})

        # Write validation accuracy summary
        train_summary_writer.add_summary(vsummary, epoch)

那么验证数据集必须预先加载到内存中吗? - C. Wang
如果您想在时期中评估验证准确性,那么绝对是这样。 - xiaoming-qxm
可以使用队列吗? - C. Wang
你为什么想要使用队列呢?我的意思是,如果你试图评估所有验证准确性,并且你使用队列,那么在你读取完它们之后,你必须将它们合并在一起。或者你希望在每个批次中进行评估吗? - xiaoming-qxm

0

如果您正在使用使用内部计数器的tf.metrics操作,则可以在验证集上使用批处理。以下是一个简化的示例:

model = create_model()
tf.summary.scalar('cost', model.cost_op)
acc_value_op, acc_update_op = tf.metrics.accuracy(labels,predictions)

summary_common = tf.summary.merge_all()

summary_valid = tf.summary.merge([
    tf.summary.scalar('accuracy', acc_value_op),
    # other metrics here...
])

with tf.Session() as sess:
    train_writer = tf.summary.FileWriter(logs_path + '/train',
                                         sess.graph)
    valid_writer = tf.summary.FileWriter(logs_path + '/valid')

在训练过程中,只需使用您的训练写手来撰写常见摘要。
summary = sess.run(summary_common)
train_writer.add_summary(summary, tf.train.global_step(sess, gstep_op))
train_writer.flush()

在每次验证后,使用valid-writer编写两个摘要:
gstep, summaryc, summaryv = sess.run([gstep_op, summary_common, summary_valid])
valid_writer.add_summary(summaryc, gstep)
valid_writer.add_summary(summaryv, gstep)
valid_writer.flush()

在使用tf.metrics时,不要忘记在每个验证步骤之前重置内部计数器(本地变量)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接