2017-03-24 82 views
2

我正在尝试实现一个将产生自定义丢失函数的Lambda图层。在图层中,我需要能够将批次中的每个元素与批次中的每个其他元素进行比较,以便计算成本。理想情况下,我想代码看起来是这样的:Keras 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函数应该返回什么。它是每个样品总成本的张量,还是仅仅是该批次的总成本?

几天来,我一直在殴打我的头。任何帮助深表谢意。

+0

没关系,用Keras回调,我确定Lambda应该返回什么 - 每批一个标量。但是,我仍然无法弄清楚在训练过程中如何迭代张量。我认为这可能与切片有关... – gaw89

+0

你看过我的回答吗? – nemo

+0

对不起,周末过去了。刚接受。非常感谢! – gaw89

回答

2

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