如何在android中读取tensorflow内存映射图文件? [英] How to read tensorflow memory mapped graph file in android?
问题描述
使用 Tensorflow 1.0.1 可以在 android 中使用 TensorFlowImageClassifier.create 方法读取优化图和量化图,例如:
Using Tensorflow 1.0.1 it's fine to read optimized graph and quantized graph in android using TensorFlowImageClassifier.create method, such as:
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/),建议在移动端使用内存映射图以避免内存相关的崩溃.
But according to the Peter Warden's Blog(https://petewarden.com/2016/09/27/tensorflow-for-mobile-poets/), it's recommended to use memory mapped graph in mobile to avoid memory related crashes.
我使用
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(...) 加载文件时,它说该文件不是有效的图形文件.
and it created fine, but when I tried to load the file with TensorFlowImageClassifier.create(...) it says the file is not valid graph file.
在iOS中,可以用
LoadMemoryMappedModel(
model_file_name, model_file_type, &tf_session, &tf_memmapped_env);
因为它有读取内存映射图的方法.
for it has a method for read memory mapped graph.
所以,我猜android中有类似的功能,但我找不到.
So, I guess there's a similar function in android, but I couldn't find it.
谁能指导我如何在android中加载内存映射图?
推荐答案
由于来自 memmapped 工具的文件不再是标准的 GraphDef protobuf,您需要对加载代码进行一些更改.您可以在 iOS 相机演示应用程序中看到一个示例,LoadMemoryMappedModel()
函数:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/ios_examples/camera/tensorflow_utils.mm#L159
Since the file from the memmapped tool is no longer a standard GraphDef protobuf, you need to make some changes to the loading code. You can see an example of this in the iOS Camera demo app, the LoadMemoryMappedModel()
function:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/ios_examples/camera/tensorflow_utils.mm#L159
相同的代码(使用 Objective C 调用获取文件名替换)也可以在其他平台上使用.因为我们使用内存映射,所以我们需要首先创建一个特殊的 TensorFlow 环境对象,该对象设置了我们将使用的文件:
The same code (with the Objective C calls for getting the filenames substituted) can be used on other platforms too. Because we’re using memory mapping, we need to start by creating a special TensorFlow environment object that’s set up with the file we’ll be using:
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);
然后您需要将此环境传递给后续调用,例如用于加载图形的调用.
You then need to pass in this environment to subsequent calls, like this one for loading the graph.
tensorflow::GraphDef tensorflow_graph;
tensorflow::Status load_graph_status = ReadBinaryProto(
memmapped_env->get(),
tensorflow::MemmappedFileSystem::kMemmappedPackageDefaultGraphDef,
&tensorflow_graph);
您还需要使用指向您创建的环境的指针创建会话:
You also need to create the session with a pointer to the environment you’ve created:
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 复制到正常的文件系统位置.
One thing to notice here is that we’re also disabling automatic optimizations, since in some cases these will fold constant sub-trees, and so create copies of tensor values that we don’t want and use up more RAM. This setup also means it's hard to use a model stored as an APK asset in Android, since those are compressed and don't have normal filenames. Instead you'll need to copy your file out of an APK onto a normal filesytem location.
完成这些步骤后,您可以照常使用会话和图形,并且您应该会看到加载时间和内存使用量有所减少.
Once you’ve gone through these steps, you can use the session and graph as normal, and you should see a reduction in loading time and memory usage.
这篇关于如何在android中读取tensorflow内存映射图文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!