Keras通过自定义损耗优化两个输出

时间:2018-04-04 08:33:06

标签: python tensorflow deep-learning keras

我最近一直试图实现一个模型,可以描述如下:给定输入矩阵和一组目标,让模型同时通过自定义学习矩阵表示和目标损失函数。

架构(简化):

input_matrix = Input(shape=(i_shape,))
layer1 = Dense(100)(input_matrix)
output = Dense(3)(layer1)

autoencoder_mid = Dense(100)(input_matrix)
autoencoder_output = Dense(i_shape)(autoencoder_mid)

我对损失函数的看法:

def customLoss(true_matrix,pred_matrix):
    def combined_loss(y_true,y_pred):
        return K.abs(y_true-y_pred)
        a = K.mean( K.square(y_pred - y_true) * K.exp(-K.log(1.7) * (K.log(1. + K.exp((y_true - 3)/5 )))),axis=-1  )
        b = K.mean( K.square(pred_matrix - true_matrix) * K.exp(-K.log(1.7) * (K.log(1. + K.exp((true_matrix - 3)/5 )))),axis=-1)
        return a+b
    return combined_loss

我将模型编译为:

net = Model(input_matrix, [output,autoencoder_output])
net = net.compile(optimizer='adam', loss=customLoss(true_matrix=X,pred_matrix=autoencoder_output))

我尝试使用标准符合网络:

 net.fit(X,
         target,
         epochs=10,
         batch_size=10)

我得到的错误是:

ValueError: Tensor conversion requested dtype float32 for Tensor with dtype float64: 'Tensor("loss/dense_4_loss/Log_3:0", shape=(389, 3890), dtype=float64, device=/device:GPU:0)'

我的问题是,有没有其他方法可以做到这一点?如果是这样,请指点我寻求可能的解决方案。非常感谢你。

1 个答案:

答案 0 :(得分:2)

你可以试试这个:

def customLoss(true_matrix):
    def combined_loss(y_true,y_pred):
        y_pred, pred_matrix = y_pred
        ...
    return combined_loss

net = Model(input_matrix, [output,autoencoder_output])
net.compile(optimizer='adam', loss=customLoss(X))

因为原来的y_pred将会成为(output,autoencoder_output)

关于double return,函数只会返回第一个函数,因此我会删除两个返回行中的一个或合并两个输出,例如:

alpha = 0.5
beta = 0.5
...
loss1, loss2 = K.abs(y_true-y_pred), a+b

return alpha*loss1 + beta*loss2 

方便时更改alphabeta

因此,整个事情可能是:

def customLoss(true_matrix, alpha = 0.5, beta = 0.5):
    def combined_loss(y_true,y_pred):
        y_pred, pred_matrix = y_pred
        a = K.mean( K.square(y_pred - y_true) * K.exp(-K.log(1.7) * (K.log(1. + K.exp((y_true - 3)/5 )))),axis=-1  )
        b = K.mean( K.square(pred_matrix - true_matrix) * K.exp(-K.log(1.7) * (K.log(1. + K.exp((true_matrix - 3)/5 )))),axis=-1)
        loss1, loss2 = K.abs(y_true-y_pred), a+b
        return alpha*loss1 + beta*loss2 
    return combined_loss

net = Model(input_matrix, [output,autoencoder_output])
net.compile(optimizer='adam', loss=customLoss(X))