简体   繁体   中英

Loading model with custom loss in keras (missing members)

I'm new to Keras and checked many of the questions related to load model but none of them {eg eg1 eg2 } progress me to solve my issue.

sorry for the long post but I want to provide as much data to help you reproduce the error

I running code in google colab

I have a model with following custom loss functions:

def wasserstein_loss(y_true, y_pred):
    return K.mean(y_true * y_pred)


def gradient_penalty_loss(y_true, y_pred, averaged_samples, gradient_penalty_weight):
    gradients = K.gradients(y_pred, averaged_samples)[0]
    gradients_sqr = K.square(gradients)
    gradients_sqr_sum = K.sum(gradients_sqr,
                          axis=np.arange(1, len(gradients_sqr.shape)))
    gradient_l2_norm = K.sqrt(gradients_sqr_sum)
    gradient_penalty = gradient_penalty_weight * K.square(1 - 
       gradient_l2_norm)
    return K.mean(gradient_penalty)

partial_gp_loss = partial(gradient_penalty_loss,
                          averaged_samples=averaged_samples,

gradient_penalty_weight=GRADIENT_PENALTY_WEIGHT)
partial_gp_loss.__name__ = 'gradient_penalty'  # Functions need names or Keras will throw an error

using the loss functions :

discriminator_model = Model(inputs=[real_samples, generator_input_for_discriminator],
                            outputs=[discriminator_output_from_real_samples,discriminator_output_from_generator,averaged_samples_out])
discriminator_model.compile(optimizer=Adam(0.0001, beta_1=0.5, beta_2=0.9),
                            loss=[wasserstein_loss,
                                  wasserstein_loss,
                                  partial_gp_loss])

they way I saved to models :

discriminator_model.save('D_' + str(epoch) + '.h5')
generator_model.save('G_' + str(epoch) + '.h5')

the way I load the models :

  generator_model = models.load_model(Gh5files[-1],custom_objects={'wasserstein_loss': wasserstein_loss})
  discriminator_model = models.load_model(Dh5files[-1],custom_objects={'wasserstein_loss': wasserstein_loss , 
                             'RandomWeightedAverage': RandomWeightedAverage , 
                             'gradient_penalty':partial_gp_loss(gradient_penalty_loss,
                                                                averaged_samples=averaged_samples,
                                                                 gradient_penalty_weight=GRADIENT_PENALTY_WEIGHT) 
                              })

no when I try to upload saved model , I get the following error

Loading pretrained models
about to load follwoing files: ./G_31.h5 ./D_31.h5
/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py:327: UserWarning: Error in loading the saved optimizer state. As a result, your model is starting with a freshly initialized optimizer.
  warnings.warn('Error in loading the saved optimizer '
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-5ed3e08a8fce> in <module>()
     12                                                                        'gradient_penalty':partial_gp_loss(gradient_penalty_loss,
     13                                                                                                           averaged_samples=averaged_samples,
---> 14                                                                                                            gradient_penalty_weight=GRADIENT_PENALTY_WEIGHT) 
     15                                                                       })
     16 

TypeError: gradient_penalty_loss() missing 1 required positional argument: 'y_pred'

what am I missing , how can I introduce y_pred ?

Keras custom loss functions must be of the form my_loss_function(y_true, y_pred) . Your gradient_penalty_loss function is invalid since it has additional parameters.

The correct way to do this would be as follows:

def get_gradient_penalty_loss(averaged_samples, gradient_penalty_weight):

    def gradient_penalty_loss(y_true, y_pred):
        gradients = K.gradients(y_pred, averaged_samples)[0]
        gradients_sqr = K.square(gradients)
        gradients_sqr_sum = K.sum(gradients_sqr,
                              axis=np.arange(1, len(gradients_sqr.shape)))
        gradient_l2_norm = K.sqrt(gradients_sqr_sum)
        gradient_penalty = gradient_penalty_weight * K.square(1 - 
           gradient_l2_norm)
        return K.mean(gradient_penalty)

return gradient_penalty_loss

gradient_penalty_loss= get_gradient_penalty_loss(
    gradient_penalty_loss,
    averaged_samples=averaged_samples,
    gradient_penalty_weight=GRADIENT_PENALTY_WEIGHT)

and then pass models.load_model(..., custom_objects={'gradient_penalty_loss':gradient_penalty_loss})

It almost looks like you might be trying to do something like that with the partial function, but since you haven't defined it I don't know if that is the case or not.

Either way, there is a further problem in that you are calling partial_gp_loss = partial(...) which returns gradient_penalty_loss . Then, when you load the model you call partial_gp_loss(...) , but at this point you should be calling anything, you should just be passing the function!

You get the error TypeError: gradient_penalty_loss() missing 1 required positional argument: 'y_pred' because at that point you are trying to execute gradient_penalty_loss and you are passing two of its named arguments to it ( averaged_samples and gradient_penalty_weight ),in addition to passing one positional argument (which goes to y_true ) and its looking for the second positional argument, y_pred which is missing.

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