Слой Keras Lambda для пользовательских потерь

Я пытаюсь реализовать слой 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, но я не могу найти какие-либо тензорные функции, которые делают то, что я хочу.

Кроме того, мне трудно понять, что именно должна возвращать моя лямбда-функция. Является ли это тензором общей стоимости каждого образца или это просто общая стоимость партии?

Я бьюсь головой об это в течение нескольких дней. Любая помощь приветствуется.


person gaw89    schedule 24.03.2017    source источник
comment
Хорошо, используя обратные вызовы Keras, я определил, что должна возвращать лямбда — один скаляр на пакет. Однако я до сих пор не могу понять, как перебирать тензоры во время обучения. Я думаю, что это может быть связано с нарезкой...   -  person gaw89    schedule 24.03.2017
comment
Вы читали мой ответ?   -  person nemo    schedule 26.03.2017
comment
Извините, пропал на выходных. Только что принято. Большое спасибо!   -  person gaw89    schedule 27.03.2017


Ответы (1)


Тензор в Керасе обычно имеет по крайней мере 2 измерения: пакет и размер нейрона/единицы/узла/.... Таким образом, плотный слой из 128 единиц, обученный с размером пакета 64, даст тензор формы (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))
person nemo    schedule 24.03.2017