TLDR:如何在Android上使用冻结tensorflow图中的变量?
1。我想做什么
我有一个Tensorflow模型,它在多个变量中保持一个内部状态,用:state_var = tf.Variable(tf.zeros(shape, dtype=tf.float32), name='state', trainable=False)
创建。在
此状态在推断过程中被修改:
tf.assign(state_var, new_value)
我现在想在Android上部署这个模型。我能够让Tensorflow示例应用程序运行。在那里,加载了一个冻结的模型,工作正常。在
2。从冻结图恢复变量不起作用
但是,当您使用freeze_graph script冻结图形时,所有变量都将转换为常量。这对于网络的权重是好的,但对于内部状态则不是这样。推理失败,并显示以下消息。我把它解释为“赋值不适用于常量张量”
^{pr2}$幸运的是,您可以将转换为常量的变量列入黑名单。但是,这也不起作用,因为冻结的图形现在包含未初始化的变量。在
java.lang.IllegalStateException: Attempting to use uninitialized value layer_7/state
3。恢复SavedModel在Android上不起作用
我尝试过的最后一个版本是使用SavedModel
格式,它应该同时包含冻结的图形和变量。不幸的是,调用restore方法在Android上不起作用。在
SavedModelBundle bundle = SavedModelBundle.load(modelFilename, modelTag);
// produces error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.tensorflow.demo, PID: 27451
java.lang.UnsupportedOperationException: Loading a SavedModel is not supported in Android. File a bug at https://github.com/tensorflow/tensorflow/issues if this feature is important to you at org.tensorflow.SavedModelBundle.load(Native Method)
4。我该怎么做?
我不知道还能做什么。以下是我的想象,但我不知道如何让它工作:
我自己通过另一条路解决了这个问题。据我所知,“变量”概念在Android上的使用方式与我在Python中使用的方式不同(例如,不能初始化变量,然后在推理过程中更新网络的内部状态)。在
相反,您可以使用placehlder和output节点来保存Java代码中的状态,并在每次推理调用时将其提供给网络。在
tf.Variable
替换为tf.placeholder
。形状保持不变。在tf.identity(inputs, name='state_output')
在Android上的推理过程中,然后将初始状态输入到网络中。在
float[] values = {0, 0, 0, ...}; // zeros of the correct shape inferenceInterface.feed('state', values, ...);
在推断之后,您将读取网络的内部状态
float[] values = new float[output_shape]; inferenceInterface.fetch('state_output', values);
然后在Java中记住这个输出,将其传递到
'state'
占位符中,以便下一次推理调用。相关问题 更多 >
编程相关推荐