np.mean 和 tf.reduce_mean 有啥区别?
Posted
技术标签:
【中文标题】np.mean 和 tf.reduce_mean 有啥区别?【英文标题】:What is the difference between np.mean and tf.reduce_mean?np.mean 和 tf.reduce_mean 有什么区别? 【发布时间】:2016-03-18 02:48:13 【问题描述】:在MNIST beginner tutorial中,有这样的说法
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
tf.cast
基本上改变了对象的张量类型,但是tf.reduce_mean
和np.mean
有什么区别呢?
这是tf.reduce_mean
上的文档:
reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)
input_tensor
: 要约简的张量。应该是数字类型。
reduction_indices
:要减小的尺寸。如果None
(默认值),则减少所有维度。# '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)
是怎么回事?
【问题讨论】:
由于python中的划分,他们产生different results on integer values 对于刚接触 tensorflow 的人来说,一个重要的区别是:tf.reduce_mean
是多线程的,通常在您的 GPU 上计算,而 np.mean
是在单个 CPU 上计算的。此外,tf
旨在处理一批数据,而np
作用于单个数据实例。
【参考方案1】:
这里的关键是reduce这个词,它是函数式编程的一个概念,它使TensorFlow中的reduce_mean
可以保持一批输入的计算结果的运行平均值。
如果您不熟悉函数式编程,这可能看起来很神秘。所以首先让我们看看reduce
做了什么。如果给你一个类似 [1,2,5,4] 的列表并被告知计算平均值,那很容易 - 只需将整个数组传递给 np.mean
即可得到平均值。但是,如果您必须计算数字流的平均值怎么办?在这种情况下,您必须首先通过从流中读取来组装数组,然后在生成的数组上调用 np.mean
- 您必须编写更多代码。
另一种方法是使用 reduce 范式。作为一个例子,看看我们如何在 python 中使用 reduce 来计算数字的总和:
reduce(lambda x,y: x+y, [1,2,5,4])
.
它是这样工作的:
-
第 1 步:从列表中读取 2 位数字 - 1,2。评估 lambda 1,2。 reduce 存储结果 3。注意 - 这是从列表中读取 2 位数字的唯一步骤
第 2 步:读取列表中的下一个数字 - 5。计算 lambda 5, 3(3 是第 1 步的结果,减少存储)。 reduce 存储结果 8。
第 3 步:读取列表中的下一个数字 - 4。计算 lambda 8,4(8 是第 2 步的结果,减少存储)。 reduce 存储结果 12
第 4 步:读取列表中的下一个数字 - 没有,因此返回存储的结果 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))
【讨论】:
【参考方案2】:numpy.mean
和 tensorflow.reduce_mean
的功能是相同的。他们做同样的事情。从文档中,对于numpy 和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) 的平均值,所以@987654331 @ 定义计算平均值的轴。当它为 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 会立即计算出来。
我希望这是有道理的。
【讨论】:
但是这里的 reduce 部分 是什么意思? @Roman 这是函数式编程的一个术语。你可以在这里阅读:python-course.eu/lambda.php @rsht REDUCE=通过将数字相加为 1 来减少数字。 MEAN=平均该总和。 @rsht 假设您有 N 个元素,并且您想要计算这 N 个数字的平均值 (M)。查看这个问题的一种方法是,我们有一个大小为 (1,N) 的向量,并且在轴 = 0 上,我们减少了元素(这里我们有 N 个元素)。归约(或聚合)带有一个功能,在我们的示例中,该功能是均值函数。【参考方案3】:新文档指出tf.reduce_mean()
产生与 np.mean 相同的结果:
等价于 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_all
、reduce_any
、reduce_min
、reduce_max
、reduce_prod
产生与 numpy 类似物相同的值。显然因为它们是操作,它们只能从会话内部执行。
【讨论】:
除了示例之外,如果您解释了区别是什么,这可能会有所帮助。通过运行您的示例,我的印象是tf.reduce_mean
确保输出 dtype
与输入 dtype
匹配。 np.mean()
的输出始终是浮点数。对吗?【参考方案4】:
1
通常指行,2
通常指列。减少“over”索引1
意味着按行减少。
[1., 2.]
只是[ <row 1 mean> , <row 2 mean> ]
。
这种索引编号约定在统计软件中很常见,尤其是 R。
【讨论】:
我相信 0 指的是列,而不是 2以上是关于np.mean 和 tf.reduce_mean 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章