模型转代码:XGBoost等模型也能快速转纯C或Java代码
机器之心编辑
参与:思源
你是否常训练炫酷的机器学习模型,用来分析数据或执行某些新奇的任务?你是否发现你的模型只能在一定开发环境上才能跑起来,很难部署也很难加入其它程序?今天我们将介绍一个炫酷的工具,它可以把构建在 scikit-learn 或 XGBoost 等库上的 ML 模型直接转化为不需要任何依赖项的 Java/Python/C 源代码。
项目地址:https://github.com/BayesWitnesses/m2cgen/
那么转化为 Java/Python/C 源代码有什么用呢?想象一下如果我们使用 ML 框架(scikit-learnXGBoostLightGBM)训练了一个模型,现在我们希望把这个模型做成应用或嵌入到已有的模型中,那么我们肯定需要考虑这些问题:
如果产品环境并没有 Python 运行时怎么办?
如果产品不能通过云服务器进行计算,只能在本地进行怎么办?
ML 模型的推断速度太慢又怎么办?
这些问题都很难解决,也是开发者在做自己项目时常遇到的问题。如果我们能将用 Python 和 ML 库构建的模型转换一下,变成纯 Java 或 C 写的代码,且这些代码不会依赖各种库,那么部署或嵌入不就简单了么。在 m2cgen 这个项目中,它就可以将 ML 模型转化为不带有依赖项的纯代码。
m2cgen(Model 2 Code Generator)是一个轻量级的 Python 库,它能快速便捷地将已训练统计模型转化为 Python、C 和 Java 代码。目前 m2cgen 已经支持各种分类模型与回归模型,包括支持向量机、决策树、随机森林和梯度提升树等,注意这些都是统计机器学习模型,深度神经网络还是老老实实使用 DL 框架吧。
模型转换效果
我们可以通过几个简单案例了解 m2cgen 是如何转换为纯代码的,简单而言即把模型架构和权重显化了。如下所示如果我们简单地训练一个线性回归模型,当然代码看着简单是因为我们直接调用了 scikit-learn 库中的模型。
from?sklearn.datasets?import?load_boston
from?sklearn?import?linear_model
import?m2cgen?as?m2c
boston?=?load_boston()
X,?y?=?boston.data,?boston.target
estimator?=?linear_model.LinearRegression()
estimator.fit(X,?y)
code?=?m2c.export_to_java(estimator)
上面最后一行将 scikit-learn 中的线性回归模型转化为 Java 代码,注意这个模型已经拟合了训练数据,或者说已经完成了训练。转化后的代码如下所示:
public?class?Model?{
????public?static?double?score(double[]?input)?{
????????return?(((((((((((((36.45948838508965)?+?((input[0])?*?(-0.10801135783679647)))?+?((input[1])?*?(0.04642045836688297)))?+?((input[2])?*?(0.020558626367073608)))?+?((input[3])?*?(2.6867338193449406)))?+?((input[4])?*?(-17.76661122830004)))?+?((input[5])?*?(3.8098652068092163)))?+?((input[6])?*?(0.0006922246403454562)))?+?((input[7])?*?(-1.475566845600257)))?+?((input[8])?*?(0.30604947898516943)))?+?((input[9])?*?(-0.012334593916574394)))?+?((input[10])?*?(-0.9527472317072884)))?+?((input[11])?*?(0.009311683273794044)))?+?((input[12])?*?(-0.5247583778554867));
????}
}
如上 return 后面的语句,它就是一个线性回归的表达式,每一个 input[ * ] 都是一种特征,它后面的数值就是训练后的权重。所以整个线性模型有 13 个特征及对应权重,以及另外一个偏置项。
我们还可以找到更多的案例,如果我们用 XGBoost 训练一个简单的分类模型,我们可以看到转化的代码会大量使用 if-else 大法,不过我们本身也不用维护生成的代码,所以这种结构也没什么关系了。
import?numpy?as?np
def?score(input):
????if?(input[2])?>=?(2.5999999):
????????var0?=?-0.0731707439
????else:
????????var0?=?0.142857149
????if?(input[2])?>=?(2.5999999):
????????var1?=?-0.0705206916
????else:
????????var1?=?0.12477719
????var2?=?np.exp(((0.5)?+?(var0))?+?(var1))
????if?(input[2])?>=?(2.5999999):
????????if?(input[2])?>=?(4.85000038):
????????????var3?=?-0.0578680299
????????else:
????????????var3?=?0.132596686
????else:
????????var3?=?-0.0714285821
????if?(input[2])?>=?(2.5999999):
????????if?(input[2])?>=?(4.85000038):
????????????var4?=?-0.0552999191
????????else:
????????????var4?=?0.116139404
????else:
????????var4?=?-0.0687687024
????var5?=?np.exp(((0.5)?+?(var3))?+?(var4))
????if?(input[2])?>=?(4.85000038):
????????if?(input[3])?>=?(1.75):
????????????var6?=?0.142011836
????????else:
????????????var6?=?0.0405405387
????else:
????????if?(input[3])?>=?(1.6500001):
????????????var6?=?0.0428571403
????????else:
????????????var6?=?-0.0730659068
????if?(input[2])?>=?(4.85000038):
????????if?(input[3])?>=?(1.75):
????????????var7?=?0.124653712
????????else:
????????????var7?=?0.035562478
????else:
????????if?(input[3])?>=?(1.6500001):
????????????var7?=?0.0425687581
????????else:
????????????var7?=?-0.0704230517
????var8?=?np.exp(((0.5)?+?(var6))?+?(var7))
????var9?=?((var2)?+?(var5))?+?(var8)
????return?np.asarray([(var2)?/?(var9),?(var5)?/?(var9),?(var8)?/?(var9)])
不过上面这种代码也非常合理,本身决策树就可以视为一种 if-else 的规则集合,不同输入特征 input[ * ] 满足不同的条件就能得到不同的值,这些值最后能联合计算分类结果。
项目细节
工具的安装很简单,直接用 pip 就行了:
pip?install?m2cgen
除了前面那样在代码中调用转换工具,我们还能通过命令行使用序列化的模型目标(pickle protocol)生成代码:
$?m2cgen?< pickle_file>?--language?< language>?[--indent?< indent>]
?????????[--class_name?< class_name>]?[--package_name?< package_name>]
?????????[--recursion-limit?< recursion_limit>]
目前项目支持以下分类和回归模型的转换:

分类模型输出结果:

本文为机器之心编辑,转载请联系本公众号获得授权。
?------------------------------------------------
加入机器之心(全职记者 / 实习生):hr@jiqizhixin.com
投稿或寻求报道:content@jiqizhixin.com
广告 & 商务合作:bd@jiqizhixin.com
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 “重要门户”迈向发展新阶段 7904842
- 2 海南省委书记用英语向全球发邀请 7808613
- 3 55岁三星长公主李富真露面 7714671
- 4 今起海南自贸港全岛封关 7617285
- 5 “顶流水果”30天狂降百元 7524138
- 6 本田在华工厂将停产 7424588
- 7 马年春晚吉祥物发布 7333031
- 8 2262年有两个春节 7231918
- 9 男子工厂吹玻璃30年成“青蛙王子” 7142887
- 10 《怦然心动》导演夫妇死因公布 7044021







机器之心
