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

Keras自定义损失函数报错:ValueError: None values not supported

解决Keras自定义函数中的ValueError: None values not supported问题

首先,咱们来拆解下你遇到的错误:这个报错的核心原因是当trade_index里没有任何True值时,tf.boolean_mask会返回一个空张量(也就是None),而Keras的损失/指标函数无法处理这种空张量,所以抛出了这个错误。

你的需求是只计算神经网络选中样本的准确率,那咱们得先处理“没有选中样本”这种边界情况,下面给你两种可行的解决方案:

方案一:直接修改自定义函数,处理空张量情况

你可以在函数里先判断是否存在选中的样本,用分支逻辑来避免空张量的出现。修改后的代码如下:

import tensorflow as tf
from tensorflow.keras import backend as K

def getBalance(x_true, x_pred):
    # 将预测值四舍五入为二进制值
    x_pred = K.round(x_pred)
    # 筛选出预测第二列不为0的样本索引
    trade_index = K.not_equal(x_pred[:, 1], 0)
    
    # 检查当前批次是否有选中的样本
    has_selected_samples = K.any(trade_index)
    
    # 定义有选中样本时的准确率计算逻辑
    def calculate_accuracy():
        # 提取选中样本的真实值和预测值(第一列)
        x_true_tradeable = K.boolean_mask(x_true[:, 0], trade_index)
        x_pred_tradeable = K.boolean_mask(x_pred[:, 0], trade_index)
        # 计算准确率:正确预测的比例
        return K.mean(K.equal(x_true_tradeable, x_pred_tradeable))
    
    # 没有选中样本时返回默认值(这里用0.0,你可以根据需求调整,比如返回1.0)
    def no_selected_case():
        return K.constant(0.0)
    
    # 根据是否有选中样本选择执行对应的逻辑
    return tf.cond(has_selected_samples, calculate_accuracy, no_selected_case)

关键说明:

  • 用K.any(trade_index)快速判断当前批次是否存在选中的样本
  • 用tf.cond实现分支逻辑,当没有选中样本时返回一个常量值,彻底避免空张量导致的None错误

方案二:用自定义Metric类实现(更适合作为评估指标)

如果你这个函数是用来评估模型准确率的(而非损失函数),更推荐用Keras的Metric类来实现,它能更好地处理跨批次的累计计算,比如某些批次没有选中样本时,不会影响整体的准确率统计。代码示例:

import tensorflow as tf
from tensorflow.keras import backend as K

class SelectedSampleAccuracy(tf.keras.metrics.Metric):
    def __init__(self, name='selected_sample_accuracy', **kwargs):
        super().__init__(name=name, **kwargs)
        # 初始化累计变量:正确预测的数量、选中样本的总数量
        self.correct_predictions = self.add_weight(name='correct', initializer='zeros')
        self.total_selected = self.add_weight(name='total', initializer='zeros')
    
    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = K.round(y_pred)
        # 筛选选中样本的索引
        trade_index = K.not_equal(y_pred[:, 1], 0)
        
        # 提取选中样本的真实值和预测值
        y_true_selected = K.boolean_mask(y_true[:, 0], trade_index)
        y_pred_selected = K.boolean_mask(y_pred[:, 0], trade_index)
        
        # 计算当前批次的正确数和选中样本数
        correct = K.sum(K.cast(K.equal(y_true_selected, y_pred_selected), dtype=K.floatx()))
        total = K.cast(K.shape(y_true_selected)[0], dtype=K.floatx())
        
        # 只有当有选中样本时才更新累计值
        if total > 0:
            self.correct_predictions.assign_add(correct)
            self.total_selected.assign_add(total)
    
    def result(self):
        # 避免除以0的情况,当没有选中样本时返回0.0
        return K.switch(K.equal(self.total_selected, 0), K.constant(0.0), 
                       self.correct_predictions / self.total_selected)
    
    def reset_state(self):
        # 重置累计变量,用于新一轮评估
        self.correct_predictions.assign(0.0)
        self.total_selected.assign(0.0)

使用方式:

在模型编译时直接传入这个自定义指标:

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[SelectedSampleAccuracy()])

这样就能在训练/评估时,自动统计所有选中样本的准确率啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:17:27