【问题标题】:Custom loss function- Keras-自定义损失函数- Keras-
【发布时间】:2020-03-27 09:54:07
【问题描述】:

我正在尝试实现一个混合模型,其中一部分是变分自动编码器,另一部分占用潜在空间并对输入的属性进行预测。我想联合训练这两个模型。这是我的模型:

# build encoder model
inputs = Input(shape=input_shape, name='encoder_input')
x = Dense(intermediate_dim1, activation='relu')(inputs)
x1 = Dense(intermediate_dim2, activation='relu')(x)
x2 = Dense(intermediate_dim3, activation='relu')(x1)
z_mean = Dense(latent_dim, name='z_mean')(x2)
z_log_var = Dense(latent_dim, name='z_log_var')(x2)

# use reparameterization trick to push the sampling out as input
# note that "output_shape" isn't necessary with the TensorFlow backend
z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var])

# instantiate encoder model
encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder')
# build decoder model
latent_inputs = Input(shape=(latent_dim,), name='z_sampling1')
x1 = Dense(intermediate_dim3, activation='relu')(latent_inputs)
x2 = Dense(intermediate_dim2, activation='relu')(x1)
x3 = Dense(intermediate_dim1, activation='relu')(x2)
outputs = Dense(2*original_dim+1, activation='sigmoid')(x3)

# instantiate decoder model
decoder = Model(latent_inputs, outputs, name='decoder')
#build property predictor model
latent_inputs = Input(shape=(latent_dim,), name='z_sampling2')
x1 = Dense(64, activation='relu')(latent_inputs)
x2 = Dense(128, activation='relu')(x1)
outputs = Dense(property_dim, activation='sigmoid')(x2)

predModel = Model(latent_inputs, outputs, name='predictor')

这是包含编码器输入和仅预测器模型输出的完整模型。

#build full model
vaeOutputs = decoder(encoder(inputs)[2])
predOutputs = predModel(encoder(inputs)[0])
vaePred = Model(inputs, [vaeOutputs,predOutputs], name='vae_fullimage')
vaePred.summary()

现在我无法定义损失函数和训练模型:

这是我的尝试:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    help_ = "Load h5 model trained weights"
    parser.add_argument("-w", "--weights", help=help_)
    help_ = "Use mse loss instead of binary cross entropy (default)"
    parser.add_argument("-m",
                        "--mse",
                        help=help_, action='store_true')
    #args = parser.parse_args()
    args = parser.parse_known_args()[0]
    models = (encoder, decoder)
    def custom_loss(y_true, y_pred):
            kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
            kl_loss = K.sum(kl_loss, axis=-1)
            kl_loss *= -0.5

            reconstruction_loss = binary_crossentropy(y_true[0], y_pred[0])
            reconstruction_loss*= original_dim

            #y_pred = predOutputs

            prediction_loss =K.square(y_pred[1] - y_true[1])

            total_loss =  K.mean(prediction_loss, axis= -1) + K.mean (reconstruction_loss) + K.mean(kl_loss)
            return total_loss

    optimizer =  keras.optimizers.Adam(learning_rate=0.001)
    vaePred.compile(optimizer, custom_loss)
    vaePred.summary()

    if args.weights:
        vaePred.load_weights(args.weights)
    else:
        # train the autoencoder
        history =vaePred.fit(x=x_train, y=[x_train,property_train],
                epochs=epochs,
                callbacks=callbacks,
                batch_size=batch_size,
                validation_data=(x_test, [x_test,property_test]))

【问题讨论】:

  • 我定义了一个 custom_loss(y_true,y_pred) 并且只使用了 predOutputs 作为整个模型的输出。

标签: python tensorflow keras autoencoder


【解决方案1】:

您似乎正在训练一个自动编码器 (AE)(一种旨在自我预测的生成模型)。如果 AE 是完美的,它的输出应该等于输入。因此,您应该将 y_true 更改为 inputs

改变:

prediction_loss = mse(y_true, predOutputs)

成为:

prediction_loss = mse(inputs, predOutputs)

注意:我没有运行或测试过任何代码。它似乎是来自 Keras 的示例代码。

【讨论】:

  • 模型的一部分是变分自动编码器 (VAE),它必须重建输入,另一部分试图使用 VAE 的潜在空间来预测某些属性。
  • 我更新了代码。它现在运行没有错误,但它有一个跳跃的损失
  • 是的,当然……部分代码是 AE。好吧,很高兴它现在为你运行......这不是你的问题吗?习惯上对 SO 发布有一个问题……您现在已经编辑了我尝试回答的原始问题。您应该关闭/删除问题并提出您的下一个具体问题。 Jumpy loss 是调优/架构的问题……第一步是运行更长的时间或降低学习率……没有人会为你这样做。
  • 好的,谢谢。是的我明白。我想也许有人可以检测到代码有问题。它给出了非常奇怪的结果。但是,我认为我应该进行更多研究。谢谢
猜你喜欢
  • 2020-12-19
  • 2017-12-18
  • 1970-01-01
  • 2018-10-28
  • 2017-12-29
  • 1970-01-01
  • 2020-02-27
  • 2018-12-26
  • 2018-07-07
相关资源
最近更新 更多