You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras中自定义“差异度量”损失函数的定义问题排查

排查你的自定义损失函数问题

首先,我们先明确Malhotra论文里损失函数的计算逻辑:对于每个包含L个时间步的样本X,损失是每个时间步的真实向量x(i)与重构向量x'(i)的L2范数平方之和,之后在整个训练集上做平均(Keras默认会对batch内的损失取平均,所以我们只需要正确计算单个样本的损失即可)。

接下来看你写的mirror_loss函数,这里确实存在几个关键问题:

1. 范数计算的维度错误

你用了tf.norm(..., axis=1),这里的axis=1指定的是时间步维度,这会把每个样本的所有时间步的特征向量拼接起来计算整体范数,完全不符合论文中“对每个时间步的特征向量单独计算范数”的要求。正确的做法应该是对特征维度计算范数,也就是axis=-1(假设你的输入shape是(batch_size, timesteps, feature_dim),-1指向最后一个维度即特征维度)。

2. 没必要混用TensorFlow和Keras后端

Keras后端其实完全可以实现这个计算,混用两者虽然不一定报错,但可能带来兼容性问题,也没必要。而且我们可以直接计算平方差的和,这和“计算L2范数再平方”是等价的,还能减少计算步骤。

修正后的损失函数

这里给你两种版本的修正代码,推荐使用纯Keras后端的版本:

纯Keras后端实现

import keras.backend as K

def mirror_loss(y_true, y_pred):
    # 计算每个时间步下,真实与重构向量的平方差之和(等价于L2范数的平方)
    per_timestep_loss = K.sum(K.square(y_true - y_pred), axis=-1)
    # 对单个样本的所有时间步损失求和,得到单个样本的损失
    return K.sum(per_timestep_loss, axis=1)

如果你偏好使用TensorFlow实现(修正维度后)

import tensorflow as tf
import keras.backend as K

def mirror_loss(y_true, y_pred):
    # 修正axis为-1,针对特征维度计算范数
    diff = tf.square(tf.norm(tf.subtract(y_true, y_pred), axis=-1))
    # 对时间步维度求和,得到单个样本的损失
    return K.sum(diff, axis=1)

额外注意点

请确认你的y_true和y_pred的维度完全匹配,比如都是(batch_size, timesteps, feature_dim)。如果维度不对应,损失计算也会出现异常。

内容的提问来源于stack exchange,提问作者Irribarra Cristián

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:03:22