使用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中加载内存映射图吗?
答案 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复制到正常的文件系统位置。
完成这些步骤后,您可以照常使用会话和图表,并且应该看到加载时间和内存使用量减少。