Using training weights on a non-training data to design a new loss function

Issue

I would like to access the training point(s) at a training iteration and incorporate a soft constraint into my loss function by using data points not included in the training set. I will use this post as a reference.

import numpy as np
import keras.backend as K
from keras.layers import Dense, Input
from keras.models import Model

# Some random training data and labels
features = np.random.rand(100, 5)
labels = np.random.rand(100, 2)

# Simple neural net with three outputs
input_layer = Input((20,))
hidden_layer = Dense(16)(input_layer)
output_layer = Dense(3)(hidden_layer)


# Model
model = Model(inputs=input_layer, outputs=output_layer)


#each training point has another data pair. In the real example, I will have multiple 
#supporters. That is why I am using dict.

holder =  np.random.rand(100, 5)
iter = np.arange(start=1, stop=features.shape[0], step=1)
supporters = {}

for i,j in zip(iter, holder): #i represent the ith training data
    supporters[i]=j


# Write a custom loss function
def custom_loss(y_true, y_pred):
    # Normal MSE loss
    mse = K.mean(K.square(y_true-y_pred), axis=-1)
    new_constraint = .... 

       

    return(mse+new_constraint)


model.compile(loss=custom_loss, optimizer='sgd')
model.fit(features, labels, epochs=1, ,batch_size=1=1)

For simplicity, let us assume that I’d like to minimize the minimum absolute value difference between the prediction value and the prediction of the pair data stored in supporters by using the fixed network weights. Also, assume that I pass one training point at each batch. However, I could not figure out how to perform this opeartion. I’ve tried something shown below, but clearly, it is not correct.

new_constraint = K.sum(y_pred - model.fit(supporters))

Solution

Fit is the procedure of training evaluating the model. I think that it would be better for your problem to load a new instance of your model with your current weights and evaluate the batch loss in order to calculate the loss of the main model.

main_model = Model()  # This is your main training model 

def custom_loss_1(y_true, y_pred):  # Avoid recursive calls
    mse = K.mean(K.square(y_true-y_pred), axis=-1)
    return mse

def custom_loss(y_true, y_pred):
    support_model =  tf.keras.models.clone_model(main_model)  # You copy the main model but the weights are uninitialized
    support_model.build((20,)) # You build with inputs same as your support data
    support_model.compile(loss=custom_loss_1, optimizer='sgd') 
    support_model.set_weights(main_model.get_weights())  # You  load the weight of the main model

    mse = custom_loss_1(y_true, y_pred)
    # You just want to evaluate the model, not to train. If you have more
    # metrics than just loss the use support_model.evaluate(supporters)[0]
    new_constraint = K.sum(y_pred -  support_model.predict(supporters))  # predict to get the output, evaluate to get the metrics

    return(mse+new_constraint)

Answered By – Giorgos Livanos

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published