TensorFlow自定义指标报错ValueError: None values not supported求解
问题解决方案
错误原因
报错的根本原因是你使用ap_distance.get_shape()[0]获取张量的静态shape:
get_shape()返回的是图构建阶段就能确定的静态shape信息,在输入batch size未固定的场景下,batch维度的静态值为None- TensorFlow的图执行模式不允许将
None转换为张量参与数值运算,因此抛出None values not supported的错误 - 你额外新增的静态shape判断逻辑依然无法解决问题,因为静态
None在图构建阶段就已经确定,无法在运行时动态判断
修复方案
将静态shape获取改为动态shape获取,使用tf.shape()函数,该函数返回的是运行时才能确定值的张量,可正常参与运算:
- 用
tf.shape(ap_distance)[0]替代ap_distance.get_shape()[0]获取当前batch的实际大小 - 不需要额外使用
tf.cond做边界判断,tf.math.divide_no_nan本身已经处理了分母为0的场景,会直接返回0 - 统一指标计算的数据类型为float32,避免类型不匹配错误
- 注意对齐你对真阳、假阳的定义:三元组任务的常规判定逻辑是
anchor与positive的距离 < anchor与negative的距离为预测正确,你当前代码的判定条件刚好相反,可按需调整
完整修改后的_compute_metrics代码
def _compute_metrics(self, data): ap_distance, an_distance = self.siamese_network(data) # 如需符合三元组常规判定逻辑,将greater改为less即可 tp = tf.reduce_sum(tf.cast(tf.math.greater(ap_distance, an_distance), tf.float32)) fp = tf.reduce_sum(tf.cast(tf.math.less_equal(ap_distance, an_distance), tf.float32)) batch_size = tf.cast(tf.shape(ap_distance)[0], tf.float32) # 此处为正确样本占比(准确率),如果你需要的是错误率,把tp改成fp即可 accuracy = tf.math.divide_no_nan(tp, batch_size) return tp, fp, accuracy
额外注意事项
你当前使用metrics.Mean来统计tp、fp的计数,这会得到每batch的平均tp/fp值,如果你需要的是整个epoch的累计tp/fp值,可将对应tracker替换为metrics.Sum。
内容的提问来源于stack exchange,提问作者pceccon
相关产品推荐
相关产品推荐

