python - 乘以输出自定义损失函数
问题描述
所以我的问题是,如果我有类似的东西:
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
isy1
或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
谢谢!
解决方案
我不确定我是否理解正确,但我会尝试。
损失函数必须同时包含预测数据和实际数据——这是一种衡量模型预测数据与真实数据之间误差的方法。然而,预测数据和实际数据不需要是一维的。您可以制作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])
下面,我将展示一个示例,说明如何重写损失函数。我不确定要调用输出的 5 列中的哪一列y_true1
vs. y_true2
,所以我猜那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)
推荐阅读
- r - 如何更改 ComplexHeatmap 中的边框大小?
- python-3.x - Ortools CVRP 重用旧车
- css - CSS属性值中的“--”破折号是什么意思
- python - 如何在python中动态生成键并将值分配给嵌套字典
- javascript - 如何查看在浏览器中出现错误的 js 行?
- javascript - 如何重构“if x return x”语句
- xamarin.android - Xamarin 中的 Android .aar 绑定库
- javascript - 导入静态函数/类时尝试导入错误
- node.js - 反应中的实时图表
- spring-boot - 查看特定的 flyway SQL 查询