简体   繁体   English

Keras自定义损失函数,使用隐藏层输出作为目标的一部分

[英]Keras custom loss function that uses hidden layer outputs as part of the objective

I am trying to implement an autoencoder in Keras that not only minimizes the reconstruction error but its constructed features should also maximize a measure I define. 我正在尝试在Keras中实现一种自动编码器,该编码器不仅可以最大程度地减少重构错误,而且其构造功能还应该可以最大化我定义的度量。 I don't really have an idea of how to do this. 我真的不知道该怎么做。

Here's a snippet of what I have so far: 这是我到目前为止的摘要:

corrupt_data = self._corrupt(self.data, 0.1)

# define encoder-decoder network structure
# create input layer
input_layer = Input(shape=(corrupt_data.shape[1], ))
encoded = Dense(self.encoding_dim, activation = "relu")(input_layer)
decoded = Dense(self.data.shape[1], activation="sigmoid")(encoded)

# create autoencoder
dae = Model(input_layer, decoded)

# define custom multitask loss with wlm measure
def multitask_loss(y_true, y_pred):
    # extract learned features from hidden layer
    learned_fea = Model(input_layer, encoded).predict(self.data)
    # additional measure I want to optimize from an external function
    wlm_measure = wlm.measure(learned_fea, self.labels)
    cross_entropy = losses.binary_crossentropy(y_true, y_pred)
    return wlm_measure + cross_entropy

# create optimizer
dae.compile(optimizer=self.optimizer, loss=multitask_loss)

dae.fit(corrupt_data, self.data, 
                epochs=self.epochs, batch_size=20, shuffle=True, 
                callbacks=[tensorboard])

# separately create an encoder model
encoder = Model(input_layer, encoded)

Currently this does not work properly... When I viewed the training history the model seems to ignore the additional measure and train only based on the cross entropy loss. 当前,这无法正常工作...当我查看训练历史记录时,该模型似乎忽略了其他度量,仅根据交叉熵损失进行训练。 Also if I change the loss function to consider only wlm measure, I get the error "numpy.float64" object has no attribute "get_shape" (I don't know if changing my wlm function's return type to a tensor will help). 另外,如果我更改损失函数以仅考虑wlm量度,则会得到错误“ numpy.float64”对象没有属性“ get_shape”(我不知道将wlm函数的返回类型更改为张量是否有帮助)。

There are a few places that I think may have gone wrong. 我认为有些地方可能出了问题。 I don't know if I am extracting the outputs of the hidden layer correctly in my custom loss function. 我不知道我是否在自定义损失函数中正确提取隐藏层的输出。 Also I don't know if my wlm.measure function is outputting correctly—whether it should output numpy.float32 or a 1-dimensional tensor of type float32. 另外我也不知道wlm.measure函数是否正确输出-是否应输出numpy.float32或float32类型的一维张量。

Basically a conventional loss function only cares about the output layer's predicted labels and the true labels. 基本上,传统的损失函数仅关心输出层的预测标签和真实标签。 In my case, I also need to consider the hidden layer's output (activation), which is not that straightforward to implement in Keras. 就我而言,我还需要考虑隐藏层的输出(激活),这在Keras中实现起来并不那么简单。

Thanks for the help! 谢谢您的帮助!

You don't want to define your learned_fea Model inside your custom loss function. 您不想在自定义损失函数中定义您的learned_fea Model Rather, you could define a single model upfront with two outputs: the output of the decoder (the reconstruction) and the output of the endoder (the feature representation): 相反,您可以预先定义一个具有两个输出的模型:解码器的输出(重建)和endder的输出(特征表示):

multi_output_model = Model(inputs=input_layer, outputs=[decoded, encoded])

Now you can write a custom loss function that only applies to the output of the encoder: 现在,您可以编写仅适用于编码器输出的自定义损失函数:

def custom_loss(y_true, y_pred):
    return wlm.measure(y_pred, y_true)

Upon compiling the model, you pass a list of loss functions (or a dictionary if you name your tensors): 编译模型后,您传递损失函数列表(如果命名张量,则传递字典):

model.compile(loss=['binary_crossentropy', custom_loss], optimizer=...)

And fit the model by passing a list of outputs: 并通过传递输出列表来拟合模型:

model.fit(X=X, y=[data_to_be_reconstructed,labels_for_wlm_measure])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM