【问题标题】:Tensorflow model import to JavaTensorFlow 模型导入 Java
【发布时间】:2017-09-17 04:49:07
【问题描述】:

我一直在尝试在 Java 中导入和使用我经过训练的模型(Tensorflow、Python)。

我能够在 Python 中保存模型,但是当我尝试在 Java 中使用相同的模型进行预测时遇到了问题。

Here,可以看到初始化、训练、保存模型的python代码。

Here,您可以看到用于导入和预测输入值的 Java 代码。

我得到的错误信息是:

Exception in thread "main" java.lang.IllegalStateException: Attempting to use uninitialized value Variable_7
     [[Node: Variable_7/read = Identity[T=DT_FLOAT, _class=["loc:@Variable_7"], _device="/job:localhost/replica:0/task:0/cpu:0"](Variable_7)]]
    at org.tensorflow.Session.run(Native Method)
    at org.tensorflow.Session.access$100(Session.java:48)
    at org.tensorflow.Session$Runner.runHelper(Session.java:285)
    at org.tensorflow.Session$Runner.run(Session.java:235)
    at org.tensorflow.examples.Identity_import.main(Identity_import.java:35)

我相信,问题出在 python 代码的某个地方,但我没能找到它。

【问题讨论】:

  • 我以this为灵感

标签: java python machine-learning tensorflow protocol-buffers


【解决方案1】:

你的 python 模型肯定会失败:

sess.run(init) #<---this will fail
save_model(sess)
error = tf.reduce_mean(tf.square(prediction - y))

#accuracy = tf.reduce_mean(tf.cast(error, 'float'))
print('Error:', error)

init 没有在模型中定义 - 我不确定你想在这个地方实现什么,但这应该给你一个起点

【讨论】:

    【解决方案2】:

    Java importGraphDef() 函数仅导入计算图(由tf.train.write_graph 在您的 Python 代码中编写),它不加载训练变量的值(存储在检查点中),这就是为什么您会得到一个抱怨未初始化变量的错误。

    另一方面,TensorFlow SavedModel format 包含有关模型的所有信息(图形、检查点状态、其他元数据),并且要在 Java 中使用,您希望使用 SavedModelBundle.load 来创建使用经过训练的变量值初始化的会话。

    要从 Python 中导出这种格式的模型,您可能需要查看相关问题 Deploy retrained inception SavedModel to google cloud ml engine

    在您的情况下,这应该相当于 Python 中的以下内容:

    def save_model(session, input_tensor, output_tensor):
      signature = tf.saved_model.signature_def_utils.build_signature_def(
        inputs = {'input': tf.saved_model.utils.build_tensor_info(input_tensor)},
        outputs = {'output': tf.saved_model.utils.build_tensor_info(output_tensor)},
      )
      b = saved_model_builder.SavedModelBuilder('/tmp/model')
      b.add_meta_graph_and_variables(session,
                                     [tf.saved_model.tag_constants.SERVING],
                                     signature_def_map={tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature})
      b.save() 
    

    然后通过save_model(session, x, yhat)调用它

    然后在 Java 中使用以下方法加载模型:

    try (SavedModelBundle b = SavedModelBundle.load("/tmp/mymodel", "serve")) {
      // b.session().run(...)
    }
    

    希望对您有所帮助。

    【讨论】:

    • 警告:虽然这适用于 Java,但 TF 目前不支持在 Android 中加载 SavedModel。发现这一点很困难。 ://
    • 请参阅问题 #12750 或 #13079,或参阅 tensorflow.org/mobile/prepare_models
    • 这适用于从 gcs 存储桶加载模型吗?我无法使用 savedmodelbundle 从 gcs 存储桶加载模型和变量
    【解决方案3】:

    Fwiw,Deeplearning4j 可让您导入在 TensorFlow 上使用 Keras 1.0 训练的模型(Keras 2.0 支持即将推出)。

    https://deeplearning4j.org/model-import-keras

    我们还构建了一个名为 Jumpy 的库,它是 Numpy 数组和 Pyjnius 的包装器,它使用指针而不是复制数据,这使得它在处理张量时比 Py4j 更高效。

    https://deeplearning4j.org/jumpy

    【讨论】:

    • 谢谢!我打算在 Tensorflow 中构建 GAN,据我所知,DL4J 通常不支持 GAN,这就是为什么我正在寻找一种解决方法,能够使用经过 Tensorflow 训练并在 JVM 上运行的 GAN。
    • keras 支持什么时候发布?我看到 PR 了。获得 conv1d 层支持会非常方便
    • RIP 跳起来。链接已损坏。
    猜你喜欢
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2021-10-20
    • 2018-06-17
    • 1970-01-01
    相关资源
    最近更新 更多