怎么把.pb转换成TFLite格式?

时间:2018-10-21 17:34:00

标签: tensorflow tensorflow-lite

我下载了我在Azure认知服务中训练过的模型的retrained_graph.pbretrained_labels.txt文件。现在,我想使用该模型制作一个Android应用程序,为此,我必须将其转换为TFLite格式。我曾经使用过toco,但遇到以下错误:

ValueError: Invalid tensors 'input' were found.

我基本上是在遵循本教程,并且在第4步直接遇到了问题 复制粘贴的终端代码: https://heartbeat.fritz.ai/neural-networks-on-mobile-devices-with-tensorflow-lite-a-tutorial-85b41f53230c

12 个答案:

答案 0 :(得分:4)

由于版本问题,此处的大多数答案都被证明无法使用。这对我有用:

注意:首先使用Netron查找 input output 层的名称,正如我提到的here。在我的情况下,它们是void LongNumAddition1(unsigned char *Vin1, unsigned char *Vin2, unsigned char *Vout, unsigned N) { unsigned char CARRY = 0; for (int i = 0; i < N; i++) { unsigned char R = Vin1[i] + Vin2[i] + CARRY; Vout[i] = R % 10; CARRY = R / 10; } } void LongNumAddition1(char *Vin1, char *Vin2, char *Vout, unsigned N) { char CARRY = 0; for (int i = 0; i < N; i++) { char R = Vin1[i] + Vin2[i] + CARRY; if (R <= 9) { Vout[i] = R; CARRY = 0; } else { Vout[i] = R - 10; CARRY = 1; } } } input

output

此外,根据zldrobit令人惊叹的work,您还可以通过以下方式获取此TFLite模型的更好量化版本:

!pip install tensorflow-gpu==1.15.0

# Convert
!toco --graph_def_file /content/yolo-v2-tiny-coco.pb \
    --output_file yolo-v2-tiny-coco.tflite \
    --output_format TFLITE \
    --inference_type FLOAT \
    --inference_input_type FLOAT \
    --input_arrays input \
    --output_arrays output

答案 1 :(得分:2)

您可以使用实用程序tflite_convert,它是tensorflow 1.10(或更高版本)软件包的一部分。

浮点推论的简单用法类似于:

$users = User::whereDate('created_at', Carbon::today())
        ->count();

输入和输出-张量流图的输入和输出张量

答案 2 :(得分:2)

如果您使用的是TF2,则以下将适用于您发布量化的.pb文件。

import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_frozen_graph(
    graph_def_file = 'path/to/frozen_inference__graph.pb', 
    input_arrays = ['Input_Tensor_Name'],
    output_arrays = ['Output_Tensor_Name'] 
)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile('model.tflite', 'wb') as f:
  f.write(tflite_model)

如果您要完整的 int8 量化,则

import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_frozen_graph(
    graph_def_file = 'path/to/frozen_inference__graph.pb', 
    input_arrays = ['Input_Tensor_Name'],
    output_arrays = ['Output_Tensor_Name'] 
)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
image_shape=(input_width,input_height,no_of_channels) #change it according to your need
def representative_dataset_gen():
    for i in range(10):
        # creating fake images
        image = tf.random.normal([1] + list(image_shape))
        yield [image]

converter.representative_dataset = tf.lite.RepresentativeDataset(representative_dataset_gen)
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] # For EdgeTPU, no float ops allowed
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8

tflite_model = converter.convert()
with tf.io.gfile.GFile('model.tflite', 'wb') as f:
  f.write(tflite_model)

答案 3 :(得分:1)

错误提示您输入的信息不正确

--input_arrays

来自TF Lite Developer Guide 我引用:

”设置 input_array output_array 参数并不简单。查找这些值的最简单方法是使用 TensorBoard 浏览图形strong>。”

只需运行以下命令,使用Tensorboard也不难

tensorboard --logdir=path/to/log-directory

通过

查看TensorBoard
localhost:6006   

答案 4 :(得分:1)

我在这里大胆猜测,也许您输入了input_arrays=input。 可能不正确。使用此脚本找出冻结推理图的输入和输出数组的名称

import tensorflow as tf
gf = tf.GraphDef()   
m_file = open('frozen_inference_graph.pb','rb')
gf.ParseFromString(m_file.read())

with open('somefile.txt', 'a') as the_file:
    for n in gf.node:
        the_file.write(n.name+'\n')

file = open('somefile.txt','r')
data = file.readlines()
print "output name = "
print data[len(data)-1]

print "Input name = "
file.seek ( 0 )
print file.readline()

就我而言,它们是:

output name: SemanticPredictions
input name: ImageTensor

答案 5 :(得分:1)

__libc_read代替Mul为我修复了它。

