如何在android中读取tensorflow内存映射图文件?

时间:2017-04-21 03:06:41

标签: android tensorflow

使用Tensorflow 1.0.1可以使用TensorFlowImageClassifier.create方法在android中读取优化图和量化图,例如:

            classifier = TensorFlowImageClassifier.create(
                    c.getAssets(),
                    MODEL_FILE,
                    LABEL_FILE,
                    IMAGE_SIZE,
                    IMAGE_MEAN,
                    IMAGE_STD,
                    INPUT_NAME,
                    OUTPUT_NAME);

但是根据Peter Warden的博客(https://petewarden.com/2016/09/27/tensorflow-for-mobile-poets/),建议在移动设备中使用内存映射图来避免与内存相关的崩溃。

我使用

构建了memmapped图形
bazel-bin/tensorflow/contrib/util/convert_graphdef_memmapped_format \
--in_graph=/tf_files/rounded_graph.pb \
--out_graph=/tf_files/mmapped_graph.pb

并且它创建得很好,但是当我尝试使用TensorFlowImageClassifier.create(...)加载文件时,它说该文件不是有效的图形文件。

在iOS中,可以使用

加载文件
LoadMemoryMappedModel(
        model_file_name, model_file_type, &tf_session, &tf_memmapped_env);

因为它有一个读取内存映射图的方法。

所以,我猜Android中有类似的功能,但我找不到它。

有人可以指导我如何在android中加载内存映射图吗?

1 个答案:

答案 0 :(得分:3)

由于来自memmapped工具的文件不再是标准的GraphDef protobuf,因此您需要对加载代码进行一些更改。您可以在iOS Camera演示应用程序LoadMemoryMappedModel()函数中看到此示例: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/ios_examples/camera/tensorflow_utils.mm#L159

同样的代码(使用Objective C调用来取代文件名)也可以在其他平台上使用。因为我们正在使用内存映射,所以我们需要首先创建一个特殊的TensorFlow环境对象,该对象是使用我们将要使用的文件设置的:

std::unique_ptr<tensorflow::MemmappedEnv> memmapped_env;
memmapped_env->reset(
      new tensorflow::MemmappedEnv(tensorflow::Env::Default()));
  tensorflow::Status mmap_status =
      (memmapped_env->get())->InitializeFromFile(file_path);

然后,您需要将此环境传递给后续调用,例如用于加载图形的调用。

tensorflow::GraphDef tensorflow_graph;
tensorflow::Status load_graph_status = ReadBinaryProto(
    memmapped_env->get(),
    tensorflow::MemmappedFileSystem::kMemmappedPackageDefaultGraphDef,
    &tensorflow_graph);

您还需要使用指向您创建的环境的指针创建会话:

tensorflow::SessionOptions options;
options.config.mutable_graph_options()
    ->mutable_optimizer_options()
    ->set_opt_level(::tensorflow::OptimizerOptions::L0);
options.env = memmapped_env->get();

tensorflow::Session* session_pointer = nullptr;
tensorflow::Status session_status =
    tensorflow::NewSession(options, &session_pointer);

这里需要注意的一点是,我们也禁用了自动优化,因为在某些情况下,这些将折叠常量子树,因此创建我们不需要的张量值的副本并消耗更多的RAM。此设置还意味着很难在Android中使用存储为APK资产的模型,因为这些模型已压缩且没有正常的文件名。相反,您需要将文件从APK复制到正常的文件系统位置。

完成这些步骤后,您可以照常使用会话和图表,并且应该看到加载时间和内存使用量减少。