我正在尝试实现一个可以生成自定义丢失函数的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 :(得分:3)
Keras中的张量通常至少有2个维度,即批次和神经元/单位/节点/ ...维度。因此,训练批量为64的128个单元的密集层将产生形状为(64,128)
的张量。
您的LambdaLayer
处理张量与任何其他图层一样,在您之前的密集图层之后将其插入将为您提供形状(64,128)
进行处理的张量。处理张量的工作方式类似于numpy数组上的计算(或任何其他矢量处理库):指定一个操作来广播数据结构中的所有元素。
例如,您的自定义成本是批次中每个值的差异,您可以这样实现:
cost_layer = LambdaLayer(lambda a,b: a - b)
-
操作在a
和b
上广播,如果尺寸匹配,将返回合适的结果。需要注意的是,您实际上只能为每个值指定一个操作。如果要执行更复杂的任务,例如基于值的计算,则需要执行两次操作的单个操作并相应地应用正确的操作,即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))