【问题标题】:How to export an h2o model as MOJO from sparkling water in scala, to be loaded by EasyPredictModelWrapper如何从 scala 中的苏打水中将 h2o 模型导出为 MOJO,由 EasyPredictModelWrapper 加载
【发布时间】:2018-03-27 14:30:29
【问题描述】:

我的目标是导出一个使用 scala(使用苏打水)在 spark 上训练的 h2o 模型,这样我就可以在没有 Spark 的应用程序中导入它。

因此:

  • 使用 scala(文档仅显示 r 和 python 的示例)
  • 导出使用苏打水(带火花的水)构建的模型
  • 在 scala 中导入模型(没有 spark 或 h2o 集群,只有 hex-genmodel 包)

因此我使用ModelSerializationSupport 导出,MojoModel.load 导入

val gbmParams = new GBMParameters()
gbmParams._train = train
gbmParams._response_column = "target"
gbmParams._ntrees = 5
gbmParams._valid = valid
gbmParams._nfolds = 3 
gbmParams._min_rows = 1
gbmParams._distribution = DistributionFamily.multinomial
val gbm = new GBM(gbmParams)
val gbmModel = gbm.trainModel.get
val mojoPath = "./model.zip"
ModelSerializationSupport.exportMOJOModel(gbmModel, new File(mojoPath).toURI, force = true)
val simpleModel = new EasyPredictModelWrapper(MojoModel.load(mojoPath))

失败了

error in opening zip file
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:220)
at java.util.zip.ZipFile.<init>(ZipFile.java:150)
at java.util.zip.ZipFile.<init>(ZipFile.java:121)
at hex.genmodel.ZipfileMojoReaderBackend.<init>(ZipfileMojoReaderBackend.java:13)
at hex.genmodel.MojoModel.load(MojoModel.java:33)
...

似乎 mojo 导出器使用的格式与 hex.genmodel 中预期的格式不同(显然是 zip)

在 h2o 2.1.23(构建集群时 2.1.24 失败,如 https://0xdata.atlassian.net/browse/SW-776 上报告的那样)和 spark 2.1 上运行

-- 更新:

使用 ModelSerializationSupport 类加载它自己的导出也失败了,同样的异常:

ModelSerializationSupport.loadMOJOModel(new File(mojoPath).toURI)

H2OModel 导出和加载
以 H2OModel 的形式重新加载(因此使用苏打水)确实有效:

val h2oModelPath = "./model_h2o"
ModelSerializationSupport.exportH2OModel(gbmModel, new File(h2oModelPath).toURI, force = true)
val loadedModel: GBMModel = ModelSerializationSupport.loadH2OModel(new File(h2oModelPath).toURI)

H2OMOJO模型导出和加载
H2OMOJOModel 加载它确实有效(从H2OGBM 的实现中复制):

val mojoModel = new H2OMOJOModel(ModelSerializationSupport.getMojoData(gbmModel))
mojoModel.write.overwrite.save(mojoPath)
H2OMOJOModel.load(mojoPath) 

H2OGBM 导出与 MojoModel 导入
尝试使用常规 MojoModel 导入失败:

val gbm = new H2OGBM(gbmParams)(h2oContext, myspark.sqlContext)
val gbmModel = gbm.trainModel(gbmParams)
val mojoPath = "./models.zip"
gbmModel.write.overwrite.save(mojoPath)
MojoModel.load(mojoPath)

以下例外:

./models.zip/model.ini (No such file or directory)
java.io.FileNotFoundException: ./models.zip/model.ini (No such file or directory)

【问题讨论】:

    标签: scala h2o sparkling-water


    【解决方案1】:

    解决方案实际上在ModelSerializationSupport 上的getMojoModel(接受Model[_,_,_]Array[Byte])中进行了解释

    getMojoModel(Model[_,_,_]) 的实现使用字节数组将getMojoData(Model[_,_,_]) 存储到,然后从该字节数组中读回。

    快速测试如下:

    val config = new EasyPredictModelWrapper.Config()
    config.setModel(ModelSerializationSupport.getMojoModel(gbmModel))
    config.setConvertUnknownCategoricalLevelsToNa(true)
    val easyPredictModelWrapper = new EasyPredictModelWrapper(config)
    

    因此,现在我们可以自己复制它,但无需使用 ModelSerializationSupport 类(因为它是苏打水的一部分)。

    首先将mojo数据存储到一个文件中:

    val path = java.nio.file.Files.createTempFile("model", ".mojo")
    path.toFile.deleteOnExit()
    path.toString
    import java.io.FileOutputStream
    val outputStream = new FileOutputStream(path.toFile)
    try {
      gbmModel.getMojo.writeTo(outputStream
    }
    finally if (outputStream != null) outputStream.close()
    

    然后读取字节(在另一个 scala 应用程序中):

    val is = new FileInputStream(path.toFile)
    val reader = MojoReaderBackendFactory.createReaderBackend(is, MojoReaderBackendFactory.CachingStrategy.MEMORY)
    val mojoModel = ModelMojoReader.readFrom(reader)
    val config = new EasyPredictModelWrapper.Config()
    config.setModel(mojoModel)
    config.setConvertUnknownCategoricalLevelsToNa(true)
    val easyPredictModelWrapper = new EasyPredictModelWrapper(config)
    

    【讨论】:

    • 如何在import ai.h2o.sparkling.ml.models.H2OMOJOModelhex.genmodel.MojoModel 之间切换?
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 2020-11-20
    • 2022-01-23
    • 2015-09-23
    • 2020-05-23
    相关资源
    最近更新 更多