Keras均方误差丢失层

时间:2017-01-17 21:48:59

标签: python deep-learning theano keras mean-square-error

我目前正在实现自定义丢失层,在此过程中,我偶然发现了objectives.py文件[1]中均方误差的实现。我知道我在理解这种损失计算时遗漏了一些东西,因为我一直认为平均值是在每个小批量(张量轴0)的每个输出的样本中单独完成的,但看起来平均值实际上是在最后一个轴上完成,在一个向量中,意味着它在输出中完成。我在处理自定义丢失层时偶然发现了这个问题,因为它需要对特定位置的训练输出中的一些输出的丢失进行折扣。无论如何,我对均方误差的理解是不正确的?为什么Keras会使用最后一个轴,从而将1xn输出向量转换为1x1输出向量?

感谢。

[1] https://github.com/fchollet/keras/blob/master/keras/objectives.py#L7

3 个答案:

答案 0 :(得分:7)

有关MSE损失的问题是:

def mean_squared_error(y_true, y_pred):
    return K.mean(K.square(y_pred - y_true), axis=-1)

首先减去y_pred和y_true,然后将结果传递给K.square,按预期方式返回其参数的平方,然后将结果赋予K.mean,计算均值。

所以代码显然正在做它应该做的事情。关于为什么操作最后一个轴,这与类无关,它只是一个约定。请注意,通常,MSE定义中没有类。

答案 1 :(得分:3)

让我们详细说明如何在Keras中计算损失的步骤,以显示所有损失计算中的axis=-1是正确的:

  • 因此,我们会在losses.py中选择一个我们将传递给模型的compile方法的损失。

  • compile中,计算总损失。它分几步执行:The first step创建一个损失列表,每个输出一个模型。

  • 这第一步调用_weighted_masked_objective,根据文档“添加对屏蔽和样本加权的支持,添加到目标函数”
  • 基本上,_weighted_masked_objective会返回一个新的目标函数,该函数会考虑用户在使用weights方法时提供的maskfit参数。

如果我将代码剪切为仅包含对问题重要的行,我们就会得到类似的东西。

def _weighted_masked_objective(fn):
    def weighted(y_true, y_pred, weights, mask=None):
          score_array = fn(y_true, y_pred) # Compute loss as in losses.py
          return K.mean(score_array) # Average over all axis

class Model(Container):
    def compile(self, optimizer, loss, metrics=None, loss_weights=None,
                sample_weight_mode=None, weighted_metrics=None,
                target_tensors=None, **kwargs):
        weighted_losses = [_weighted_masked_objective(fn) for fn in loss_functions]

所以最后,损失确实是在每个维度上的平均值,并且使用axis=-1只是一种优雅的方法,可以在代码中的另一点启用屏蔽和加权损失

注意:我没有解释其他步骤,因为他们没有帮助回答这个问题。

答案 2 :(得分:2)

我相信,经过与同事的一些对话后,我了解了这种情况并找到了解决问题的正确方法。虽然我知道Theano正在提供懒惰评估的张量函数,这些函数在GPU上运行矩阵运算,但我没有意识到Keras的损失函数实际上是以编译的theano执行图是智能的方式编写的足以缓存某些值,以便在整个网络中正确地反向传播损失值。由于我创建的网络类型,我潜心编写自己的自定义损失函数,而没有完全理解Theano在函数计算后如何处理损失。

据我所知,我的担忧是正确的,Keras'使用最后一个轴是一个问题。在我的例子中,我有一个完全卷积的深度神经网络,损失函数的输入是(x,7,16,16),其中x是小批量的大小。通常,神经网络输出矩阵,其中第一维是小批量大小,第二维(通常是最后)维是输出向量的实际大小。因此,使用输出张量中的最后一个轴来做实际的"意味着"均方误差的一部分是不正确的。相反,轴应该是1(在基于零的索引的情况下),因为它是需要区分用于反向传播的7个实际回归输出特征。

我原本知道轴= -1可能不正确,我发布这个问题的原因是因为我无法解释原因。已经很长一段时间了,因为我不得不深入研究神经网络背后的数学,但是当我最终做到这一点时,我能够解决这些差距(我认为)。我在这里发布这个回复,以便将来可能会遇到同样的问题或者他们对Theano的张量框架理解上的差距。