简体   繁体   中英

Multiply the outputs custom loss function

So my question is, if I have something like:

model = Model(inputs = input, outputs = [y1,y2])

model.compile(loss = my_loss ...) 

I have only seen my_loss as a dictionary of independent losses and, then, the final loss is defined as the sum of those. But, can I define in a multitask model a loss function that take all the predicted/true values and then I can multiply them (for instance)?

This is the loss I am trying to define:

def my_loss(y_true1, y_true2, y_pred1, y_pred2):
   final_loss = binary_crossentropy(y_true1, y_pred1) + y_true1 * categorical_crossentropy(y_true2, y_pred2)
   return final_loss

Usually, your paramaters are y_true, y_pred in the loss function, where y_pred is either y1 or y2 . But now I need both to compute the loss, so how can I define this loss function and pass all the parameters to the function: y_true1, y_true2, y_pred1, y_pred2 .

My current model that I want to change its loss:

x = Input(shape=(n, ))
shared = Dense(32)(x)
sub1 = Dense(16)(shared)
sub2 = Dense(16)(shared)
y1 = Dense(1)(sub1, activation='sigmoid')
y2 = Dense(4)(sub2, activation='softmax')

model = Model(inputs = input, outputs = [y1,y2])

model.compile(loss = ['binary_crossentropy', 'categorical_crossentropy'] ...) #THIS LINE I WANT TO CHANGE IT

Thanks!

I'm not sure if I'm understanding correctly, but I'll try.

The loss function must contain both the predicted and the actual data -- it's a way to measure the error between what your model is predicting and the true data. However, the predicted and actual data do not need to be one-dimensional. You can make y_pred a tensor that contains both y_pred1 and y_pred2 . Likewise, y_true can be a tensor that contains both y_true1 and y_true2 .

As far as I know, loss functions should return a single number. That's why loss functions often have a mean or a sum to add up all of the losses for individual data points.

Here's an example of mean square error that will work for more than 1D:

import keras.backend as K

def my_loss(y_true, y_pred):
    # this example is mean squared error
    # works if if y_pred and y_true are greater than 1D
    return K.mean(K.square(y_pred - y_true))

Here's another example of a loss function that I think is closer to your question (although I cannot comment on whether or not it's a good loss function):

def my_loss(y_true, y_pred):
    # calculate mean(abs(y_pred1*y_pred2 - y_true1*ytrue2)) 
    # this will work for 2D inputs of y_pred and y_true
    return K.mean(K.abs(K.prod(y_pred, axis = 1) - K.prod(y_true, axis = 1)))

Update:

You can concatenate two outputs into a single tensor with keras.layers.Concatenate . That way you can still have a loss function with only two arguments.

In the model you wrote above, the y1 output shape is (None, 1) and the y2 output shape is (None, 4) . Here's an example of how you could write your model so that the output is a single tensor that concatenates y1 and y1 into a shape of (None, 5) :

from keras import Model
from keras.layers import Input, Dense
from keras.layers import Concatenate

input_layer = Input(shape=(n, ))
shared = Dense(32)(input_layer)
sub1 = Dense(16)(shared)
sub2 = Dense(16)(shared)
y1 = Dense(1, activation='sigmoid')(sub1)
y2 = Dense(4, activation='softmax')(sub2)
mergedOutput = Concatenate()([y1, y2])

Below, I show an example for how you could rewrite your loss function. I wasn't sure which of the 5 columns of the output to call y_true1 vs. y_true2 , so I guessed that y_true1 was column 1 and y_true2 was the remaining 4 columns. The same column structure would apply to y_pred1 and y_pred2 .

from keras import losses

def my_loss(y_true, y_pred):
    final_loss = (losses.binary_crossentropy(y_true[:, 0], y_pred[:, 0]) + 
                    y_true[:, 0] * 
                  losses.categorical_crossentropy(y_true[:, 1:], y_pred[:,1:]))
    return final_loss

Finally, you can compile the model without any major changes from normal:

model.compile(optimizer='adam', loss=my_loss)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM