Размер y_true в пользовательской функции потерь Keras

Я пытаюсь написать пользовательскую функцию потерь для U-net в Keras, и ее цель - вычислить не только среднеквадратичную ошибку (MSE) предсказанного изображения и истинного изображения, но также MSE их градиентов.

Я не уверен, что это нормально, но форма y_true в моей настраиваемой функции потерь (Нет, Нет, Нет, Нет), хотя из следующего link, я ожидаю, что размер y_true будет идентичен y_pred и в в моем случае он должен иметь размер: (batch_size, 128, 256, 3).

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

import tensorflow.keras.backend as K
# Encouraging the predicted image to match the label not only in image domain, but also in gradient domain
def keras_customized_loss(batch_size, lambda1 = 1.0, lambda2 = 0.05):
    def grad_x(image):
        out = K.zeros((batch_size,)+image.shape[1:4])
        out = K.abs(image[0:batch_size, 1:, :, :] - image[0:batch_size, :-1, :, :])
        return out

    def grad_y(image):
        out = K.zeros((batch_size,)+image.shape[1:4])
        out = K.abs(image[0:batch_size, :, 1:, :] - image[0:batch_size, :, :-1, :])
        return out

    #OBS: Now y_true has size: (None, None, None, None), figure out how to solve it
    def compute_loss(y_true, y_pred):
        pred_grad_x = grad_x(y_pred)
        pred_grad_y = grad_y(y_pred)
        true_grad_x = grad_x(y_true)
        true_grad_y = grad_y(y_true)
        loss1 = K.mean(K.square(y_pred-y_true)) 
        loss2 = K.mean(K.square(pred_grad_x-true_grad_x))
        loss3 = K.mean(K.square(pred_grad_y-true_grad_y))

        return (lambda1*loss1+lambda2*loss2+lambda2*loss3)

    return compute_loss

model.compile(optimizer='adam', loss = keras_customized_loss(BATCH_SIZE), metrics=['MeanAbsoluteError'])

person Gao Bo    schedule 09.03.2020    source источник


Ответы (1)


None означает, что он принимает переменные размеры.
Таким образом, ваши индивидуальные потери могут быть очень гибкими.

Реальный размер, естественно, будет размером пакета данных, который вы передаете fit.
Если ваши данные имеют форму (samples, 128,256,3), вам не о чем беспокоиться.

Но в вашем коде много ненужных вещей, вы можете просто:

def keras_customized_loss(lambda1 = 1.0, lambda2 = 0.05):
    def grad_x(image):
        return K.abs(image[:, 1:] - image[:, :-1])

    def grad_y(image):
        return K.abs(image[:, :, 1:] - image[:, :, :-1])

    def compute_loss(y_true, y_pred):
        pred_grad_x = grad_x(y_pred)
        pred_grad_y = grad_y(y_pred)
        true_grad_x = grad_x(y_true)
        true_grad_y = grad_y(y_true)
        loss1 = K.mean(K.square(y_pred-y_true)) 
        loss2 = K.mean(K.square(pred_grad_x-true_grad_x))
        loss3 = K.mean(K.square(pred_grad_y-true_grad_y))

        return (lambda1*loss1+lambda2*loss2+lambda2*loss3)

    return compute_loss
person Daniel Möller    schedule 09.03.2020
comment
Привет, Даниэль, спасибо за ответ! Я только что протестировал ваш код, и он отлично работает. - person Gao Bo; 09.03.2020
comment
Хорошо, @GaoBo :) - Если вы считаете, что это правильно отвечает на ваш вопрос, отметьте его как ответ. - person Daniel Möller; 09.03.2020