tf.reduce_mean 和 tf.reduce_sum, 优化目标函数时如何选择?

文章目录

  • 前言
  • tf.reduce_sum
  • tf.reduce_mean
  • 优化目标函数,如何选择

前言

熟悉 TensorFlow 的同学都知道, TensorFlow 中有两个经常用到的函数:

  • tf.reduce_mean
  • tf.reduce_sum

那么,二者有何区别?训练时目标函数应该使用哪一个?

tf.reduce_sum

我们先看函数定义:

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

主要是三个参数:

  • input_tensor:输入的张量数组
  • axis:求和的维度
  • keepdims:是否保持维度不变

其余reduction_indiceskeep_dims是为了保持和旧版本兼容,现已废弃。
从字面上理解,这是一个降维求和函数,对于给定的输入input_tensor,对其维度axis进行降维求和(不指定则默认对整个数组求和),并且返回求和后的结果张量。直接看样例:

    >>> tensor = tf.constant(np.array([[1., 2.],[3., 4.]]))
    >>> tensor.eval()
    array([[1., 2.],
            [3., 4.]])
    >>> tf.reduce_sum(tensor).eval() # 全部求和
    10.0
    >>> tf.reduce_sum(tensor, axis=0).eval() # 按列求和
    array([4., 6.])
    >>> tf.reduce_sum(tensor, axis=1).eval() # 按行求和
    array([3., 7.])
    >>> tf.reduce_sum(tensor, axis=1, keepdims=True).eval() # 按行求和同时保持维度不变
    array([[3.],
            [7.]])

tf.reduce_mean

同样看函数定义:

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

同样主要是三个参数:

  • input_tensor:输入的张量数组
  • axis:求均值的维度
  • keepdims:是否保持维度不变

其余reduction_indiceskeep_dims是为了保持和旧版本兼容,现已废弃。
类似tf.reduce_sum,只是一个是求和一个是求均值。

    >>> tensor = tf.constant(np.array([[1., 2.],[3., 4.]]))
    >>> tensor.eval()
    array([[1., 2.],
            [3., 4.]])
    >>> tf.reduce_mean(tensor).eval() # 全部求均
    2.5
    >>> tf.reduce_mean(tensor, axis=0).eval() # 按列求均
    array([2., 3.])
    >>> tf.reduce_mean(tensor, axis=1).eval() # 按行求均
    array([1.5, 3.5])
    >>> tf.reduce_mean(tensor, axis=1, keepdims=True).eval() # 按行求均同时保持维度不变
    array([[1.5],
            [3.5]])

优化目标函数,如何选择

通常,对于数据的训练,采用的都是mini-batch的方法,也就是传入的数据都是以一个batch的形式传入的,那么当我们设计目标函数的时候,对于误差应该如何传导?

L = ∑ ( . . . ) L = \sum(...) L=(...)
或者
L = 1 n ∑ ( . . . ) L = \frac{1}{n}\sum(...) L=n1(...)

对于目标函数的设计,决定了使用的是tf.reduce_sum()或者tf.reduce_mean()
假设当前训练的真实数据y_data = [1.5, 2.5, 3.6],预测结果y_pred = [1, 2, 3]
我们使用平方误差来衡量y_datay_pred之间的差异程度
对于前者:
L = ∑ ( . . . ) L = \sum(...) L=(...)

    >>> tf.reduce_sum(tf.square(y_pred - y_data)).eval() # loss
    0.86 # 0.25 + 0.25 + 0.36

对于后者:
L = 1 n ∑ ( . . . ) L = \frac{1}{n}\sum(...) L=n1(...)
loss将会是原来的1/30.86 / 3 = 0.287

对于梯度的反向传导,使用前者(求和)的梯度将会是使用后者(求均)的梯度的3倍,那么如果你的学习率较大,可能会更新过快而导致跳过了最优点;相反,使用后者的时候也可能由于梯度更新过小而陷入局部极小值点,具体情况需要根据训练模型及优化器而定。

你可能感兴趣的:(Tensorflow)