发新帖

tensorflowLite的量化使用问题

[复制链接]
17735 91

快来加入 TensorFlowers 大家庭!

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
我想问下,现在很多企业都说使用了tensorflow lite,但他们使用的tensorflow lite是经过量化的吗?因为现在好多操作都不支持量化操作,比如tf.Abs,tf.tf.Square等等.如果是使用未量化的tensorflow lite,那这样速度比起量化后的pb文件在android手机上使用,速度有提高吗?提高多少?        还有一个问题.就是要使用toco工具生成量化的lite文件,是不是要求在训练过程中得先使用tf.contrib.quantize.create_training_graph和tf.contrib.quantize.create_eval_graph()进行伪量化训练?
麻烦各位大佬解答下.有没有大佬量化自己模型真正测试成功过的,回答下疑惑.或者能写下量化具体步骤教程.这还有一个我的相同的贴,可以一并回答tensorflowLite的量化使用问题https://www.tensorflowers.cn/t/7100
(出处: TensorFlow中文开发者社区)


我知道答案 回答被采纳将会获得10 金币 + 50 金币 已有91人回答
已有1人评分金币 理由
段德璋 + 27

查看全部评分 总评分:金币 +27 

本楼点评(1) 收起
  • 大当家tzp我实现tflite量化后,pc上跑结果是,遇到了情况,就是relu层不支持uint8得计算,请问有什么方法可以跑得时候,把tflite这一层设到浮点上计算。错误message是:
    RuntimeError: Only float32 is supported currently, got UINT8.Node number 28 (RELU) failed to invoke.
    2019-10-30 12:44 回复

精彩评论91

Zongjun  TF豆豆  发表于 2018-10-24 05:38:19 | 显示全部楼层
本帖最后由 Zongjun 于 2019-4-20 02:19 编辑

以下是我的个人理解,如果是在android 上,Tensorflow Lite (tflite) 可以利用hardware accelerator,应该是更快的。量化只是一个float32到uint8的过程,本质上是weights\bias大小的变化(是原来的25%),有的microcontroller太小,不量化根本就放不进去,并且mircocontroller大部分是8bit计算,float32非常昂贵,所以需要量化。
用toco生成的量化有两个途径:1.你提到的伪量化,这个确实在training时要调用你说的这两句。具体展开:要生成两个graph,一个用于training,在compute gradients前使用create_training_graph,因为forward和backward都需要模拟量化。这个过程其实是找到需要量化的变量,插入fake quantization nodes 来记录 min-max range information。再具体一点:见(*)。另一个graph用于eval,要在import_graph_def后,saver.restore前插入create_eval_graph。后面如何freeze如何调用toco,按照这个链接上说的即可:https://github.com/tensorflow/te ... ow/contrib/quantize
2. post-training quantization。顾名思义,无需伪量化,是toco拿过来一个pb file,直接把toco的post-training quantization flag设成true完成的。但是注意,这个方法只quantize weights,而1.是一个fully quantized model. 并且2.在inference时,会把uint8的weights再转换回float32来做矩阵乘法。所以,2.这个方法其实依然相当于没做quantization。它的存在应当只是便于用户转移model,计算时依然是个非量化model。链接:https://www.tensorflow.org/performance/post_training_quantization

