【发布时间】:2020-05-05 13:38:27
【问题描述】:
我一直在尝试在 Keras 中构建自己的自定义损失并遇到一些错误。
我的需求如下:我想在一个稳定的时间序列上构建一个分类器:它必须决定曲线是上升还是下降趋势,这意味着如果导数为负对于 2 或 3 个时间步,它必须保持“上升”分类,而不是在一小段时间内切换到后代。输入数据是上下文数据,应有助于 NN 检测时间序列方向的当前变化是否可能持续。
为此,我设想构建一个自定义损失函数,该函数会为在参考之上或之下的每次分类更改添加惩罚。
我首先想在预测张量和参考张量上使用 np.where,但我知道浏览论坛这是不可能的,因为损失函数使用占位符张量。我必须留在 keras 后端的功能空间内。
出于这个原因,我使用我在这个论坛上找到的一些代码来构建以下损失函数:
import keras.backend as kb
def roll_reg(x):
length = kb.int_shape(x)[0]
x_tile = kb.tile(x, [2, 1])
x_roll = x_tile[length - 1:-1]
return kb.sum(kb.abs(x - x_roll))
def custom_loss(y_actual,y_predicted):
posact=kb.flatten(y_actual)
pospred=kb.flatten(y_predicted)
na=roll_reg(posact)
np=roll_reg(pospred)
loss_cust=kb.mean(((y_actual-y_predicted)**2)**0.5/(kb.max(y_actual)-kb.min(y_actual)))+abs(na-np)/kb.int_shape(posact)*10
return loss_cust
但我仍然收到此错误:
ValueError:形状必须为 1 级,但为 2 级 'loss_9/dense_25_loss/Tile'(操作:'Tile'),输入形状:[?]、[2]。
我将其解释为无法在占位符张量上进行操作……而我试图为这些张量使用专用函数。
有人知道我可以做些什么来改进此代码以使我的损失函数运行吗?
关于这个问题的一些更新。我在互联网上找到了这个页面:https://medium.com/@j.ali.hab/on-custom-loss-functions-in-keras-3af88cf59e48 使用 tf.math 库解决了同样的问题。
所以我将代码更新为:
def custom_loss(y_actual,y_predicted):
na=kb.tf.math.cumsum(y_actual,axis=0)
np=kb.tf.math.cumsum(y_predicted,axis=0)
penalty=kb.abs(kb.sum(np-na))/118319#/kb.int_shape(y_actual)[0]
loss_nico=penalty
return loss_nico
现在代码正在编译,但我在每个 epoch 的最后得到一个 Nan 作为损失函数。当然,神经网络不会因此而学习任何东西。
有人知道我做错了什么吗?
【问题讨论】:
-
关于这个问题的一些更新。
标签: python keras loss-function