【问题标题】:How to convert .pb to TFLite format?如何将 .pb 转换为 TFLite 格式?
【发布时间】:2019-03-25 20:41:08
【问题描述】:

我下载了我在 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

【问题讨论】:

    标签: tensorflow tensorflow-lite


    【解决方案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
    

    【讨论】:

    • 注意:它适用于 TensorFlow v1.x。所以请使用!pip install tensorflow==1.14 安装它
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:
      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(可能不止一个,取决于您的模型输出数量)

      我的输出

      • image_tensor
      • 演员表
      • 预处理器/map/Shape Preprocessor/map/strided_slice/stack
      • 预处理器/map/strided_slice/stack_1
      • 后处理器/BatchMultiClassNonMaxSuppression/map/
      • TensorArrayStack_5/TensorArrayGatherV3
      • 后处理器/Cast_3
      • 后处理器/挤压
      • 添加/y
      • 添加
      • detection_boxes
      • detection_scores
      • detection_multiclass_scores
      • 检测类
      • num_detections
      • raw_detection_boxes
      • raw_detection_scores

      【讨论】:

        【解决方案4】:

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

        注意:首先使用 Netron 找到 inputoutput 层的名称,正如我提到的 here。就我而言,它们是inputoutput

        !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 的惊人 work,您还可以获取此 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
        

        【讨论】:

          【解决方案5】:

          错误提示你没有输入正确

          --input_arrays
          

          来自TF Lite Developer Guide 我引用:

          “设置 input_arrayoutput_array 参数并不简单。找到这些值的最简单方法是使用 TensorBoard强>。”

          使用 Tensorboard 也不难,只需运行此命令即可

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

          查看 TensorBoard
          localhost:6006   
          

          【讨论】:

          • 在张量板的哪个位置可以找到 input_array 和 output_array?
          • @Razgriz 如果在您的代码中执行了tf.summary.FileWriter(path, sess.graph),您将找到一个名为GRAPHS 的选项卡。点击GRAPH中的变量/操作框,你会找到名字。
          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

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

            为避免这一切,只需使用 Google Colab 将您的 .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() 命令运行单元并单击浏览并从本地计算机中选择 .pb 文件。

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

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

            【讨论】:

              【解决方案8】:

              没有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: –input_arrays and –output_arrays are required with –graph_def_file” 尽管提供了两个参数。然而,它在 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)
              

              【讨论】:

              • 您好泽山,我也在做同样的事情,但出现如下错误。请帮助 Traceback(最近一次调用最后):文件“freeze_graph.py”,第 8 行,在 转换器 = tf.lite.TFLiteConverter.from_frozen_graph( AttributeError: type object 'TFLiteConverterV2' has no attribute 'from_frozen_graph'
              【解决方案9】:

              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
              

              【讨论】:

                【解决方案10】:

                我正在跟进我之前的回答,您可以使用以下脚本将 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
                

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    【解决方案12】:

                    将张量流导入为 tf

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

                    【讨论】:

                      猜你喜欢
                      • 2019-05-08
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-05-04
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-10-22
                      相关资源
                      最近更新 更多