input

答案 6 :(得分:1)

要在本地计算机上运行tflite转换器,您将需要bazel和toco。

如果您在GitHub上阅读了一些问题,则在某些版本的Tensrflow tflite中会造成很多麻烦。为了克服这个麻烦,有人建议每晚使用tf!

要避免所有这些情况,只需使用Google Colab将.pb转换为.lite或.tflite。

由于Colab开始具有用于将文件上传到当前内核的“上传”选项,所以我认为这是最简单的方法,而不必担心其他软件包及其依赖性。

这是Colab笔记本:

https://drive.google.com/file/d/1lDcttsmZC0Y6dXxwe0EVZUsyVoR8HuR-/view?usp=sharing

有两种方法可以将.pb文件上传到当前会话:

i)(简便方法)在上述笔记本中运行第一个单元之后,将安装驱动器。因此,在屏幕的左侧,转到“文件”列,然后右键单击要上载.pb文件的文件夹,然后选择“上载”。 然后使用“ ls”和“ cd”命令进入文件夹并运行tflite转换器单元。

ii)使用files.upload()命令运行单元,然后单击浏览并从本地计算机中选择.pb文件。

文件上传后,将其路径提供给变量“ localpb”,并提供.lite模型的名称。然后只需运行具有“ TFLiteConverter”命令的单元格即可。

瞧。您应该在驱动器中出现一个tflite模型。只需右键单击它并下载到本地计算机即可运行推理。

答案 7 :(得分:0)

很可能是因为在重新训练过程中,输入和输出张量被重命名了。如果这是重新训练的Inceptionv3图,请尝试使用 Mul 作为输入张量名称,并使用 final_result 作为输出张量名称。

bazel run --config=opt //tensorflow/contrib/lite/toco:toco -- \
    ... other options ...
    --input_shape=1,299,299,3 \
    --input_array=Mul \
    --output_array=final_result

如果按照Aleksandr的建议使用tflife_convert,则进行类似的调整。

答案 8 :(得分:0)

没有挡板,您可以尝试以下代码

pip uninstall tensorflow
pip install tf-nightly
pip show protobuf

如果protobuf的版本为3.6.1,则继续安装3.7.0的预发行版本。

pip uninstall protobuf
pip install protobuf==3.7.0rc2 

我仍然无法使用命令行版本。它一直返回错误:“ tflite_convert:错误:–graph_def_file需要–input_arrays和–output_arrays”,尽管同时提供了两个参数。但是,它可以在Python中工作。

import tensorflow as tf

graph_def_file = "model.pb"
input_arrays = ["model_inputs"]
output_arrays = ["model_outputs"]

converter = tf.lite.TFLiteConverter.from_frozen_graph(
        graph_def_file, input_arrays, output_arrays)
tflite_model = converter.convert()
open("converted_model.tflite", "wb").write(tflite_model)

答案 9 :(得分:0)

import tensorflow as tf
gf = tf.GraphDef()
m_file = open('frozen_inference_graph.pb','rb')
for n in gf.node:
    print( n.name )

第一个是input_arrays 姓氏是output_arrays(取决于模型的输出数量,可以是多个)

我的输出

  • 图像张量<---输入数组
  • 发布
  • 预处理器/贴图/形状预处理器/贴图/ strided_slice /堆栈
  • Preprocessor / map / strided_slice / stack_1
  • Postprocessor / BatchMultiClassNonMaxSuppression / map /
  • TensorArrayStack_5 / TensorArrayGatherV3
  • 后处理器/ Cast_3
  • 后处理器/压缩
  • 添加/ y
  • 添加
  • detection_boxes <---输出数组
  • detection_scores <--- output_array
  • detection_multiclass_scores
  • detection_classes <---输出数组
  • num_detections <---输出数组
  • raw_detection_boxes
  • raw_detection_scores

答案 10 :(得分:0)

将tensorflow导入为tf

!tflite_convert \
--output_file "random.tflite" \
--graph_def_file "pb file path" \
--input_arrays "input tensor name" \
--output_arrays "output tensor name"    

答案 11 :(得分:0)

我正在从上一个答案中跟进,您可以使用以下脚本使用

将ssd mobilenet上的训练模型转换为tflte
python object_detection/export_tflite_ssd_graph \
    --pipeline_config_path ssd_0.75_export/pipeline.config \
    --trained_checkpoint_prefix ssd_0.75_export/model.ckpt \
    --output_directory ssd_to_tflite_output

为此,您首先需要出现在tensorflow对象检测API的研究文件夹中,然后根据您的名称更改dile路径/名称。 如果这项工作很有效,请尝试从研究文件夹运行此脚本,然后重新运行:

protoc object_detection/protos/*.proto --python_out=.
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim