【问题标题】:How to use a generated H2O Autoencoder / Anomaly Detection Model for Inference in Java API?如何在 Java API 中使用生成的 H2O 自动编码器/异常检测模型进行推理?
【发布时间】:2017-11-06 15:27:15
【问题描述】:

我想在 Java 类中使用 H2O 自动编码器(异常检测)进行推理/预测。

我使用 R 从 H2O DeepLearningBooklet 构建了自动编码器示例“ECG Hearbeats”并保存了它。我可以成功地将生成的 Java 类及其相关的 h2o-genmodel.jar 导入到我的 Java 项目中。

不幸的是,我找不到如何在那里使用它的示例或文档。

这是我第一次尝试使用一些代码,并根据我对用于 Java 代码推理的其他 H2O 模型的经验进行了一些猜测:

private static String modelClassName = "machinelearning.DeepLearning_model_R_1509973865970_1";

public static void main(String[] args) throws Exception {

    hex.genmodel.GenModel rawModel;
    rawModel = (hex.genmodel.GenModel) Class.forName(modelClassName).newInstance();
    EasyPredictModelWrapper model = new EasyPredictModelWrapper(rawModel);

    RowData row = new RowData();
    // row.put(key, value); // TODO Add new line of input data, e.g.:
    // 2.10,2.13,2.19,2.28,2.44,2.62,2.80,3.04,3.36,3.69,3.97,4.24,4.53,4.80,5.02,5.21,5.40,5.57,5.71,5.79,5.86,5.92,5.98,6.02,6.06,6.08,6.14,6.18,6.22,6.27,6.32,6.35,6.38,6.45,6.49,6.53,6.57,6.64,6.70,6.73,6.78,6.83,6.88,6.92,6.94,6.98,7.01,7.03,7.05,7.06,7.07,7.08,7.06,7.04,7.03,6.99,6.94,6.88,6.83,6.77,6.69,6.60,6.53,6.45,6.36,6.27,6.19,6.11,6.03,5.94,5.88,5.81,5.75,5.68,5.62,5.61,5.54,5.49,5.45,5.42,5.38,5.34,5.31,5.30,5.29,5.26,5.23,5.23,5.22,5.20,5.19,5.18,5.19,5.17,5.15,5.14,5.17,5.16,5.15,5.15,5.15,5.14,5.14,5.14,5.15,5.14,5.14,5.13,5.15,5.15,5.15,5.14,5.16,5.15,5.15,5.14,5.14,5.15,5.15,5.14,5.13,5.14,5.14,5.11,5.12,5.12,5.12,5.09,5.09,5.09,5.10,5.08,5.08,5.08,5.08,5.06,5.05,5.06,5.07,5.05,5.03,5.03,5.04,5.03,5.01,5.01,5.02,5.01,5.01,5.00,5.00,5.02,5.01,4.98,5.00,5.00,5.00,4.99,5.00,5.01,5.02,5.01,5.03,5.03,5.02,5.02,5.04,5.04,5.04,5.02,5.02,5.01,4.99,4.98,4.96,4.96,4.96,4.94,4.93,4.93,4.93,4.93,4.93,5.02,5.27,5.80,5.94,5.58,5.39,5.32,5.25,5.21,5.13,4.97,4.71,4.39,4.05,3.69,3.32,3.05,2.99,2.74,2.61,2.47,2.35,2.26,2.20,2.15,2.10,2.08

    AutoEncoderModelPrediction p = model.predictAutoEncoder(row);

    System.out.println(p.reconstructedRowData);
    System.out.println(p.reconstructed[0]);
    // TODO How to do get the MSE from object 'p'? 

此代码实际编译并运行。但是,我真的不明白如何

  1. 正确配置 EasyPredictModelWrapper(还是我只需要实例化它?)
  2. 添加一个新的单个事件进行预测,因为我没有键,只有 ECG 心跳的值。 (我假设 row.putAll 方法对 ECG 数据集的各种特征来说是最好的?!)
  3. 从预测中获取 MSE(类似于我们在 R / Python 示例中看到的“recon_error

我认为答案很简单,但没有文档不容易找到:-)

感谢您的帮助。

【问题讨论】:

  • 您是否看到此文档:github.com/h2oai/h2o-3/blob/master/h2o-docs/src/product/…?它能回答你的大部分问题吗?
  • 我在前一段时间看到并实现了它作为第一个示例。但是,我需要一些文档如何使用 AutoEncoderModelPrediction 或其他使用自动编码器/异常检测功能的 H2O Java 代码。

标签: java deep-learning h2o autoencoder anomaly-detection


【解决方案1】:

(最后是main.java的代码示例)

  1. 你有正确的,它在这一行被实例化rawModel = (hex.genmodel.GenModel) Class.forName(modelClassName).newInstance();

  2. key 是列标题,value 是实际值,如果 H2Oframe 没有列标题,那么 H2O 会自动分配它们 C1C2 等。您可以手动编写此代码或使用 System.out.println(java.util.Arrays.toString(rawModel.getNames())); 循环(参见代码 sn-p 示例)

  3. 目前还没有这种方法,但是你可以得到原始值和重构值,然后从中计算 MSE(见下面的代码 sn-p,最后几行使用 @ 987654327@ 和 reconstructed 数组)

当我创建我的模型时,我将其命名为anomaly_model(直接参见下面的代码,model_id 是其中一个参数),你会看到在下面最后一个代码 sn-p 中使用了它,所以如果你使用不同的名称,您将需要更新该部分。

anomaly_model <- h2o.deeplearning(x = names(train_ecg), training_frame = train_ecg, activation = "Tanh",
                              autoencoder = TRUE,hidden = c(50,20,50),sparse = TRUE,l1 = 1e-4,epochs = 100, model_id = 'anomaly_model')

这是有关如何创建 main.java 文件、为您的键传递列名以及使用内置方法结果计算 MSE 的示例代码。

(注意:我为row.put(key, values) 生成了随机值,你可以在其中放任何你想要的东西)

import java.io.*;
import hex.genmodel.easy.RowData;
import hex.genmodel.easy.EasyPredictModelWrapper;
import hex.genmodel.easy.prediction.*;

public class main {
  private static String modelClassName = "anomaly_model";

  public static void main(String[] args) throws Exception {
    hex.genmodel.GenModel rawModel;
    rawModel = (hex.genmodel.GenModel) Class.forName(modelClassName).newInstance();
    EasyPredictModelWrapper model = new EasyPredictModelWrapper(rawModel);

    java.util.Random rng = new java.util.Random();
    RowData row = new RowData();
    for (String colName : rawModel.getNames()) {
      row.put(colName,rng.nextDouble());
    }

    AutoEncoderModelPrediction p = model.predictAutoEncoder(row);
    System.out.println("original: " + java.util.Arrays.toString(p.original));
    System.out.println("reconstructedrowData: " + p.reconstructedRowData);
    System.out.println("reconstructed: " + java.util.Arrays.toString(p.reconstructed));

    double sum = 0;
    for (int i = 0; i<p.original.length; i++) {
      sum += (p.original[i] - p.reconstructed[i])*(p.original[i] - p.reconstructed[i]);
    }
    double mse = sum/p.original.length;
    System.out.println("MSE: " + mse);
  }
}

希望这会有所帮助!

【讨论】:

  • 完美。工作......正是我需要的!我只需要用实际值替换 Row 的随机生成数据...
  • 在最新版本的 genmodel 包中,它们提供了 mse 值。但是有没有办法从 Java 类本身获取阈值?或任何计算都会有用。
猜你喜欢
  • 2022-01-14
  • 2016-04-16
  • 1970-01-01
  • 2021-07-18
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多