0

我正在尝试使用功能 API中描述的每个输出中的不同损失函数来实现多输出回归问题。对于每个输出,我尝试使用与每个输出对应的自定义损失函数(分位数)。但是,该模型似乎没有适当地应用不同的损失函数,并且仅针对其中一个评估每个输出(它恰好是列表中的最后一个)。

quantiles = [0.05,0.5,0.95]

input_layer = keras.Input(shape=(inputs_norm.shape[1]), name="input")
hidden_layer_1 = layers.Dense(units=100,name='hidden_1',activation='tanh',kernel_regularizer=regularizers.l2(0.05))(input_layer)

output_layers = []
losses = {}

def quantile_loss(q,y,f): #Custom quantile loss function with parameter q
    e = (y-f)
    return K.mean(K.maximum(q*e, (q-1)*e), axis=-1)

for q in quantiles:
    name = 'q{:0.2f}'.format(q) #Name to give each layer/loss function
    output_layers.append(layers.Dense(1,name=name)(hidden_layer_1)) #Add output layers for each quantile
    losses[name] = lambda y,f:quantile_loss(q,y,f) #Specify loss function for each output layer

model = keras.Model(inputs=input_layer,outputs=output_layers)
model.compile(optimizer='Adam',loss=losses)

model.fit(x=X_train,y=y_train,verbose=1,epochs=20,batch_size=8)

在训练期间,模型快速收敛到每个输出的值。在测试样本上评估模型会为每个输出层产生相同的损失:

sample_x = X_test[0:24,:]
sample_y = y_test[0:24] * targets.std() + targets.mean()

print(model.evaluate(sample_x,sample_y))

1/1 [==============================] - 0s 12ms/step - loss: 42.3914 - q0.05_loss: 14.1223 - q0.50_loss: 14.1212 - q0.95_loss: 14.1231
[42.39143753051758, 14.122288703918457, 14.121197700500488, 14.123051643371582]

但正如我所料,单独循环遍历每个损失函数会产生不同的损失值。

preds = model.predict(sample_x)
test_losses = []

for i in range(0,len(quantiles)):
    q = quantiles[i]
    print(K.mean(model.loss['q{:0.2f}'.format(q)](sample_y,preds[i])))

tf.Tensor(0.8576285001198866, shape=(), dtype=float64)
tf.Tensor(7.439945051634891, shape=(), dtype=float64)
tf.Tensor(14.023351473256945, shape=(), dtype=float64)

这个真的让我摸不着头脑。我的直觉告诉我,我指定输出层或损失函数的方式存在问题。

4

0 回答 0