详解TensorFlow的 tf.reduce_mean 函数:对张量进行求平均操作

  • Post category:Python

tf.reduce_mean 函数是 TensorFlow 中用于求平均值的函数,可以作用在各种类型的 Tensor 上,包括多维数组。该函数可以沿着指定的轴在 Tensor 上求平均值,或计算整个 Tensor 所有元素的平均值,具体使用方法如下:

函数签名

tf.reduce_mean(
    input_tensor,
    axis=None,
    keepdims=None,
    name=None,
    reduction_indices=None,
    keep_dims=None
)

参数解释

  • input_tensor: 待求平均值的 Tensor。
  • axis: (可选参数) 沿着哪个轴求平均值。默认为 None,即所有元素。
  • keepdims: (可选参数) 是否保留原来的维度。如果为 True,则在平均值的维度上插入一个大小为 1 的维度。如果为 False,则去掉原来的维度。默认为 None,即不保留原来的维度。
  • name: (可选参数) 操作的名字。
  • reduction_indices: (已经被弃用) 等同于 axis 参数。
  • keep_dims: (已经被弃用) 等同于 keepdims 参数。

在下面的代码块中,我们将演示 tf.reduce_mean 函数的使用:

import tensorflow as tf

# 求一维数组的平均值
a = tf.constant([1, 2, 3, 4, 5], dtype=tf.float32)
a_mean = tf.reduce_mean(a)
print('a_mean:', a_mean.numpy())
# 输出:3.0

# 求矩阵的总体平均值
b = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32)
b_mean = tf.reduce_mean(b)
print('b_mean:', b_mean.numpy())
# 输出:3.5

# 沿着特定的维度求平均值
c = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32)
c_mean_axis0 = tf.reduce_mean(c, axis=0)
c_mean_axis1 = tf.reduce_mean(c, axis=1)
print('c_mean_axis0:', c_mean_axis0.numpy())
# 输出:[2.5 3.5 4.5]
print('c_mean_axis1:', c_mean_axis1.numpy())
# 输出:[2. 5.]

在以上的代码中,我们首先创建了一个一维数组和一个二维数组。然后分别演示了 tf.reduce_mean 的基本用法和沿着特定的维度求平均值的用法。其中,第一次调用时,未指定任何轴,则对整个数组求平均值;第二次调用时,对整个二维数组求平均值;第三次调用时,分别沿着两个轴求平均值。

接下来提供两个更具体的例子:

例子 1:计算 softmax 交叉熵损失函数

在神经网络中,使用 softmax 交叉熵损失函数计算分类问题的损失值。该损失函数的定义如下:

$$ L = – \frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{C} y_i^{(j)} \ln \hat{y}_i^{(j)} $$

其中,$N$ 是数据样本数量;$C$ 是类别数量;$y_i$ 是数据样本 $i$ 的标签向量,用 one-hot 编码表示;$\hat{y}_i$ 是数据样本 $i$ 的预测值向量,经过 softmax 函数后表示各类别的概率分布。

在 TensorFlow 中,可以使用 tf.reduce_mean 函数来实现该损失函数的计算:

import tensorflow as tf

logits = tf.constant([[1., 2., 3.], [4., 5., 6.]], dtype=tf.float32)
labels = tf.constant([[0, 1, 0], [1, 0, 0]], dtype=tf.float32)

softmax = tf.nn.softmax(logits, axis=1)
loss = -tf.reduce_mean(labels * tf.math.log(softmax))
print('loss:', loss.numpy())
# 输出:1.1601251

在以上代码中,我们首先创建了一个形状为 $(2, 3)$ 的张量,表示数据样本的预测值 logits;并创建了一个形状为 $(2, 3)$ 的张量,表示数据样本的标签 labels,使用 one-hot 编码表示。然后,我们使用 tf.nn.softmax 函数对 logits 进行 softmax 变换,得到概率分布;最后,根据上述公式,使用 tf.reduce_mean 函数对所有数据样本的交叉熵损失求平均值。

例子 2:使用样本加权的方式计算平均值

在某些情况下,需要计算加权平均值。例如,在深度学习模型的训练过程中,某些数据的重要性可能会高于其他数据,因此需要使用该数据的权重作为平均值的权重,而不是均分权重。使用 tf.reduce_mean 函数可以轻松实现这一目标,只需用权重乘以每个数据元素,然后将加权后的元素相加即可:

import tensorflow as tf

a = tf.constant([1, 2, 3], dtype=tf.float32)
w = tf.constant([0.1, 0.3, 0.6], dtype=tf.float32)

weighted_mean = tf.reduce_mean(a * w)
print('weighted_mean:', weighted_mean.numpy())
# 输出:2.5

在以上代码中,我们首先创建了一个形状为 $(3,)$ 的一维数组 a,和一个形状为 $(3,)$ 的一维数组 w,表示每个数据元素的权重。然后,将数组 a 与权重数组 w 逐元素相乘,得到加权后的数组,使用 tf.reduce_mean 函数计算加权平均值。最终结果为 2.5,即 $1 \times 0.1 + 2 \times 0.3 + 3 \times 0.6$。