np.mean 和 tf.reduce_mean 有什么区别?

What is the difference between np.mean and tf.reduce_mean?

MNIST beginner tutorial中,有语句

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

tf.cast基本上改变了对象的张量类型,但是tf.reduce_mean and np.mean有什么区别呢?

这是 tf.reduce_mean 上的文档:

reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)

input_tensor: The tensor to reduce. Should have numeric type.

reduction_indices: The dimensions to reduce. If None (the defaut), reduces all dimensions.

# 'x' is [[1., 1. ]]
#         [2., 2.]]
tf.reduce_mean(x) ==> 1.5
tf.reduce_mean(x, 0) ==> [1.5, 1.5]
tf.reduce_mean(x, 1) ==> [1.,  2.]

对于一维矢量,它看起来像 np.mean == tf.reduce_mean,但我不明白 tf.reduce_mean(x, 1) ==> [1., 2.] 中发生了什么。 tf.reduce_mean(x, 0) ==> [1.5, 1.5] 有点道理,因为 [1, 2][1, 2] 的平均值是 [1.5, 1.5],但是 tf.reduce_mean(x, 1) 是怎么回事?

numpy.meantensorflow.reduce_mean的功能是一样的。他们做同样的事情。从文档中,对于 numpy and tensorflow,您可以看到这一点。让我们看一个例子,

c = np.array([[3.,4], [5.,6], [6.,7]])
print(np.mean(c,1))

Mean = tf.reduce_mean(c,1)
with tf.Session() as sess:
    result = sess.run(Mean)
    print(result)

输出

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

在这里你可以看到,当 axis(numpy) 或 reduction_indices(tensorflow) 为 1 时,它计算 (3,4) 和 (5,6) 和 (6, 7), 所以 1 定义了在哪个轴上计算平均值。当它为 0 时,计算跨 (3,5,6) 和 (4,6,7) 的平均值,依此类推。我希望你明白了。

现在它们之间有什么区别?

您可以在 python 上的任何地方计算 numpy 操作。但是为了进行tensorflow操作,必须在tensorflow内部完成Session。您可以阅读更多相关信息 here。因此,当您需要对张量流图(或结构,如果您愿意)执行任何计算时,它必须在张量流中完成 Session.

让我们再看一个例子。

npMean = np.mean(c)
print(npMean+1)

tfMean = tf.reduce_mean(c)
Add = tfMean + 1
with tf.Session() as sess:
    result = sess.run(Add)
    print(result)

我们可以在 numpy 中增加 1 的均值,就像你自然会做的那样,但为了在 tensorflow 中做到这一点,你需要在 Session 中执行,而不使用 Session 你不能那样做。换句话说,当您计算 tfMean = tf.reduce_mean(c) 时,tensorflow 不会计算它。它只在 Session 中计算。但是当你写 np.mean().

时,numpy 会立即计算出来

我希望它有意义。

新文档指出 tf.reduce_mean() 产生与 np.mean 相同的结果:

Equivalent to np.mean

它也有与np.mean完全相同的参数。但这里有一个重要的区别:它们产生相同的结果 仅对浮点值:

import tensorflow as tf
import numpy as np
from random import randint

num_dims = 10
rand_dim = randint(0, num_dims - 1)
c = np.random.randint(50, size=tuple([5] * num_dims)).astype(float)

with tf.Session() as sess:
    r1 = sess.run(tf.reduce_mean(c, rand_dim))
    r2 = np.mean(c, rand_dim)
    is_equal = np.array_equal(r1, r2)
    print is_equal
    if not is_equal:
        print r1
        print r2

如果删除类型转换,您会看到不同的结果


除此之外,还有许多其他 tf.reduce_ 函数,例如 reduce_allreduce_anyreduce_minreduce_maxreduce_prod 产生与 numpy 类似物的值相同。很明显,因为它们是操作,它们只能从会话内部执行。

这里的关键是reduce这个词,一个来自函数式编程的概念,它使得reduce_mean在TensorFlow中可以保持运行来自一批输入的计算结果的平均值.

如果您不熟悉函数式编程,这可能看起来很神秘。所以首先让我们看看 reduce 做了什么。如果给你一个像 [1,2,5,4] 这样的列表,并告诉你计算平均值,那很容易 - 只需将整个数组传递给 np.mean 就可以得到平均值。但是,如果您必须计算数字流的平均值怎么办?在这种情况下,您必须首先通过从流中读取 assemble 数组,然后对结果数组调用 np.mean - 您将不得不编写更多代码。

另一种方法是使用 reduce 范例。例如,看看我们如何在 python 中使用 reduce 来计算数字的总和: reduce(lambda x,y: x+y, [1,2,5,4]).

它是这样工作的:

  1. 第 1 步:从列表中读取 2 个数字 - 1,2。评估 lambda 1,2。 reduce 存储结果 3。注意 - 这是从列表中读取 2 位数字的唯一步骤
  2. 第 2 步:从列表中读取下一个数字 - 5。计算 lambda 5、3(3 是第 1 步的结果,减少存储)。 reduce 存储结果 8.
  3. 第 3 步:从列表中读取下一个数字 - 4。计算 lambda 8,4(8 是第 2 步的结果,减少存储)。 reduce 存储结果 12
  4. 第 4 步:从列表中读取下一个数字 - 有 none,所以 return 存储的结果是 12.

在此处阅读更多内容 Functional Programming in Python

要了解这如何应用于 TensorFlow,请查看以下代码块,它定义了一个简单的图形,它接受一个浮点数并计算平均值。然而,图形的输入不是单个浮点数而是一个浮点数数组。 reduce_mean 计算所有这些浮点数的平均值。

import tensorflow as tf


inp = tf.placeholder(tf.float32)
mean = tf.reduce_mean(inp)

x = [1,2,3,4,5]

with tf.Session() as sess:
    print(mean.eval(feed_dict={inp : x}))

在计算成批图像的值时,这种模式会派上用场。查看 The Deep MNIST Example,您会看到如下代码:

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))