Metri c имена для потери GAN в Керасе - PullRequest
3 голосов
/ 04 марта 2020

Я работаю с улучшенной версией GAN Wasserstein, для сгенерированных изображений, когда в качестве входных данных даются некоторые функции X_{S}, связанные с вектором шума z. Кроме того, я хотел бы генерировать образцы из определенных c классов. Поэтому к стандартному обучению всей системы был добавлен классификатор. Мой код для построения всей системы следующий:

class WGANGP():
def __init__(self):

    self.target_mod = ".."
    self.learning_param = 0.0001
    self.no_input_feats = ...

    # Following parameter and optimizer set as recommended in paper
    self.n_critic = 15
    optimizer = RMSprop(lr=self.learning_param)

    self.img_rows = ...
    self.img_cols = ...
    self.channels = 3
    self.img_shape = (self.img_rows, self.img_cols, self.channels)
    self.latent_dim = ...

    # Build the generator and critic
    self.generator = build_generator(self.latent_dim, self.channels)
    #self.generator = self.build_generator_old()
    self.critic = build_critic(self.img_shape)

    #-------------------------------
    # Construct Computational Graph
    #       for the Critic
    #-------------------------------

    # Freeze generator's layers while training critic
    self.generator.trainable = False

    # Image input (real sample)
    real_img = Input(shape=self.img_shape)

    # Noise input
    z_disc = Input(shape=(self.latent_dim,))
    # Generate image based of noise (fake sample)
    fake_img = self.generator(z_disc)

    # Discriminator determines validity of the real and fake images
    fake, aux1 = self.critic(fake_img)
    valid, aux2 = self.critic(real_img)

    # Construct weighted average between real and fake images
    interpolated_img = RandomWeightedAverage()([real_img, fake_img])
    # Determine validity of weighted sample
    validity_interpolated, aux3 = self.critic(interpolated_img)

    # Use Python partial to provide loss function with additional
    # 'averaged_samples' argument
    partial_gp_loss = partial(self.gradient_penalty_loss,
                      averaged_samples=interpolated_img)

    partial_gp_loss.__name__ = 'gradient_penalty' 
    # Keras requires function names

    self.critic_model = Model(inputs=[real_img, z_disc],
                        outputs=[valid, fake, validity_interpolated, aux1])

    self.critic_model.compile(loss=[self.wasserstein_loss,
            self.wasserstein_loss,
            partial_gp_loss,
            'categorical_crossentropy'],
        optimizer=optimizer,
        metrics=['accuracy'],
        loss_weights=[1, 1, 5, 1])
    #-------------------------------
    # Construct Computational Graph
    #         for Generator
    #-------------------------------

    # For the generator we freeze the critic's layers
    self.critic.trainable = False
    self.generator.trainable = True

    # Sampled noise for input to generator
    z_gen = Input(shape=(self.latent_dim,))
    # Generate images based of noise
    img = self.generator(z_gen)
    # Discriminator determines validity
    valid = self.critic(img)
    # Defines generator model
    self.generator_model = Model(z_gen, valid)
    self.generator_model.compile(loss=self.wasserstein_loss, optimizer=optimizer)

Когда я печатаю critic_model.metric_names, я получаю следующее:

['loss', 'model_2_loss ',' model_2_loss ',' model_2_loss ',' model_2_loss ',' model_2_a cc ',' model_2_acc_1 ',' model_2_acc_2 ',' model_2_acc_3 ']

Может кто-нибудь помочь мне понять, что эти имена стоять за?

Ответы [ 2 ]

2 голосов
/ 09 марта 2020

Ответ прямо здесь:

self.critic_model = Model(inputs=[real_img, z_disc],
                        outputs=[valid, fake, validity_interpolated, aux1]) #<- 4 outputs

                                                              #4 model losses + 1 total loss:
