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

如何在Keras中构建带逐样本权重自定义损失函数的神经网络

Keras自定义加权分类损失实现方案

你代码中已经开启了run_eagerly=True,所有张量默认按eager模式执行,input、y_true、y_pred均为按批次存储的张量,第一维为批次大小,每一行对应同一个样本的输入、真实标签、预测结果。

1. 打印input、y_true和y_pred的取值

eager模式下直接用print或者tf.print均可输出张量的具体数值,示例代码:

def custom_loss(input):
    def loss(y_true, y_pred):
        # 直接打印,eager模式自动输出具体值
        print("批次输入:", input)
        print("真实标签:", y_true)
        print("预测结果:", y_pred)
        # 也可以用tf.print,兼容性更强,summarize=-1可打印全部内容,默认只打印前几个元素
        tf.print("批次输入:", input, summarize=-1)
        # 后续损失逻辑
    return loss

2. 将input转换为numpy ndarray格式

开启eager执行的前提下,直接调用张量的.numpy()方法即可转换:

def custom_loss(input):
    def loss(y_true, y_pred):
        input_np = input.numpy()
        y_true_np = y_true.numpy()
        y_pred_np = y_pred.numpy()
        # 此时input_np就是shape为(batch_size, 16)的numpy数组,可以直接遍历查询权重
        return ...
    return loss

如果后续要关闭eager提升运行效率,可以改用TensorFlow内置的哈希表查询权重,无需转numpy。

3. 实现分类错误按权重计算损失的逻辑

首先注意你当前模型存在问题:输出层为1个神经元,用softmax激活的话输出值永远为1,无法正常做二分类判断,建议将输出层激活改为sigmoid。
损失实现示例(假设输入的第0位为样本ID,提前构造好ID到权重的映射字典):

# 提前构造样本ID到权重的映射,可替换为你的实际权重逻辑
sample_weight_map = {1: 0.5, 2: 1.2, 3: 2.0}

def custom_loss(input):
    def loss(y_true, y_pred):
        # 1. 判断每个样本是否分类正确
        # 二分类场景,sigmoid输出>0.5判定为正类
        y_pred_cls = tf.cast(y_pred > 0.5, tf.float32)
        # 正确为1,错误为0
        correct_flag = tf.cast(tf.equal(y_pred_cls, y_true), tf.float32)
        # 错误样本掩码:错误为1,正确为0
        error_mask = 1 - correct_flag

        # 2. 批量查询每个样本的权重
        input_np = input.numpy()
        batch_weights = []
        for i in range(input_np.shape[0]):
            sample_id = int(input_np[i][0])
            batch_weights.append(sample_weight_map.get(sample_id, 1.0)) # 不存在的ID默认权重为1
        batch_weights_tensor = tf.convert_to_tensor(batch_weights, dtype=tf.float32)

        # 3. 计算损失:正确样本损失为0,错误样本损失为对应权重,返回批次平均损失
        per_sample_loss = error_mask * batch_weights_tensor
        return tf.reduce_mean(per_sample_loss)
    return loss

如果想避免转numpy提升运行效率,可以用TensorFlow内置哈希表实现权重查询,无需依赖eager模式:

# 构造静态哈希表
keys = tf.constant([1,2,3], dtype=tf.int32)
values = tf.constant([0.5,1.2,2.0], dtype=tf.float32)
weight_table = tf.lookup.StaticHashTable(
    tf.lookup.KeyValueTensorInitializer(keys, values),
    default_value=1.0
)

def custom_loss(input):
    def loss(y_true, y_pred):
        y_pred_cls = tf.cast(y_pred > 0.5, tf.float32)
        correct_flag = tf.cast(tf.equal(y_pred_cls, y_true), tf.float32)
        error_mask = 1 - correct_flag
        # 直接用张量操作查权重,无需转numpy
        sample_ids = tf.cast(input[:, 0], tf.int32)
        batch_weights_tensor = weight_table.lookup(sample_ids)
        per_sample_loss = error_mask * batch_weights_tensor
        return tf.reduce_mean(per_sample_loss)
    return loss

内容的提问来源于stack exchange,提问作者Katja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 02:42:02