Загрузка модели с нестандартной потерей в кератах (отсутствующие участники) - PullRequest
0 голосов
/ 29 декабря 2018

Я новичок в Keras и проверил многие вопросы, связанные с загрузкой модели, но ни один из них {например eg1 eg2 } не помог мне решить мою проблему.

извините за длинный пост, но я хочу предоставить как можно больше данных, чтобы помочь вам воспроизвести ошибку

Я выполняю код в google colab

У меня есть модель со следующими пользовательскими функциями потери:

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

с использованием функций потерь:

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])

их путь, который я сохранил для моделей:

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

способ загрузки моделей:

  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) 
                              })

нет, когда я пытаюсь загрузить сохраненную модель, я получаю следующую ошибку

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'

что мне не хватает, как я могу ввести y_pred?

1 Ответ

0 голосов
/ 29 декабря 2018

Пользовательские функции потерь Keras должны иметь вид my_loss_function(y_true, y_pred).Ваша функция gradient_penalty_loss недопустима, так как имеет дополнительные параметры.

Правильный способ сделать это будет следующим:

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)

и затем передать models.load_model(..., custom_objects={'gradient_penalty_loss':gradient_penalty_loss})

Похоже, вы пытаетесь сделать что-то подобное с помощью функции partial, но, поскольку вы не определили это, я не знаю, так ли это на самом деле.

В любом случае, есть еще одна проблема в том, что вы звоните partial_gp_loss = partial(...), который возвращает gradient_penalty_loss.Затем, когда вы загружаете модель, которую вы вызываете partial_gp_loss(...), но в этот момент вы должны вызывать что угодно, вы просто должны передать функцию!

Вы получаете ошибку TypeError: gradient_penalty_loss() missing 1 required positional argument: 'y_pred', потому что в этот момент выпытаясь выполнить gradient_penalty_loss, и вы передаете ему два из его именованных аргументов (averaged_samples и gradient_penalty_weight), в дополнение к передаче одного позиционного аргумента (который идет к y_true) и его поиску второго позиционного аргументаy_pred, который отсутствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...