何时以及为什么要使用tf.reduce_mean?

3

在建立模型时,我有时会看到以下代码:

# Scenario 1
# Define loss and optimizer
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=logits, labels=Y))

或者
# Scenario 2
# Evaluate model (with test logits, for dropout to be disabled)
prediction = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(prediction, tf.float32))
tf.reduce_mean的定义是“计算张量元素沿张量各个维度的平均值”。简单来说,它是用于计算张量在指定维数上的平均值。关于什么时候需要使用它,可以参考以下两种情况:#场景1和#场景2。谢谢!
2个回答

2
据我所知,tensorflow.reduce_meannumpy.mean相同。它创建了一个在底层tensorflow图中计算张量平均值的操作。 tensorflow.reduce_mean最重要的关键字参数是axis。基本上,如果你有一个形状为(4, 3, 2)的张量和axis=1,将创建一个形状为(4, 2)的空数组,并计算所选轴上的平均值以填充空数组。(这只是一个伪过程,帮助您理解输出结果,但可能不是实际过程)
以下是一个简单的示例,帮助您理解:
import tensorflow as tf
import numpy as np

one = np.linspace(1, 30, 30).reshape(5, 3, 2)

x = tf.placeholder('float32', shape=[5, 3, 2])
op_1 = tf.reduce_mean(x)
op_2 = tf.reduce_mean(x, axis=0)
op_3 = tf.reduce_mean(x, axis=1)
op_4 = tf.reduce_mean(x, axis=2)

with tf.Session() as sess:
    print(sess.run(op_1, feed_dict={x: one}))
    print(sess.run(op_2, feed_dict={x: one}))
    print(sess.run(op_3, feed_dict={x: one}))
    print(sess.run(op_4, feed_dict={x: one}))

第一个输出是一个数字,因为我们没有提供轴(axis)参数。其余输出的形状分别为(3, 2)(5, 2)(5, 3)
当目标值是矩阵时,reduce_mean非常有用。

1

用户 @meTchaikovsky 解释了 tf.reduce_mean 的一般情况。在你们两个的情况下,tf.reduce_mean 就像任何平均值计算器一样工作,即你不是沿着张量的任何特定轴取平均值,而是将张量中元素的总和除以元素数量。

让我们解码两种情况中到底发生了什么。对于这两种情况,假设 batch_size = 2num_classes = 5,意味着每个批次有两个示例。现在对于第一种情况,tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y) 返回一个形状为 (2,) 的数组。

>>import numpy as np
>>import tensorflow as tf
>>sess= tf.InteractiveSession()

>>batch_size = 2
>>num_classes = 5
>>logits = np.random.rand(batch_size,num_classes) 
>>print(logits)
[[0.94108451 0.68186329 0.04000461 0.25996487 0.50391948]
 [0.22781201 0.32305269 0.93359371 0.22599208 0.05942905]]
>>labels = np.array([[1,0,0,0,0],[0,1,0,0,0]])
>>print(labels)
[[1 0 0 0 0]
 [0 1 0 0 0]]
>>logits_ = tf.placeholder(dtype=tf.float32,shape=(batch_size,num_classes))
>>Y_ = tf.placeholder(dtype=tf.int32,shape=(batch_size,num_classes))
>>loss_op = tf.nn.softmax_cross_entropy_with_logits(logits=logits_, labels=Y_)
>>loss_per_example = sess.run(loss_op,feed_dict={Y_:labels,logits_:logits})
>>print(loss_per_example)
array([1.2028817, 1.6912657], dtype=float32)

您可以看到loss_per_example的形状为(2,)。如果我们对此变量取平均值,那么我们就可以近似计算整个批次的平均损失。因此,我们进行如下计算:

>>loss_per_example_holder = tf.placeholder(dtype=tf.float32,shape=(batch_size))
>>final_loss_per_batch = tf.reduce_mean(loss_per_example_holder)
>>final_loss = sess.run(final_loss_per_batch,feed_dict={loss_per_example_holder:loss_per_example})  
>>print(final_loss)
1.4470737

来看你的第二个情况:
>>predictions_holder = tf.placeholder(dtype=tf.float32,shape=(batch_size,num_classes))
>>labels_holder = tf.placeholder(dtype=tf.int32,shape=(batch_size,num_classes))
>>prediction_tf = tf.equal(tf.argmax(predictions_holder, 1), tf.argmax(labels_holder, 1))
>>labels_match = sess.run(prediction_tf,feed_dict={predictions_holder:logits,labels_holder:labels})
>>print(labels_match)
[ True False] 

上面的输出是预期的,因为变量logits的第一个示例仅表示具有最高激活(0.9410)的神经元是零号,与标签相同。现在我们想计算准确性,这意味着我们必须取变量labels_match的平均值。
>>labels_match_holder = tf.placeholder(dtype=tf.float32,shape=(batch_size))
>>accuracy_calc = tf.reduce_mean(tf.cast(labels_match_holder, tf.float32))
>>accuracy = sess.run(accuracy_calc, feed_dict={labels_match_holder:labels_match})
>>print(accuracy)
0.5

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