Tensorflow 如何将.pb转换为TFLite格式?

Tensorflow 如何将.pb转换为TFLite格式?,tensorflow,tensorflow-lite,Tensorflow,Tensorflow Lite,我下载了我在Azure认知服务中培训过的一个模型的rettrained_graph.pb和rettrained_labels.txt文件。现在我想用这个模型制作一个Android应用程序,为此我必须将它转换成TFLite格式。我使用了toco,我得到以下错误: ValueError: Invalid tensors 'input' were found. 我基本上是在遵循这个教程,在第4步和第4步中有问题 复制粘贴的终端代码: 您可以使用tensorflow 1.10(或更高版本)软件包中的实

我下载了我在Azure认知服务中培训过的一个模型的
rettrained_graph.pb
rettrained_labels.txt
文件。现在我想用这个模型制作一个Android应用程序,为此我必须将它转换成TFLite格式。我使用了toco,我得到以下错误:

ValueError: Invalid tensors 'input' were found.
我基本上是在遵循这个教程,在第4步和第4步中有问题 复制粘贴的终端代码:

您可以使用tensorflow 1.10(或更高版本)软件包中的实用程序

浮点推断的简单用法如下:

tflite_convert \
    --output_file=/tmp/retrained_graph.tflite \
    --graph_def_file=/tmp/retrained_graph.pb \
    --input_arrays=input \
    --output_arrays=output

其中输入和输出-是tensorflow图的输入和输出张量

很可能是因为在重新培训过程中输入和输出张量被重命名。如果这是一个重新训练的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\u convert,则会进行类似的调整。

错误提示您没有输入正确的

--input_arrays
从 我引述:

“设置输入数组输出数组参数并不简单。查找这些值的最简单方法是使用TensorBoard浏览图形。”

通过简单地运行这个命令,使用Tensorboard也不难

tensorboard --logdir=path/to/log-directory
查看位于的张力板

localhost:6006   

我在这里胡乱猜测,也许你输入了
input\u 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

如果没有bazel,您可以尝试以下代码

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:error:–graph_def_file需要–input_数组和–output_数组”,尽管提供了这两个参数。然而,它在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)
第一个是输入数组 姓氏是输出数组(可能不止一个,取决于模型的输出数量)

我的输出


  • image_tensor导入tensorflow作为tf

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

    Mul
    代替
    input
    为我修复了它

    IMAGE_SIZE=299
    tflite_convert \
      --graph_def_file=tf_files/retrained_graph.pb \
      --output_file=tf_files/optimized_graph.lite \
      --input_format=TENSORFLOW_GRAPHDEF \
      --output_format=TFLITE \
      --input_shape=1,${IMAGE_SIZE},${IMAGE_SIZE},3 \
      --input_array=Mul \
      --output_array=final_result \
      --inference_type=FLOAT \
      --input_data_type=FLOAT
    

    我在跟进我之前的回答,您可以使用以下脚本使用

    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
    

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

    如果您阅读了GitHub中的一些问题,那么在一些版本的Tensrflow tflite中会引起很多麻烦。为了克服这个问题,一些人建议每晚使用tf

    为了避免所有这些,只需使用GoogleColab将.pb转换为.lite或.tflite即可

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

    以下是相同的代码:

    from google.colab import drive
    drive.mount('/content/drive')
    
    
    !cd drive/My\ Drive
    
    
    from google.colab import files
    pbfile = files.upload()
    
    
    import tensorflow as tf
    
    localpb = 'frozen_inference_graph_frcnn.pb'
    tflite_file = 'frcnn_od.lite'
    
    print("{} -> {}".format(localpb, tflite_file))
    
    converter = tf.lite.TFLiteConverter.from_frozen_graph(
        localpb, 
        ["image_tensor"], 
        ['detection_boxes']
    )
    
    tflite_model = converter.convert()
    
    open(tflite_file,'wb').write(tflite_model)
    
    interpreter = tf.lite.Interpreter(model_content=tflite_model)
    interpreter.allocate_tensors()
    
    """**download optimized .lite file to local machine**"""
    
    files.download(tflite_file)
    
    有两种方法可以将.pb文件上载到当前会话:

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

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

    上传文件后,给出变量“localpb”的路径以及.lite模型的名称。然后简单地运行具有“TFLiteConverter”comamnd的单元


    瞧。您应该在驱动器中显示tflite型号。只需右键单击它并下载到您的本地计算机上即可进行推断。

    这里的大多数答案都被证明是由于版本问题而错误的。这对我很有用:

    注意:首先使用Netron查找输入输出层的名称,如我所述。在我的例子中,它们是
    输入
    输出

    !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
    
    
    此外,根据zldrobit的惊人之处,您还可以获取此TFLite模型的更好量化版本,如下所示:

    
    # Now let's quantize it
    !toco --graph_def_file /content/yolo-v2-tiny-coco.pb \
        --output_file quantized-yolo-v2-tiny-coco.tflite \
        --output_format TFLITE \
        --inference_type FLOAT \
        --inference_input_type FLOAT \
        --input_arrays input \
        --output_arrays output \
        --post_training_quantize
    

    如果您使用的是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)
    

    在tensorboard的哪个位置可以找到输入数组和输出数组?@Razgriz如果在您的代码中有
    tf.summary.FileWriter(path,sess.graph)
    ,您将找到一个名为
    GRAPHS
    的选项卡。点击图中的变量/操作框,你会找到名称。嗨,泽山,我也在做同样的事情,但得到如下错误。请帮助回溯(最后一次调用):converter=tf.lite.TFLiteConverter.from_Froze_graph(AttributeError:type对象'TFLiteConverterV2'没有'from_Froze_graph'属性)中的文件“freeze_graph.py”,第8行,注意:它适用于TensorFlow v1.x。请使用
    !pip install TensorFlow==1.14
    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)