self.critic_model.compile(loss=[self.wasserstein_loss,        #loss for output 0
                                self.wasserstein_loss,        #loss for output 1
                                partial_gp_loss,              #loss for output 2
                                'categorical_crossentropy']   #loss for output 3
                          optimizer=optimizer,
                          metrics=['accuracy'],           #replicated, one for each output
                          loss_weights=[1, 1, 5, 1])

Ваша модель явно имеет 4 выхода, и вы определили одну потерю на выход. Всякий раз, когда у вас есть несколько потерь, Keras будет суммировать для вас общую потерю, поэтому:

  • 'loss' - это общая потеря (сумма всех потерь для этой модели)

Остальные 4 'model_2_loss' расположены по порядку:

  • self.wasserstein_loss для первого выхода valid
  • self.wasserstein_loss, для второго выхода fake
  • partial_gp_loss, для validity_interpolated
  • 'categorical_crossentropy' для aux1

Для метрик, поскольку вы определили только одну, система реплицирует эту же Метри c для каждого из выходов модели:

  • 'model_2_acc', Метри c для valid
  • 'model_2_acc_1', Метри c для fake
  • 'model_2_acc_2', метри c для validity_interpolated
  • 'model_2_acc_3', метри c для aux1

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

Некоторые операции принимают имена, например: Как установить имя моей операции потери в Tensorflow?

Потери в более новых версиях, созданных как объекты, также принимают Имена: https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy

Модели принимают имена, такие как:

self.critic_model = Model(inputs=[real_img, z_disc],
                          outputs=[valid, fake, validity_interpolated, aux1], 
                          name='critic_model')

Слои принимают имена, поэтому у вас должно быть имя для выходного слоя каждой модели чтобы отслеживать вещи лучше.

Я не совсем знаком с новой концепцией исполнения в нетерпеливом режиме, но вы можете попытаться добавить имя также всякий раз, когда вызываете модель ... не уверен, возможно ли это.

2 голосов
/ 09 марта 2020

У вас есть две метрики: потеря и точность, керас генерирует имя метрики из слоя, где в последний раз определяются выходные данные вашей модели. Выходные данные вашей модели являются выходными данными = [valid, fake, validity_interpolated, aux1], поэтому у вас есть четыре из них, и все они определены с помощью критической модели c:

 fake, aux1 = self.critic(fake_img)
 valid, aux2 = self.critic(real_img)
 validity_interpolated, aux3 = self.critic(interpolated_img)

, поэтому все они называются name_of_the_model_name_of_the_loss - > Model_2_loss

Показывает, как добавить параметр имени в слой, чтобы изменить имя, данное метрике c: Существует ли способ переименования метрик и потерь модели Keras?

изменить комментарий:

Исходный код из keras находится здесь: https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/engine/training.py#L81 -L2865

, как показано в функции metrics_names ниже, по умолчанию первое имя жестко закодировано как «потеря», возможно потому, что оно всегда является как минимум потерей, а затем автоматически добавляется атрибут имени:

     @property
      def metrics_names(self):
        """Returns the model's display labels for all outputs."""

        # This property includes all output names including `loss` and per-output
        # losses for backward compatibility.
        metrics_names = ['loss']
        if self._is_compiled:
          # Add output loss metric names to the metric names list.
          if len(self._training_endpoints) > 1:
            metrics_names.extend([
                e.loss_name()
                for e in self._training_endpoints
                if not e.should_skip_target()
            ])

        # Add all metric names.
        metrics_names += [m.name for m in self.metrics]
        return metrics_names

Метод возвращает атрибут self.name объекта потери, а не имя переменной, которое можно использовать для их вызова

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

input_ =  keras.layers.Input(shape=(8,))
x =  keras.layers.Dense(16)(input_)
output1 = keras.layers.Dense(32)(x)
output2 = keras.layers.Dense(32, name="output2")(x)
model = keras.models.Model(inputs=input_, outputs=[output1, output2])
model.compile(loss=["mse", "mae"], optimizer="adam", metrics={"output2":"accuracy"})
print(model.metrics_names)

>>> ['loss', 'dense_3_loss', 'output2_loss', 'output2_acc']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...