所以我的问题是,如果我有类似的东西:
model = Model(inputs = input, outputs = [y1,y2])
model.compile(loss = my_loss ...)
我只把my_loss
看作是独立损失的字典,然后,最终损失定义为这些损失之和。但是,我可以在多任务模型中定义一个损失函数,该函数采用所有预测/真实值,然后将它们相乘(例如)吗?
这是我要定义的损失:
def my_loss(y_true1, y_true2, y_pred1, y_pred2):
final_loss = binary_crossentropy(y_true1, y_pred1) + y_true1 * categorical_crossentropy(y_true2, y_pred2)
return final_loss
通常,您的参数在损失函数中为y_true, y_pred
,其中y_pred
是y1
或y2
。但是现在我既需要计算损失,又要如何定义此损失函数并将所有参数传递给该函数:y_true1, y_true2, y_pred1, y_pred2
。
我要更改其损失的当前模型:
x = Input(shape=(n, ))
shared = Dense(32)(x)
sub1 = Dense(16)(shared)
sub2 = Dense(16)(shared)
y1 = Dense(1)(sub1, activation='sigmoid')
y2 = Dense(4)(sub2, activation='softmax')
model = Model(inputs = input, outputs = [y1,y2])
model.compile(loss = ['binary_crossentropy', 'categorical_crossentropy'] ...) #THIS LINE I WANT TO CHANGE IT
谢谢!
答案 0 :(得分:0)
我不确定我是否理解正确,但是我会尝试的。
损失函数必须同时包含预测数据和实际数据-这是一种衡量模型预测的数据与真实数据之间的误差的方法。但是,预测数据和实际数据不必是一维的。您可以使y_pred
既包含y_pred1
也包含y_pred2
的张量。同样,y_true
可以是同时包含y_true1
和y_true2
的张量。
据我所知,损失函数应该返回一个数字。因此,损失函数通常具有均值或总和,以求出各个数据点的所有损失。
这是一个均方误差示例,适用于一维以上:
import keras.backend as K
def my_loss(y_true, y_pred):
# this example is mean squared error
# works if if y_pred and y_true are greater than 1D
return K.mean(K.square(y_pred - y_true))
这是损失函数的另一个示例,我认为它更接近您的问题(尽管我无法评论它是否是一个好的损失函数):
def my_loss(y_true, y_pred):
# calculate mean(abs(y_pred1*y_pred2 - y_true1*ytrue2))
# this will work for 2D inputs of y_pred and y_true
return K.mean(K.abs(K.prod(y_pred, axis = 1) - K.prod(y_true, axis = 1)))
更新:
您可以使用keras.layers.Concatenate
将两个输出连接成一个张量。这样,您仍然可以仅具有两个参数而具有损失函数。
在上面编写的模型中,y1
的输出形状是(None, 1)
,而y2
的输出形状是(None, 4)
。这是一个示例,说明如何编写模型,以使输出为将y1
和y1
连接为(None, 5)
形状的单个张量:
from keras import Model
from keras.layers import Input, Dense
from keras.layers import Concatenate
input_layer = Input(shape=(n, ))
shared = Dense(32)(input_layer)
sub1 = Dense(16)(shared)
sub2 = Dense(16)(shared)
y1 = Dense(1, activation='sigmoid')(sub1)
y2 = Dense(4, activation='softmax')(sub2)
mergedOutput = Concatenate()([y1, y2])
下面,我将展示一个示例,说明如何重写损失函数。我不确定要调用y_true1
与y_true2
的输出的5列中的哪一列,因此我猜想y_true1
是列1,y_true2
是其余4列列。相同的列结构将适用于y_pred1
和y_pred2
。
from keras import losses
def my_loss(y_true, y_pred):
final_loss = (losses.binary_crossentropy(y_true[:, 0], y_pred[:, 0]) +
y_true[:, 0] *
losses.categorical_crossentropy(y_true[:, 1:], y_pred[:,1:]))
return final_loss
最后,您可以编译模型,而与正常情况相比没有任何重大变化:
model.compile(optimizer='adam', loss=my_loss)