用于自定义损失的 Keras Lambda 层

Keras Lambda Layer for Custom Loss

我正在尝试实现一个将生成自定义损失函数的 Lambda 层。在图层中,我需要能够将批次中的每个元素与批次中的每个其他元素进行比较,以便计算成本。理想情况下,我希望代码看起来像这样:

for el_1 in zip(y_pred, y_true):
    for el_2 in zip(y_pred, y_true):
        if el_1[1] == el_2[1]:
            # Perform a calculation
        else:
            # Perform a different calculation

当我真的这样做时,我得到:

TypeError: TensorType does not support iteration.

我正在使用 Keras 2.0.2 版和 Theano 0.9.0 版后端。我知道我需要使用 Keras 张量函数才能执行此操作,但我无法找出任何可以满足我要求的张量函数。

此外,我很难准确理解我的 Lambda 函数应该做什么 return。它是每个样本总成本的张量,还是只是该批次的总成本?

几天来我一直在为此苦苦思索。非常感谢任何帮助。

Keras 中的张量通常至少有 2 个维度,批处理和 neuron/unit/node/... 维度。因此,一个包含 128 个单元的密集层以 64 的批次大小训练,将产生一个形状为 (64,128).

的张量

你的 LambdaLayer 像任何其他层一样处理张量,将它插入之前的致密层之后会给你一个形状为 (64,128) 的张量来处理。处理张量的工作方式类似于 numpy 数组(或任何其他矢量处理库)的计算方式:您指定一个操作来广播数据结构中的所有元素。

例如,您的自定义成本是批次中每个值的差异,您可以这样实现它:

cost_layer = LambdaLayer(lambda a,b: a - b)

- 操作在 ab 上广播,如果维度匹配,return 将得到合适的结果。要点是您实际上只能为每个值指定一个操作。如果你想做更复杂的任务,例如基于值的计算,你需要一个单一的操作,它需要两个操作并相应地应用正确的一个,即 switch 操作。

K.switch 的语法是

K.switch(condition, then_expression, else_expression)

例如,如果您想在 a != b 时减去两个值,但在它们相等时将它们相加,您可以这样写:

import keras.backend as K
cost_layer = LambdaLayer(lambda a,b: K.switch(a != b, a - b, a + b))