我偶然发现了变种自动编码器,并试图使它们使用keras在MNIST上工作。我在github上找到了一个教程。
我的问题涉及以下代码行:
# Build model
vae = Model(x, x_decoded_mean)# Calculate custom loss
xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
vae_loss = K.mean(xent_loss + kl_loss)# Compile
vae.add_loss(vae_loss)
vae.compile(optimizer='rmsprop')
为什么使用add_loss而不是将其指定为编译选项? 类似于vae.compile(optimizer='rmsprop',loss=vae_loss)
似乎不起作用,它还指出以下错误:
ValueError: The model cannot be compiled because it has no loss to optimize.
这个函数和自定义损失函数有什么区别,我可以添加它作为Model.fit()的参数吗?
编辑1
我删除了向模型添加损失的行,并使用了compile函数的loss参数。像这样:
# Build model
vae = Model(x, x_decoded_mean)
# Calculate custom loss
xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
vae_loss = K.mean(xent_loss + kl_loss)
# Compile
vae.compile(optimizer='rmsprop', loss=vae_loss)
这将引发TypeError:
TypeError: Using a 'tf.Tensor' as a Python 'bool' is not allowed. Use 'if t is not None:' instead of 'if t:' to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor.
编辑2
感谢@MarioZ,我得以找到解决方法。
# Build model
vae = Model(x, x_decoded_mean)
# Calculate custom loss in separate functiondef vae_loss(x, x_decoded_mean):
xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
vae_loss = K.mean(xent_loss + kl_loss)
return vae_loss
# Compile
vae.compile(optimizer='rmsprop', loss=vae_loss)
...
vae.fit(x_train,
x_train, # <-- did not need this previously
shuffle=True,
epochs=epochs,
batch_size=batch_size,
validation_data=(x_test, x_test)) # <-- worked with (x_test, None)
由于某些原因,我在拟合模型时必须明确指定y和y_test。最初,我不需要这样做。产生的样本对我来说似乎很合理。
尽管我可以解决这个问题,但我仍然不知道这两种方法的区别和缺点(除了需要不同的语法)。有人可以给我更多的见解吗?