在Tensorflow.keras 2.0中,当一个模型有多个输出时,如何为model.fit()定义一个灵活的损失函数



假设这里有一个具有两个输出的模型。

import tensorflow as tf
import numpy as np 
x = tf.keras.Input(shape=(35, 7), dtype=tf.float32)     # (None, 35, 7)
net = tf.keras.layers.Dense(11, activation='relu')(x)   # (None, 35, 11)
net = tf.reduce_max(net, axis=1, name='maxpool')        # (None, 11)
a = tf.keras.layers.Dense(13, activation='relu')(net)   # (None, 35, 11)
b = tf.keras.layers.Dense(17, activation='relu')(net)   # (None, 35, 11)
model = tf.keras.Model(inputs=x, outputs=[a, b])

当我执行model.compile(loss=loss_fn, optimizer='sgd'):
时,model.fit(x=train, y=(label1, label2))为每对输出和标签(即loss_fn(a, l1)loss_fn(b, l1)(运行loss_fn

当我执行model.compile(loss=[loss_fn1, loss_fn2], optimizer='sgd'):
时,model.fit(x=train, y=(label1, label2))a运行loss_fn1,为b运行loss_fn2(即loss_fn1(a, l1)loss_fn2(b, l1)(。

因此,基本上它似乎是单独处理输出(与给定的相应标签配对(。

如果我必须定义一个损失函数,该函数应同时处理/考虑两个输出,并将该函数与model.fit一起使用,该怎么办

(我能想到的一件事是将输出连接到一个张量中,并在损失函数中分离它们。然而,我不想去那里,因为两个输出可能没有一致的形状。相反,有可能吗,例如,类似…(

def loss_fn(y_true, y_pred):
# I want to access both output ...
l1, l2 = y_true
a, b = y_pred
# ... do something about loss ...
return loss

您将连接两个密集层,并执行与您提到的完全相同的操作:

import numpy as np
from tensorflow.keras.layers import Input, Dense, Concatenate
from tensorflow.keras.models import Model
import tensorflow.keras.backend as K
i = Input((10,))
x = Dense(10)(i)
a = Dense(3, use_bias=False)(x)
b = Dense(3, use_bias=False)(x)
# Now you concatenate both outputs,
# so nothing happens to them
c = Concatenate()([a,b])
m = Model(i, c)
def loss(y_true, y_pred):
# Do your loss on your subset
a, b  = y_pred[:, :3], y_pred[:, 3:]
# Do something random
return K.mean(a*b)
m.compile("adam", loss)
m.fit(np.random.random((10, 10)),
np.random.random((10, 6)))
# Outputs:
# 10/10 [=======] - 0s 22ms/sample - loss: -0.2251

编辑;实际上还没有看到@bit01已经评论了要去的方法

相关内容

最新更新