(*):再往前几个版本,tensorflow其实有自己的量化,就叫做quantize。他不是用伪量化,也无需tflite介入。这个文件在现在的tensorflow github中已经不存在了(半个月前移除的,pete warden决心只搞tflite了)。但是他很好的解释了tensorlow 和 tflite量化的数学原理。如果不加入上述的fake quantize node,tensorflow quantize则需要requantize和dequantize的过程。其中requantize是必须的,因为8bit的两个整数相乘为16bit的数。int8的两个矩阵相乘会得出一个32bit的结果,即一个2d convolution layer的输出结果是int32的。但是下一个quantized op需要一个8bit的输入,这就需要记录float32的min 和max,从而对这个int32的中间结果进行requantization,重新获得8bit的数据继续往下传。当使用了fake quantization后,上述过程在训练过程中被模拟了。于是你会看到训练完了的图,不再存在requantization node和dequantization node。有的只是那些fake quantization nodes。值得注意的是,不加伪量化的量化,不是fully quantized model,因为其涉及到了利用float32 min和max转换。而伪量化不存在该问题。简言之,目前唯一可行的fully quantization method就是在tensorflow 下伪量化训练,再到tflite上转化。
(另外,之前还有一个做移动端的方法,即tensorflow mobile。但是它会在 early 2019 deprecate (应该是被tensorflow lite取代),如图:)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
本楼点评(17) 收起
  • OnceJune您好,请教一个问题,我在使用create_training_graph的时候,出现了Cannot use '%s' as input to '%s' because '%s' is in a while loop.这样的错。想请教一下在加fake quant node的时候,对于op的操作上面会和不加有什么区别吗?同样的结构直接训练是可以一路训通的。
    2019-1-29 18:51 回复
  • Zongjun回复 OnceJune :如果用的是底层tensorflow的api, ops比如conv2d这些layer,它们的写法和以前没有不同。只是在定义loss之后和定义optimizer之前加入create_training_graph()即可。这个函数会自动识别一些常用的op,然后训练时在这些op之前插入fake quant node。这个还和你Model的具体结构有关,比如rcnn有的op就不会被自动识别,需要手动插入fake quant nodes。
    你的这个报错我没有遇见过,估计是model结构不同吧。
    2019-1-30 02:02 回复
  • OnceJune回复 Zongjun :您好,感谢回答。我实际上是想对tacotron2的模型做量化,但是while op好像不被支持。手动插入fake quant nodes这块是在调用create_training_graph之前来操作吗?还是完全重新实现一套插入fake quant nodes的逻辑?或者说我可不可以通过某种方式在CheckInputFromValidContext这一步跳过不被支持的op呢?
    2019-2-1 18:05 回复
  • Zongjun回复 OnceJune :果然是模型的问题。tacotron2是不是还有LSTM的部分啊?这一部分官方的说法是自动插入fake quant nodes还没做到这一步。所以你除了create_training_graph之外(这个部分保留),还要在你定义graph的时候手动插入fake quant nodes。
    还有一种方法,和quantization aware training完全不同了。那就是用Tensorflow自带的 Graph Transform Tool. 链接: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms 重点看一下"Shrinking File Size"这里。还有这个链接:https://github.com/tensorflow/tensorflow/issues/7949,这个是有人问怎么量化LSTM(LSTM是不能自动识别添加fake quant node的),你看一下pete warden的官方回答。
    量化这方面,我的模型一直是自动插入fake quant node的,所以我也只能给这些建议了。希望能帮到你一丢丢哈。Good Luck!
    2019-2-2 06:22 回复
  • OnceJune回复 Zongjun :手动插入fake quant nodes的话是要完全抛弃create_training_graph()是吗?然后eval的时候再把手动插入的也手动删除?我看到有FakeQuantWithMinMaxArgs这个方法,具体操作是通过它来逐层修改还是要到更底层的地方啊?另外GraphTransform这个我也尝试过,模型的size确实和预期一样减小,但是本地运行的速度在avx2指令集下反而是慢了的,我理解这里也是一个fake quant吧,所以可能norm/denorm的运算开销冲抵了8bit带来的提升。
    2019-2-2 16:45 回复
  • Zongjun回复 OnceJune :手动插入我没用过,但是我觉得首先可以尝试保留create_training_graph()和create_eval_graph()。在它们无法检测到的层的地方手动加入fake quant node。看看会不会在create_eval_graph()的时候把所有的fake quant node都自动处理,不行的话再尝试手动删除。
    graph transform应该不是fake quant。所谓fake quant其本质是quantization-aware training,是train的过程中模拟量化。graph transform是你拿着一个训练好的模型给它,它再进行处理。读一下graph transform的Eight-bit Calculations部分,它上面也说了:on many platforms the quantized code may actually be slower than the float equivalents, but this is a way of increasing performance substantially when all the circumstances are right. 下面一段简单讲了一下怎么手动插入fake quant node。这一部分其实就是在说,如果想真正做到fully quantization,那就需要fake quant node,训练时就train好min 和 max,然后用它说的那个指令量化。但是这个看上去又和fake quantization之后在用tensorflow lite fully quanitze并没有什么区别。具体实现要看底层代码了。
    综上,只要你想fully quantize一个模型,那就必须手动插入fake quant node去训练。我建议你先放一放graph transform,手动插入训练成功以后直接用tensorflow lite转化试试。
    2019-2-5 02:09 回复
  • OnceJune回复 Zongjun :看了一下,确实是好简略一段啊……A full guide to optimizing for quantization is beyond the scope of this guide, but one thing that can help is using the FakeQuantWithMinMaxVars op after Conv2D or similar operations during training. This trains the min/max variables that control the range used for quantization, so that the range doesn't have to be calculated dynamically by RequantizationRange during inference.我改改建图的脚本试试吧。多谢回答~~
    2019-2-11 11:26 回复
  • OnceJune回复 Zongjun :今天上班又看了一下,发现有一个experimental_create_training_graph的等价方法,可以定义scope,应该可以作为一个解法。把支持的ops放在一个scope里面,不支持的比如lstm放在另一个里面,然后只transform支持的。
    2019-2-11 15:38 回复
  • Zongjun回复 OnceJune :嗯,你说的这个我也可以尝试一下哈!
    2019-2-12 03:33 回复
  • OnceJune回复 Zongjun :另外看到您下面的回复中提到了quant的论文,可以发一下链接吗?我的理解比较粗,想再看一下细节。另外tacotron我做了performance profiling,cost的大户还是在lstm上面……最后可能还得手动去做quant。
    2019-2-13 14:33 回复
Zongjun  TF豆豆  发表于 2018-11-6 08:49:44 | 显示全部楼层
对了,我补充一点,我debug的时候花了不少时间的一个地方:我用的是在linux下,安装tf.nightly,然后jupyter notebook里调用tf.lite.TFLiteConverter这个东西。因为是quantization,所以要求给出quantized_input_stats,这是一个tuple (med, std)平均值和标准差是要自己手动调的。我的是图片为输入,一开始给(128,128),结果很惨。我调来调去,最后是(128,73)给出的accuracy达到了fake quantization的效果。
本楼点评(4) 收起
  • 杨7277请教一下大神,quantized_input_stats中的mean/stddev的值的设定,有什么规律吗?如何正确 快速的接近合理的值?
    2019-4-15 16:50 回复
  • Zongjun回复 杨7277 :看这个链接:https://stackoverflow.com/questions/54261772/tensorflow-lite-toco-mean-values-std-values
    这个公式是谷歌官方的回答。
    2019-4-18 01:50 回复
  • 杨7277回复 Zongjun : 不好意思回复晚了,多谢大神的分享,我学习一下
    2019-4-25 15:43 回复
  • Zongjun回复 杨7277 :客气。这个也是我好不容易才搞来的公式。。。
    2019-4-26 00:45 回复
九幽  TF荚荚  发表于 2018-11-14 11:32:14 来自手机  | 显示全部楼层
Zongjun 发表于 2018-11-6 08:49
对了,我补充一点,我debug的时候花了不少时间的一个地方:我用的是在linux下,安装tf.nightly,然后jupyter  ...

您好,想请教您一个问题,我现在参照着官方的mobilenet训练例子在mnist里面加入了伪量化训练代码,但只加了Create_training_graph那部分,然后跑出了模型,但是在用工具转化tflite的时候,报错说不知道FakeQuantWithMinMaxVars的数据类型,这个是不是我训练的时候代码写错了?
我看了官方的两篇论文,还有各种社区的各种问题,但还是不确定步骤对不对,您是怎么做的怎么找的资料啊?还有什么我可以找的资料吗?或者您能把你的例子给我看一下吗?非常感谢~
本楼点评(0) 收起
Zongjun  TF豆豆  发表于 2018-11-15 06:19:41 | 显示全部楼层
本帖最后由 Zongjun 于 2018-11-15 06:42 编辑
九幽 发表于 2018-11-14 11:32
您好,想请教您一个问题,我现在参照着官方的mobilenet训练例子在mnist里面加入了伪量化训练代码,但只加 ...

首先,我记得官方的mobilenet是用slim写的吧?slim我没用过,但是fake quantization本质应该是一样的。
我下面写的是用纯tensorflow(非slim)做fake quantization:

1. 你的一个明显错误是,没有使用create_eval_graph。你要创建两个graph,一个只用来training,在这个graph上使用create_training_graph(). 另一个graph,只用来inference,在这个graph上使用create_eval_graph(). 最后,Freeze这个用来inference的graph,再把它传给toco。

2. 使用toco需要linux machine,linux比较stable。你要在这个linux machine上安装 tf.nightly 版本的tensorflow,再使用toco。(你的报错也有可能来自这一步。但是第1步是必须做的,不管用的什么版本的tensorflow。)

3. 我自己的例子不能贴出来,是公司的project。但是,谷歌有一个现成的例子,代码非常基础并且清晰。例子链接。 你打开这个目录以后,先看train.py,第157行(create_training_graph)。再去看freeze.py,第133行(create_eval_graph)。这个相当于,在freeze的文件里包含了create_eval_graph。你可以发现,create_eval_graph()上面是调用create_inference_graph()这个函数,显然,create_inference_graph这个函数重新写了一个graph,而不是用你create_training_graph的那个graph。run完freeze.py以后,生成的就是.pb文件。可以直接把这个.pb文件给toco转化了。(注意区分create_eval_graph()和create_inference_graph()。前者是现成的可以直接调用,后者是你自己写的一个普通function。)


4. 还有一个注意事项就是顺序,这个我在最开始的post里提到过了。create_training_graph,要出现在cross_entropy之后,tf.train.GradientDescentOptimizer之前。而create_eval_graph则是出现在创建完inference graph之后,load checkpoint之前。load checkpoint之后是freeze graph,freeze graph 用的是graph_util.convert_variables_to_constants()。

我就是从这个例子学会怎么做quantization-aware training的。至于谷歌官方的documentation,我实在是不敢恭维。(当然paper我也读了,更多的是从中学到背后的数学原理。)

