我想为Keras中的双输入双输出模型创建一个自定义损失函数:
- 最大程度地减少了两个自动编码器的重建误差;
- 最大化自动编码器的瓶颈功能的相关性。
为此,我需要传递到损失功能:
- 两个输入;
- 两个输出/重建;
- 两种中间层的输出(隐藏激活)。
我知道我可以将输入和输出传递给模型,但是正在努力寻找通过隐藏激活的方法。
我可以创建两个具有中间层输出的新型号,并将其传递给损失,例如:
intermediate_layer_model1 = Model(input=input1, output=autoencoder.get_layer('encoded1').output)
intermediate_layer_model2 = Model(input=input2, output=autoencoder.get_layer('encoded2').output)
autoencoder.compile(optimizer='adadelta', loss=loss(intermediate_layer_model1, intermediate_layer_model2))
但是,我仍然需要找到一种将y_true
与正确的中间模型匹配的方法。
处理此问题的正确方法是什么?
编辑
我认为这是一种方法。简化:
# autoencoder 1
input1 = Input(shape=(input_dim,))
encoded1 = Dense(encoding_dim, activation='relu', name='encoded1')(input1)
decoded1 = Dense(input_dim, activation='sigmoid', name='decoded1')(encoded1)
# autoencoder 2
input2 = Input(shape=(input_dim,))
encoded2 = Dense(encoding_dim, activation='relu', name='encoded2')(input2)
decoded2 = Dense(input_dim, activation='sigmoid', name='decoded2')(encoded2)
# merge encodings
merge_layer = merge([encoded1, encoded2], mode='concat', name='merge', concat_axis=1)
model = Model(input=[input1, input2], output=[decoded1, decoded2, merge_layer])
model.compile(optimizer='rmsprop', loss={
'decoded1': 'binary_crossentropy',
'decoded2': 'binary_crossentropy',
'merge': correlation,
})
然后在 correlation
中我可以拆分 y_pred
并进行计算。
怎么样:
-
定义具有多个输出的单个模型(请确保正确命名编码和重建层):
duo_model = Model(input=input, output=[coding_layer, reconstruction_layer])
-
用两种不同的损失(甚至执行损失重新加权)编译模型:
duo_model.compile(optimizer='rmsprop', loss={'coding_layer': correlation_loss, 'reconstruction_layer': 'mse'})
-
以您的最终模型为A:
encoder = Model(input=input, output=[coding_layer]) autoencoder = Model(input=input, output=[reconstruction_layer])
正确编译后,这应该可以完成工作。
在定义适当的相关损耗函数时,有两种方法:
- 当编码层和输出层具有相同的维度时 - 您可以轻松地使用预先定义的
cosine_proximity
功能keras库。 - 当编码层具有不同的多态性时 - 您首先将编码向量和重建向量的嵌入到同一空间中,然后在那里计算相关性。请记住,此嵌入应该是keras层/功能或Theano/Tensor流动操作(取决于您使用的后端)。当然,您可以将嵌入和相关功能作为一个损失功能的一部分计算。