Keras: Custom loss function with training data not directly related to model

前端 未结 1 1887
旧巷少年郎
旧巷少年郎 2021-01-06 07:02

I am trying to convert my CNN written with tensorflow layers to use the keras api in tensorflow (I am using the keras api provided by TF 1.x), and am having issue writing a

1条回答
  •  执笔经年
    2021-01-06 07:43

    There is a hack I often use that is to calculate the loss within the model, by means of Lambda layers. (When the loss is independent from the true data, for instance, and the model doesn't really have an output to be compared)

    In a functional API model:

    def loss_calc(x):
        loss_input_1, loss_input_2 = x #arbirtray inputs, you choose
                                       #according to what you gave to the Lambda layer
    
        #here you use some external data that doesn't relate to the samples
        externalData = K.constant(external_numpy_data)
    
    
        #calculate the loss
        return the loss
    

    Using the outputs of the model itself (the tensor(s) that are used in your loss)

    loss = Lambda(loss_calc)([model_output_1, model_output_2])
    

    Create the model outputting the loss instead of the outputs:

    model = Model(inputs, loss)
    

    Create a dummy keras loss function for compilation:

    def dummy_loss(y_true, y_pred):
        return y_pred #where y_pred is the loss itself, the output of the model above
    
    model.compile(loss = dummy_loss, ....)
    

    Use any dummy array correctly sized regarding number of samples for training, it will be ignored:

    model.fit(your_inputs, np.zeros((number_of_samples,)), ...)
    

    Another way of doing it, is using a custom training loop.

    This is much more work, though.

    Although you're using TF1, you can still turn eager execution on at the very beginning of your code and do stuff like it's done in TF2. (tf.enable_eager_execution())

    Follow the tutorial for custom training loops: https://www.tensorflow.org/tutorials/customization/custom_training_walkthrough

    Here, you calculate the gradients yourself, of any result regarding whatever you want. This means you don't need to follow Keras standards of training.


    Finally, you can use the approach you suggested of model.add_loss. In this case, you calculate the loss exaclty the same way I did in the first answer. And pass this loss tensor to add_loss.

    You can probably compile a model with loss=None then (not sure), because you're going to use other losses, not the standard one.

    In this case, your model's output will probably be None too, and you should fit with y=None.

    0 讨论(0)
提交回复
热议问题