本楼点评(20) 收起
  • 九幽嗯嗯嗯,读论文只是知道个原理,真的不知道具体怎么做的,,,我还刚开始学用tf,好多程序源码可能看了但是并不能自己总结出用法规律啥的,身边还没有人问,就在这个问题上卡了好久,,,
    经过这么多天的查找看代码啥的,我就是隐隐有些思路,知道两个create都要加,但就是不知道怎么加,果然看你说了之后,知道了这里面还是有不少坑的,是我这种小白不能看出来的,,,
    非常感谢您的回答,帮了大忙了,思路瞬间感觉清晰了,我之前也是看了您上面的回答才去找的相关资料,我之前只找到了mobilenet那个,确实里面看到了slim,我也觉得应该不是一种方法,不过也算是参考之后完成了一半的内容。
    您的回答非常清晰,十分感谢!~碰到您这样做过量化又很会讲解描述的人,我这个小白实在幸运,多谢~
    那我就不改那个错误了,先改正代码,照着您说的实现一下,希望可以完成,,再次感谢!
    2018-11-15 12:26 回复
  • 九幽看到了那个例子,演讲的那个,我之前也看到了,也照着写了,但是就是因为着急和迷惑吧,就只看了有create_training_graph的部分,其他的没分析出来,,,我继续看去,,,
    2018-11-15 12:29 回复
  • Zongjun不用客气哈。对,那个例子的create_eval_graph藏的比较深,在freeze里面,相当于两件事儿在一个文件里做。Good luck!
    2018-11-16 01:14 回复
  • 九幽回复 Zongjun :我仔细看了一下train.py和freeze.py,这两个文件一个是训练,一个是推理(验证:test)?就是在train.py里用create_training_graph()生成了训练图,然后freeze用create_inference_graph()重写了一个推理图,又用create_eval_graph()调用,生成最终的推理图?create_inference_graph()这个只是给了一个图的定义是吗?我看它做了一个output 给后面的inference,为什么要加create_inference_graph()呢?可以就直接在保存ckpt之前加上freeze.py里面create_eval_graph()那一部分吗?
    我tf语法比较差,刚接触没多久,,,只大概看懂了整体结构,但内部的关系还没太清楚,,,我做的项目是keras写的物体检测和分类训练,网络和训练是分开的,但训练里面是训练和验证一起的,结构上感觉跟speech这个例子差不多,但是speech是把训练和验证分开了是吧?
    就是训练生成.pb和.ckpt,然后验证推理的部分和frozen一起放到了freeze里是吗?我也可以把两部分放在一起是吧?就像我上面想的,不知道create_inference_graph()这个的含义,一直也不太清楚eval这部分该怎么和我之前写的训练的代码结合起来,,,
    然后我试了个简单的例子,就是mnist,它就两部分,一个是建立网络,然后就是训练,我把create_training_graph放到了建立网络里:
    ........
    finaloutput = tf.nn.softmax(tf.nn.dropout(dense_layer2, keep_prob), name="softmax")
        g = tf.get_default_graph()
        with tf.name_scope('cross_entropy'):
            cross_entropy_mean = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=finaloutput))
        tf.contrib.quantize.create_training_graph(input_graph=g,
                                                  quant_delay=0)
        optimize = tf.train.GradientDescentOptimizer(1e-5).minimize(cross_entropy_mean)
        prediction_labels = tf.argmax(finaloutput, axis=1, name="output")
        correct_prediction = tf.equal(tf.argmax(finaloutput, 1), tf.argmax(y, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    然后看你说的eval的放置位置注意,就是把eval放在第二部分的训练那里吗?因为模型保存部分在训练那里。
    还有个问题,这个eval就是生成一个推理图吗?推理图和训练图是一样的吧?只是参数不一样,结构一样?这个的作用具体是什么呢?量化推理模型?
    2018-11-19 17:43 回复
  • Zongjun回复 九幽 :freeze.py没有在做实际的testing,它只是生成了用于testing的那个graph(create_inference_graph()),它是一个图的定义。这个图将来可以用来做推理。可以理解为,训练图训练出来的参数保存在checkpoint file里,freeze.py把这些checkpoint file load了进来,传给了用来inference的这个图。这里必须create_inference_graph(),直接在训练图上调用create_eval_graph()是不对的。
    对,你也完全可以把创建推理图和freeze放在一个文件中。eval并不是生成推理图,生成推理图是create_inference_graph(),eval只是把这张推理图转换成了tflite能够识别并量化的格式。eval要出现在Load checkpoint的地方而不是save checkpoint的地方。
    2018-11-20 05:30 回复
  • Zongjun回复 九幽 :所以总结一下就是这样的:
    1.创建训练图,其中加入create_training_graph(),训练。把训练好的数据存在checkpoint file中。
    2. 创建推理图,其中加入create_eval_graph()。把训练好的数据导入推理图中,即load checkpoint。
    3. Freeze 生成.pb file.(演讲的例子把2,3合成了一个文件中做。)
    4. 在linux machine上把这个.pb file转化成.tflite file。
    5. 可以用tflite python api的 interpreter读入这个.tflite模型然后做testing.
    2018-11-20 05:40 回复
  • 九幽回复 Zongjun :恩恩,这样清晰不少了,感谢~我继续写试试~
    这些你都是通过读例子程序看出来的吗?还是程序和论文一起分析出来的,还是找到了很多相关资料呢?我看了好多还是不确定,分析不出来......
    2018-11-20 10:09 回复
  • 九幽回复 Zongjun :还有一个问题,我刚把speech的例子跑出来了,然后用toco工具转化了tflite,freeze运行出来的.pb文件是3.7M,然后toco转化出的tflite大小也是3.7M,这样对吗?还是说生成量化的tflite,是会变成pb文件的1/4?
    我用的指令,bazel的,还是说要按你的方法,下载tf.nightly写程序转化?
    我用你说的Netron工具看了转化前后的两个图,结构一样,只是转化之后出现了fused层,我觉得图应该是对的
    2018-11-20 17:52 回复
  • Zongjun回复 九幽 :对,这些操作过程完全是读这个例子的程序看出来的,我从论文获得的只是它背后的数学原理。应该是1/4,我猜你训练的时候是 python train.py。你应该是python train.py --quantize=True. 你得告诉这个网络你要求它做fake quantization啊,不然它默认是不进行伪量化的。
    2018-11-21 01:17 回复
  • Zongjun回复 九幽 :bazel完全可以用。不用非要我说的那样,我说的是针对用python的玩家们。但是即便用bazel,我也推荐用tf.nightly版本。Netron打开发现结构一样就说明你没用伪量化。fake quantization以后,你会看到.pb文件中会出现FakeQuantWithMinMaxVars node, 而.tflite中是没有的。在Netron中展开每一个node看细节,信息量很大的。我自己写过一个tensorflow的kernel,然后自己手动量化(用Paper中的公式),然后拿过来netron中显示的量化min,max,用我的function输出的结果和netron中显示的量化结果一致。证明量化成功。
    2018-11-21 01:23 回复
快到碗里来  TF豆豆  发表于 2018-11-16 18:18:56 | 显示全部楼层
Zongjun 发表于 2018-11-15 06:19
首先,我记得官方的mobilenet是用slim写的吧?slim我没用过,但是fake quantization本质应该是一样的。
我 ...

你好,我想请教下,我使用toco工具将一个冻结了的pb文件,大概4.3m,进行转换成lite文件./bazel-bin/tensorflow/contrib/lite/toco/toco \
--input_file=frozen_eval_graph_test.pb \
--output_file=tflite_model.tflite \
--input_format=TENSORFLOW_GRAPHDEF \
--output_format=TFLITE \
--inference_type=FLOAT \
--input_shape="1,626,361,3" \
--input_array=input_image \
--output_array=result  \
--std_value=127.5 --mean_value=127.5 --default_ranges_min=-1.0 --default_ranges_max=1.0

过程中,我发现,只要我模型里面存在下面这段代码relu = tf.where(tf.less(input, 0),  tf.zeros_like(input), input)或者nan_to_zero = tf.where(tf.equal(relu, relu), relu, tf.zeros_like(relu))   转换出来后的lite文件将会变成100多m,如果去掉的话出来的lite文件就正常4.3m左右 ,我问了下别人,有人说是现在tensorflow-lite的bug,里面有些操作影响到,我想问下你有没有出现过这个问题,会不会是你上面提到的tensorflow版本必须要tf.nightly版本才行,我的版本是从github上下载源码编译的2.11版本.还有一个问题就是,你安装tf.nightly版本的tensorflow是用pip install tf-nightly直接安装的吗?谢谢

本楼点评(0) 收起
Zongjun  TF豆豆  发表于 2018-11-17 01:41:34 | 显示全部楼层
快到碗里来 发表于 2018-11-16 18:18
你好,我想请教下,我使用toco工具将一个冻结了的pb文件,大概4.3m,进行转换成lite文件./bazel-bin/tensorfl ...

我是按照官方教程安装的tf.nightly,基本和你说的一样,建个环境然后pip安装。我是一个Ubuntu-16.04的虚拟机。toco我不是用的bazel,我用的是python api. 在这个tf.nightly的机器上,打开一个jupyter notebook,import tensorflow as tf之后,运行 tf.lite.TFLiteConverter.from_frozen_graph. 如果这句不报错那就是成功了。这句在python里就相当于call了toco。

我读了一下你的toco,你如果是quantization-aware training了,那你的inference type那里应该是QUANTIZED_UINT8而不是FLOAT.

relu的那个我木有碰到过,所以可能帮不上忙了。我推荐你下载Netron.可以直接打开你的.pb和.tflite文件,先看一下.pb文件是不是正常,有可能训练或者freeze的时候就出现问题了。Good luck!
本楼点评(22) 收起
  • 快到碗里来大神,你好,我测试了你说的Netron跟使用tf.lite.TFLiteConverter.from_frozen_graph去生成lite,现在基本成功,只要去除一些操作就可以生成量化的lite文件.现在还有个问题想请教下,如果模型里面存在tf.Square操作,lite文件生成就会报错,我查了下文档,里面有这么一句话不太理解,在https://www.tensorflow.org/lite/tf_ops_compatibility   里面的"Here is a list of TensorFlow operations that are usually removed from the graph",什么叫做从通常从图中移除这些操作
    2018-11-26 16:48 回复
  • Zongjun回复 快到碗里来 :这个列表里面的操作应该是toco自动去删除,替代,融合的。比如tf.relu,它可以fuse进上一层的conv2d layer中,成为上一层的输出。tf.Square应该也是一样的,toco会去处理掉,这样tflite的model中就看不到这个操作了。你报的错是啥啊?toco没有自动处理tf.Square吗?
    2018-11-27 02:02 回复
  • 快到碗里来回复 Zongjun :你好,我上面的问题基本解决了,现在我生成了一个lite文件,用python脚本测试,测试代码如下:
    interpreter = tf.contrib.lite.Interpreter(model_path="quantized_model.tflite")
    interpreter.allocate_tensors()

    # Get input and output tensors.
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()

    image=scipy.misc.imread("timg(11).jpg")
    image_=np.array([image.astype('float32')])
    print(image_.shape)
    print(type(image_))
    print(input_details)
    interpreter.set_tensor(input_details[0]['index'], image_)

    interpreter.invoke()
    output_data = interpreter.get_tensor(output_details[0]['index'])
    scipy.misc.imsave('res.jpg',output_data)
    是能顺利运行并输出东西来的,但我交给我朋友做android的在android上运行lite文件,他是替换官方的demo
      
    https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/java/demo的文件去测试,报了以下错误:
    Caused by: java.lang.IllegalArgumentException: ByteBuffer is not a valid flatbuffer model
                                                                                              at org.tensorflow.lite.NativeInterpreterWrapper.createModelWithBuffer(Native Method)
                                                                                              at org.tensorflow.lite.NativeInterpreterWrapper.<init>(NativeInterpreterWrapper.java:72)
                                                                                              at org.tensorflow.lite.NativeInterpreterWrapper.<init>(NativeInterpreterWrapper.java:52)
                                                                                              at org.tensorflow.lite.Interpreter.<init>(Interpreter.java:114)
                                                                                              at com.example.android.tflitecamerademo.ImageClassifier.<init>(ImageClassifier.java:98)
                                                                                              at com.example.android.tflitecamerademo.ImageClassifierQuantizedMobileNet.<init>(ImageClassifierQuantizedMobileNet.java:38)
                                                                                              at com.example.android.tflitecamerademo.Camera2BasicFragment.onActivityCreated(Camera2BasicFragment.java:334)
                                                                                              at android.app.Fragment.performActivityCreated(Fragment.java:2289)
    我想问下,你有没有遇到这个问题或者知道怎么解决吗?有什么好的建议或者能不能分享下你调用lite文件的android代码.谢谢大神
    2018-12-1 11:52 回复
  • Zongjun回复 快到碗里来 :我训练完的model是直接往单片机上放的,所以我没在android上用过。我看了一下你给的链接里的代码,这个报错是说bytebuffer不是一个flatbuffer model(flatbuffer model是tflite的格式)。但是,我发现bytebuffer在代码中是输入图片的一个buffer,里面存的是image data,并不是model本身。所以你同事android的java代码可能出了问题。
    2018-12-4 02:08 回复
  • 快到碗里来回复 Zongjun :好的,谢谢大神,我看下怎么处理.
    2018-12-4 18:02 回复
  • Zongjun回复 快到碗里来 :嗯嗯。不用客气!大神不敢当,只是碰巧平时工作会一些这方面的东西,尽可能帮忙而已。祝你们好运哈!
    2018-12-5 02:27 回复
  • 快到碗里来回复 Zongjun :哈哈,我觉得你有空可以写篇博客讲下tensorflow-lite,现在tensorflow-lite的博客太少了,而且都不是很详细,很多都是抄来抄去的.这段时间我都会找时间研究下tensorflow-lite,现在生成的lite文件还没能部署在android跟ios上,遇到问题到时还要请教你
    2018-12-6 15:12 回复
  • Zongjun回复 快到碗里来 :嗯嗯,模型都有了,部署在android上应该就不难了,毕竟是java哈。
    2018-12-7 02:32 回复
  • 快到碗里来回复 Zongjun :你好,这几天我终于把lite文件部署到android上,但经过测试,量化后的pb文件比量化后的lite文件速度更快,这是什么原因你知道吗?还有,就是现在官方不是说,现在tensorflow-lite只支持mobilenet及少量模型,但我们可以将我们的模型转换成lite文件,所以,我好奇的这个官方说的支持是不是指对mobilenent等这些模型进行优化,加速计算,而不是指单纯可以使用.
    2018-12-13 20:38 回复
  • Zongjun回复 快到碗里来 :具体哪些能转化成tensorflow lite不是看模型,而是看你的模型里面用的哪些op。如果有tflite不能转化的op,这个模型就不能被转化。能被tflite转化的op如下:https://www.tensorflow.org/lite/tf_ops_compatibility
    量化后的pb文件指的是有fakequant nodes但还没被toco转化的.pb文件吗?这个阶段它还是floating point的model,所以称不上是被量化了。而.tflite文件才是真正被量化了的model。你的这个速度问题,我在网上见过类似的。所以在我最一开始的回答中就避开了速度的事儿,只是分析了大小变化。因为理论上应该是量化了更快,但是涉及到android的内部实现问题,这方面我不懂,所以我不确定哪里出了问题。我能想到的是:tensorflow lite要用最新版本,就是我之前说的用tf.nightly版本的tensorflow。某些kernel(比如conv2d),新版本的tensorflow lite更高效。
    2018-12-14 05:41 回复
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

快速回复 返回顶部 返回列表