skl2onnx转换RandomForestClassifier时final_types的正确配置方法
你遇到的问题不需要调整随机森林模型本身,只需要修正ONNX转换环节的配置即可,核心原因是你对RandomForestClassifier的默认输出结构、skl2onnx的参数规则匹配错误。
错误原因说明
- 第一次报错是因为RandomForestClassifier默认输出两个结果:
output_label(预测类别标签,int64类型)、output_probability(各类别预测概率),你只声明了1个输出,数量不匹配。 - 第二次推理报错是因为skl2onnx默认把概率输出为
seq(map(int64, float))的复合结构,你强行指定为FloatTensorType([None, 1]),导致转换时生成了非法的类型转换节点,ONNX Runtime无法识别。
最佳配置方案
场景1:仅需要预测类别标签,不需要概率输出
转换时指定参数禁用概率输出即可,配置代码如下:
from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType, Int64TensorType initial_type = [('input', FloatTensorType([None, 13]))] # 仅配置标签输出,形状为一维数组,对应每个样本的预测结果 final_type = [('output_label', Int64TensorType([None]))] sklonnx = convert_sklearn( rfc, initial_types=initial_type, final_types=final_type, # 禁用概率输出 options={id(rfc): {'output_class_labels': True}} ) with open("sklrfc.onnx", "wb") as f: f.write(sklonnx.SerializeToString())
你原本的推理代码无需修改即可正常运行。
场景2:同时需要预测标签和类别概率
需要添加zipmap=False参数,把概率输出从默认的复合结构转为标准二维张量,对应配置如下:
from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType, Int64TensorType initial_type = [('input', FloatTensorType([None, 13]))] final_type = [ ('output_label', Int64TensorType([None])), # 二分类场景概率形状为[样本数, 2],多分类场景将2替换为你的类别总数即可 ('output_probability', FloatTensorType([None, 2])) ] sklonnx = convert_sklearn( rfc, initial_types=initial_type, final_types=final_type, # 关闭zipmap结构,将概率输出为标准二维张量 options={id(rfc): {'zipmap': False}} ) with open("sklrfc.onnx", "wb") as f: f.write(sklonnx.SerializeToString())
推理时如果仅需要标签,还是按你之前的代码取第一个输出即可;如果需要概率,取第二个输出,二分类场景下取output_probability[:, 1]即可得到正类的预测概率。
内容的提问来源于stack exchange,提问作者Anjoys
相关产品推荐
相关产品推荐

