自定义损失的Keras Lambda层

时间:2017-03-24 13:22:20

标签: keras keras-layer

我正在尝试实现一个可以生成自定义丢失函数的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函数应该返回什么。它是每个样品总成本的张量,还是仅仅是批次的总成本?

我几天来一直在反对这一点。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

Keras中的张量通常至少有2个维度,即批次和神经元/单位/节点/ ...维度。因此,训练批量为64的128个单元的密集层将产生形状为(64,128)的张量。

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

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

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

-操作在ab上广播,如果尺寸匹配,将返回合适的结果。需要注意的是,您实际上只能为每个值指定一个操作。如果要执行更复杂的任务,例如基于值的计算,则需要执行两次操作的单个操作并相应地应用正确的操作,即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))