首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >LSTM模型的Int8量子化无论哪个版本,我都会遇到问题。

LSTM模型的Int8量子化无论哪个版本,我都会遇到问题。
EN

Stack Overflow用户
提问于 2021-09-21 14:04:32
回答 2查看 663关注 0票数 1

我想用生成器来量化LSTM模型。

问题

我从这个问题开始,因为这是一个相当长的职位。实际上,我想知道你是否已经开始量化(int8),一个带有训练后量化的LSTM模型。

我试过不同的TF版本,但总是遇到错误。下面是我的一些尝试。也许你看到了我犯的错误或者有个建议。谢谢

工作部件

预期输入为(批处理,1,45)。用非量化模型运行推理,运行良好的.在这里可以找到模型和csv:

csv文件:https://mega.nz/file/5FciFDaR#Ev33Ij124vUmOF02jWLu0azxZs-Yahyp6PPGOqr8tok

模型文件:https://mega.nz/file/UAMgUBQA#oK-E0LjZ2YfShPlhHN3uKg8t7bALc2VAONpFirwbmys

代码语言:javascript
运行
复制
import tensorflow as tf
import numpy as np
import pathlib as path
import pandas as pd  

def reshape_for_Lstm(data):    
    timesteps=1
    samples=int(np.floor(data.shape[0]/timesteps))
    data=data.reshape((samples,timesteps,data.shape[1]))   #samples, timesteps, sensors     
    return data

if __name__ == '__main__':

#GET DATA
    import pandas as pd
    data=pd.read_csv('./test_x_data_OOP3.csv', index_col=[0])
    data=np.array(data)
    data=reshape_for_Lstm(data)  
    
#LOAD MODEL
    saved_model_dir= path.Path.cwd() / 'model' / 'singnature_model_tf_2.7.0-dev20210914'    
    model=tf.keras.models.load_model(saved_model_dir)

# INFERENCE
    [yhat,yclass] = model.predict(data)    
    Yclass=[np.argmax(yclass[i],0) for i in range(len(yclass))] # get final class
    
    print('all good')

变量data的形状和dtype为(20000,1,45), float64

出错的地方,

现在我要量化这个模型。但根据TensorFlow版本的不同,我会遇到不同的错误。

我使用的代码选项合并如下:

代码语言:javascript
运行
复制
    converter=tf.lite.TFLiteConverter.from_saved_model('./model/singnature_model_tf_2.7.0-dev20210914')
    converter.representative_dataset = batch_generator
    converter.optimizations = [tf.lite.Optimize.DEFAULT]         

    converter.experimental_new_converter = False  
   
    #converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] 
    converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8, tf.lite.OpsSet.TFLITE_BUILTINS]
    #converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS]
    
    #converter._experimental_lower_tensor_list_ops = False

    converter.target_spec.supported_types = [tf.int8]
    quantized_tflite_model = converter.convert()

TensorFlow 2.2

使用TF2.2,正如Git中经常提到的那样,我遇到了来自tflite的不受支持的操作符。使用tf2.2创建的模型确保版本支持。这里,只支持TOCO转换。

模型中的一些操作符不受标准TensorFlow Lite运行时的支持,也不为TensorFlow所识别。

错误不依赖于converter.target_spec.supported_ops选项。因此,我找不到解决办法。allow_custom_ops只会转移问题。这里有一些相当的 一些 git 问题(仅举几个例子),但所有建议的选项都不起作用。

一种是尝试新的MILR转换器,然而,在2.2中,只有整数转换的MILR 还没做完

因此,让我们尝试一个更新的版本。

TensorFlow 2.5.0

然后我尝试了一个经过仔细审查的版本。在这里,无论我使用MLIR转换在以下错误中运行的converter.target_spec.supported_ops

in the calibrator.py

ValueError:未能解析模型:pybind11 11::init():factory函数返回nullptr。

关于Git的解决方案将使用TF==2.2.0版本。

通过TOCO转换,我得到以下错误:

tensorflow/lite/toco/allocate_transient_arrays.cc:181]是一个数组,在所有图形转换运行之后,StatefulPartitionedCall/StatefulPartitionedCall/model/lstm/TensorArrayUnstack/TensorListFromTensor,仍然没有已知的数据类型。致命Python错误:中止

我没有找到关于这个错误的任何东西。也许它在2.6中解决了

TensorFlow 2.6.0

在这里,无论我使用哪个converter.target_spec.supported_ops,我都会遇到以下错误:

ValueError:未能解析该模型:只支持具有单个子图的模型,模型有5个子图。

该模型为五层模型。因此,似乎每个层都被看作一个子图。我没有找到一个关于如何将它们合并成一个子图的答案。这个问题显然与2.6.0有关在2.7中解决 --所以,让我们尝试一下夜间构建。

TensorFlow 2.7-夜间(尝试2.7.0-dev20210914和2.7.0-dev20210921)

这里我们必须使用Python3.7作为3.6不再支持

在这里我们必须使用

代码语言:javascript
运行
复制
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS]

但是,甚至有人说

代码语言:javascript
运行
复制
converter._experimental_lower_tensor_list_ops = False

应该设定,似乎没有必要。

这里的问题是,据我所知,tf.lite.OpsSet.SELECT_TF_OPS称为calibrator.py。在calibrator.py中,representative_dataset需要特定的生成器数据。从第93行起_feed_tensor()函数中,生成器需要一个dict、list或tuple。在tf.lite.RepresentativeDataset函数描述或tflite类描述中,它声明数据集应该与模型的输入相同。在我的例子中(大多数情况下),它只是一个正确维度中的numpy数组。

在这里,我可以尝试将我的数据转换成一个元组,但是,这似乎是不正确的。还是说这就是真正的出路?

非常感谢你阅读了这篇文章。如果我找到答案,我当然会更新的帖子

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-11 09:32:52

我和你有同样的问题,我还在努力解决它,但是我注意到我们的代码有一些不同,所以分享它可能是有用的。

我使用的是TF 2.7.0,当使用以下内容时,转换工作得很好:

代码语言:javascript
运行
复制
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS, tf.lite.OpsSet.TFLITE_BUILTINS_INT8]

无论如何,据我所知,使用这些选项(正如您提到的)并不能保证模型的充分量化;因此,您很可能无法像Google那样将其完全部署在微控制器或TPU系统上。

在使用正式指南推荐的转换选项以实现完全量化时:

代码语言:javascript
运行
复制
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] 

转换失败。

我最近成功地解决了这个问题!在配置转换器时,需要添加额外的代码行:

代码语言:javascript
运行
复制
converter.target_spec.supported_types = [tf.int8]

下面是我所遵循的教程的链接:tf2.ipynb#scrollTo=EBRDh9SZVBX1

票数 1
EN

Stack Overflow用户

发布于 2021-09-27 12:05:32

如果可能,您可以尝试修改LSTM,以便将其转换为TFLite的融合LSTM运算符。https://www.tensorflow.org/lite/convert/rnn支持基本融合LSTM和UnidirectionalSequenceLSTM算子的全整数量化.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69270295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档