串联层改变损耗量

时间:2019-04-03 08:43:49

标签: keras keras-layer

我将Keras模型与连接层拟合以实现复合损失。但是,即使我只是忽略这两个合并组成部分之一,我的损失也明显高于单独使用的其余组成部分。

或者也许我的代码中有一些错误...

请问您有什么线索吗? 谢谢!

某些上下文

在我的实际设置中,我有两个输入集(X1,X2)和两个对应的标签集(Y,Z),它们流经同一模型。 该模型必须最小化(X1,Y)上的binary_crossentropy,并在Y预测上受等式约束的情况下最大化(X2,Z)上的条件熵。为此,我将两个路径X1-Y和X2-Z与连接层合并,并定义了相应的自定义损失。但是,即使我只是忽略复合损耗中的Z部分,与基本的1-input / 1-output(X1-Y)路径相比,我也得到了非常不同的损耗值。

这里有一些(简化的)代码可以重现该问题:


from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Input, Lambda, concatenate
from keras.optimizers import Adam, SGD
import keras.backend as K
import numpy as np


# Define a stupid custom loss on z-labels
def loss1(z, zhat):
    return K.sum(K.square(z-zhat), axis=-1)

# Another stupid custom loss on (y,z)-labels that just ignores y then forward to loss1
def loss2(yz, yzhat):
    z=yz[:,1]
    zhat=yzhat[:,1]
    return loss1(z, zhat)


# Toy dataset
X = np.random.rand(1000,100)
X2 = X

y = 1* X[:,0]>0.5
z = 1* X[:,1]>0.5

# Model
model = Sequential()
model.add(Dense(30, input_shape=[X.shape[1]], activation='relu'))
model.add(Dense(1, activation='sigmoid'))

# 2 inputs (X,X2) , 2 outputs (Y,Z)
inY = Input([X.shape[1]], name="X")
outY = Lambda(lambda x: x, name="Y")(model(inY))
inZ = Input([X2.shape[1]], name="X2")
outZ = Lambda(lambda x: x, name="Z")(model(inZ))

# Take a 3rd output YZ by concatenating Y and Z
full_model = Model(inputs=[inY, inZ], outputs=[outY, outZ, concatenate([outY,outZ], name='YZ'), ])

# Run model with loss1 on Z and loss2 on YZ
full_model.compile(optimizer="adam",
    loss={'Y':"binary_crossentropy", 'Z':loss1, 'YZ': loss2},
    loss_weights={'Y':1, 'Z':0, 'YZ':0})
full_model.fit([X,X2], [y,z, np.stack((y,z),axis=-1)],    batch_size=32, epochs=100,  verbose=1)


# Z_loss1 and YZ_loss2 should be equal ! ...  ??? but got
# > Z_loss: 0.2542 - YZ_loss: 8.3113
# > Z_loss: 0.2519 - YZ_loss: 8.2832
# > Z_loss: 0.2523 - YZ_loss: 8.2477
# > Z_loss: 0.2598 - YZ_loss: 8.2236
# > ...

Z_loss1和YZ_loss2应该相等

但上面的代码会产生

Z_损失:0.2542-YZ_损失:7.9963

Z_损失:0.2519-YZ_损失:7.4883

Z_损失:0.2523-YZ_损失:7.1448

Z_损失:0.2598-YZ_损失:6.9451

Z_损失:0.2583-YZ_损失:6.6104

Z_损失:0.2621-YZ_损失:6.2509

1 个答案:

答案 0 :(得分:0)

使用2D张量调用损失函数-采样x输出。然后,损失函数计算批次中每个样品的损失,并分别返回。

z=yz[:,1]-在这里,您将2D张量转换为1D,然后loss1对整个批次而不是每个样本的损失求和。

如果保留张量维数:

z=yz[:,1:]
zhat=yzhat[:,1:]

然后YZ损失与Y损失完全匹配:

Epoch 1/5
1000/1000 [==============================] - 1s 1ms/step - loss: 0.7100 - Y_loss: 0.7100 - Z_loss: 0.2617 - YZ_loss: 0.2617