ljklonepiece
ljklonepiece

Reputation: 211

Keras Implementation of Customized Loss Function that need internal layer output as label

in keras, I want to customize my loss function which not only takes (y_true, y_pred) as input but also need to use the output from the internal layer of the network as the label for an output layer.This picture shows the Network Layout

Here, the internal output is xn, which is a 1D feature vector. in the upper right corner, the output is xn', which is the prediction of xn. In other words, xn is the label for xn'.

While [Ax, Ay] is traditionally known as y_true, and [Ax',Ay'] is y_pred.

I want to combine these two loss components into one and train the network jointly.

Any ideas or thoughts are much appreciated!

Upvotes: 9

Views: 6519

Answers (3)

Khurram Sultan
Khurram Sultan

Reputation: 1

I have my reservations regarding this implementation. The loss computed at the merged layer is propagated back to both the merged branches. Generally you would like to propagate it through just one layer.

Upvotes: 0

ljklonepiece
ljklonepiece

Reputation: 211

I have figured out a way out, in case anyone is searching for the same, I posted here (based on the network given in this post):

The idea is to define the customized loss function and use it as the output of the network. (Notation: A is the true label of variable A, and A' is the predicted value of variable A)

def customized_loss(args):
    #A is from the training data
    #S is the internal state
    A, A', S, S' = args 
    #customize your own loss components
    loss1 = K.mean(K.square(A - A'), axis=-1)
    loss2 = K.mean(K.square(S - S'), axis=-1)
    #adjust the weight between loss components
    return 0.5 * loss1 + 0.5 * loss2

 def model():
     #define other inputs
     A = Input(...) # define input A
     #construct your model 
     cnn_model = Sequential()
     ...
     # get true internal state
     S = cnn_model(prev_layer_output0)
     # get predicted internal state output
     S' = Dense(...)(prev_layer_output1)
     # get predicted A output
     A' = Dense(...)(prev_layer_output2)
     # customized loss function
     loss_out = Lambda(customized_loss, output_shape=(1,), name='joint_loss')([A, A', S, S'])
     model = Model(input=[...], output=[loss_out])
     return model

  def train():
      m = model()
      opt = 'adam'
      model.compile(loss={'joint_loss': lambda y_true, y_pred:y_pred}, optimizer = opt)
      # train the model 
      ....

Upvotes: 12

Dr. Snoopy
Dr. Snoopy

Reputation: 56377

First of all you should be using the Functional API. Then you should define the network output as the output plus the result from the internal layer, merge them into a single output (by concatenating), and then make a custom loss function that then splits the merged output into two parts and does the loss computations on its own.

Something like:

def customLoss(y_true, y_pred):
    #loss here
    internalLayer = Convolution2D()(inputs) #or other layers
    internalModel = Model(input=inputs, output=internalLayer)
    tmpOut = Dense(...)(internalModel)
    mergedOut = merge([tmpOut, mergedOut], mode = "concat", axis = -1)
    fullModel = Model(input=inputs, output=mergedOut)

    fullModel.compile(loss = customLoss, optimizer = "whatever")

Upvotes: 0

Related Questions