Keras 中 GAN 损失的指标名称
Metric names for the GANs loss in Keras
我正在使用 Wasserstein GAN 的改进版本,用于在将一些特征 X_{S}
与噪声向量 z
结合在一起作为输入时生成的图像。此外,我想从特定 类 生成样本。因此,在整个系统的标准训练中加入了一个分类器。我构建整个系统的代码如下:
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_acc', 'model_2_acc_1', 'model_2_acc_2', 'model_2_acc_3']
谁能帮我理解这些名字代表什么?
您有两个指标,损失和准确性,keras 从最后定义模型输出的层生成指标名称。
你的模型的输出是 outputs=[valid, fake, validity_interpolated, aux1] 所以你有四个并且都是用评论模型定义的:
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
这显示了如何将名称参数添加到图层以更改为指标指定的名称:
编辑评论:
keras 的源代码在这里:
https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/engine/training.py#L81-L2865
如下面的metrics_names函数所示,名字默认硬编码为'loss',可能是因为他们总是至少输,然后自动加上name属性:
@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
方法 return 损失的 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']
答案就在这里:
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
对于指标,由于您只定义了一个指标,系统会为每个模型的输出复制相同的指标:
'model_2_acc'
,valid
的指标
'model_2_acc_1'
,fake
的指标
'model_2_acc_2'
,validity_interpolated
的指标
'model_2_acc_3'
,aux1
的指标
为了获得更好的损失名称,您应该将名称添加到模型的输出、损失等,只要有可能添加 name
参数。
有些操作接受名称,例如:How can I set the name of my loss operation in 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')
层接受名称,因此您应该为每个模型的输出层命名,以便更好地跟踪事物。
我对新的急切模式执行概念并不完全熟悉,但您也可以尝试在调用模型时添加一个名称……不确定这是否可行。
我正在使用 Wasserstein GAN 的改进版本,用于在将一些特征 X_{S}
与噪声向量 z
结合在一起作为输入时生成的图像。此外,我想从特定 类 生成样本。因此,在整个系统的标准训练中加入了一个分类器。我构建整个系统的代码如下:
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_acc', 'model_2_acc_1', 'model_2_acc_2', 'model_2_acc_3']
谁能帮我理解这些名字代表什么?
您有两个指标,损失和准确性,keras 从最后定义模型输出的层生成指标名称。 你的模型的输出是 outputs=[valid, fake, validity_interpolated, aux1] 所以你有四个并且都是用评论模型定义的:
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
这显示了如何将名称参数添加到图层以更改为指标指定的名称:
编辑评论:
keras 的源代码在这里: https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/engine/training.py#L81-L2865
如下面的metrics_names函数所示,名字默认硬编码为'loss',可能是因为他们总是至少输,然后自动加上name属性:
@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
方法 return 损失的 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']
答案就在这里:
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
对于指标,由于您只定义了一个指标,系统会为每个模型的输出复制相同的指标:
'model_2_acc'
,valid
的指标
'model_2_acc_1'
,fake
的指标
'model_2_acc_2'
,validity_interpolated
的指标
'model_2_acc_3'
,aux1
的指标
为了获得更好的损失名称,您应该将名称添加到模型的输出、损失等,只要有可能添加 name
参数。
有些操作接受名称,例如:How can I set the name of my loss operation in 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')
层接受名称,因此您应该为每个模型的输出层命名,以便更好地跟踪事物。
我对新的急切模式执行概念并不完全熟悉,但您也可以尝试在调用模型时添加一个名称……不确定这是否可行。