Whats the correct and optimized way to use multiple loss functions with Python and Keras?
I'm playing with this article:
The author use the standard 'mse' as loss, and I wanna add some more custom functions, those functions they do not have mathematical accuracy, but are the result of observations only.
Let's say I have 5 situations:
My approach started from:
Situation 1
def fn_never_repeat(y_true, y_pred, previous_data):
# Compute the difference score between the predicted outputs and the previous data
diff = K.mean(K.square(y_pred - previous_data), axis=-1)
# Return the weighted sum of the difference scores
return diff
Situation 2
def fn_sum_values(y_true, y_pred):
# Calculate the sum of the predicted numbers
predicted_sum = K.sum(y_pred)
# Set the minimum value to 133 and maximum value to 249
X = 133
Y = 249
# Calculate the loss based on the deviation from the desired range (X, Y)
loss = K.maximum(X - predicted_sum, 0) + K.maximum(predicted_sum - Y, 0)
return loss
Situation 3 and 4 (Using 10 as example for both quadrant)
def fn_quadrant(y_true, y_pred):
count_0_to_49 = K.sum(K.cast(K.less(y_pred, 50), 'float'))
count_50_to_99 = K.sum(K.cast(K.greater_equal(y_pred, 49), 'float'))
penalty = 0
if count_0_to_49 > 10:
penalty += K.square(count_0_to_49 - 10)
if count_50_to_99 > 10:
penalty += K.square(count_50_to_99 - 10)
return K.mean(K.square(y_true - y_pred)) + penalty
Situation 5
def fn_combined_loss(y_true, y_pred):
fn_never_repeat = fn_never_repeat(y_true, y_pred, previous_data)
fn_sum_values = fn_sum_values(y_true, y_pred)
fn_quadrant = fn_quadrant(y_true, y_pred)
mse = K.mean(K.square(y_true - y_pred))
return 0.25 * fn_never_repeat + 0.25 * fn_sum_values + 0.25 * fn_quadrant + 0.25 * mse
Calling it with:
model.compile(optimizer=Adam(learning_rate=0.0001), loss='fn_combined_loss', metrics=['accuracy'], custom_objects={'fn_combined_loss': fn_combined_loss})
And error occours after:
model.fit(x=x_train, y=y_train, batch_size=number_of_batch, epochs=Nepochs, verbose=1, callbacks=[callbacks_list])
I'm stuck on this error:
ValueError: Unknown loss function: combined_loss_fn. Please ensure this object is passed to the
custom_objects
argument. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.
The paremeters from lowest times or X times something can happen or cant exceed will come from stored procedure in database. And since the value is provided based on registered results, although it is not an absolute mathematical statistic, it will be dynamically informed.
I'm not sure if functions are correctly, since it is not compiling yet, you guys can point any mistaken if you seen something wrong too.
Thanks in advice!!!
With these few changes I think your training should work
model.compile(optimizer=Adam(learning_rate=0.0001),loss=fn_combined_loss,metrics=['accuracy'])
def fn_combined_loss(y_true, y_pred): fn_never_repeat_ = fn_never_repeat(y_true, y_pred) fn_sum_values_ = fn_sum_values(y_true, y_pred) fn_quadrant_ = fn_quadrant(y_true, y_pred) mse = K.mean(K.square(y_true - y_pred)) return 0.25 * fn_never_repeat_ + 0.25 * fn_sum_values_ + 0.25 * fn_quadrant_ + 0.25 * mse
fn_quadrant
change the constants to floatdef fn_quadrant(y_true, y_pred): count_0_to_49 = K.sum(K.cast(K.less(y_pred, 50), 'float')) count_50_to_99 = K.sum(K.cast(K.greater_equal(y_pred, 49), 'float')) penalty = 0. if count_0_to_49 > 10: penalty += K.square(count_0_to_49 - 10.) if count_50_to_99 > 10: penalty += K.square(count_50_to_99 - 10.) return K.mean(K.square(y_true - y_pred)) + penalty