chun2495 发表于 2020-10-13 15:12:51

【人工智能 图像分割 原创首发】第六章 将pb模型转换到移动端

本帖最后由 chun2495 于 2020-10-13 15:14 编辑

这一章就是将如何将已经训练好的网络进行固化,并采用apple公司提供的工具转换为iphone可以识别的网络。
因为之前一直用的deeplab是1.13.x,这个版本不被apple支持,所以这里需要重新建立一个环境。

1. 需要新建一个虚拟环境,因为官网(https://coremltools.readme.io/docs/what-are-coreml-tools)要求tensorflow必须大于1.14.0或者大于2.1.0。

首先在cmd中创建虚拟环境 
conda create -n tf1.14.0 python=3.6.4

然后激活
conda activate tf1.14.0

依次安装以下deeplabv3需要的库,因为后面需要在tensorflow1.14.0中训练deeplab v3网络。前面四步是安装deeplab需要的库,最后一行是安装tensorflow1.14.0。
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install Jupyter notebook -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install Matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install tensorflow==1.14.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

最后一步安装官网指导(https://coremltools.readme.io/docs/installation),安装转换工具coremltools。
pip install coremltools==4.0b3 -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 安装deeplab,并配置环境训练。

拷贝一份之前下载的deeplab。


打开anconda,选择刚才新建的环境tf1.14.0。然后打开PyCharm,选择到上一步的deeplab目录。


打开pycharm的终端,发现默认的环境还是在之前的deeplab里,当然也可以直接用conda activate tf1.14.0来激活新环境,但是切换一个shell,又得重新配置,而且新建的shell没办法切换环境,非常麻烦。所以我们需要配置一个新环境。按照下图箭头来更改就行了,因为我已经建好了,所以下划线那个需要改为envs/tf1.14.0。


3. 然后就是deeplab进行训练,这一步在我另一篇文章中介绍了,最后生成的为xxx.pb文件。这就是转换需要的文件了。

4. 新建一个shell,输入以下代码,运行后就生成了mlmodel。


5 转换代码如下:
import tensorflow as tf
import coremltools as ct

print("tensorflow: ", tf.__version__)#输出tensorflow版本,只能在tf1.14.0以上来转换模型。

image_wide = 400
image_high = 320
pbpath = "./exp/mydata_train/export/frozen_inference_graph_16358.pb"#输入的.pb模型
mlpath = "./exp/mydata_train/export/MobileNetV2.mlmodel"#输出的.mlmodel模型

image_input = ct.ImageType(shape=(1, image_high, image_wide, 3,))#输入图像的类型

model = ct.convert(
    pbpath, source="tensorflow", inputs=, outputs=["SemanticPredictions:0"],
)

# model.input_description["image_input"] = "Input image to be classified"#输入不需要描述,根据输入图像自动描述。
model.output_description["SemanticPredictions:0"] = "预测膀胱图像,图像大小和输入图像一致,输出宽度*高度的点阵,数值为1或0"
model.author = "chun"
model.license = "none"
model.short_description = "Detect Bladder"
model.version = "1.0"

model.save(mlpath)


6. 对于输入输出的参数的确定需要再编写一个.py,来获取自己模型的信息。代码如下:

import tensorflow as tf
from tensorflow.core.framework import graph_pb2
import operator
import sys

pbpath = "./exp/mydata_train/export/frozen_inference_graph_16358.pb"
infopath = "./exp/mydata_train/export/pb-info.txt"


def inspect(model_pb, output_txt_file):
    graph_def = graph_pb2.GraphDef()
    with open(model_pb, "rb") as f:
      graph_def.ParseFromString(f.read())

    tf.import_graph_def(graph_def)

    sess = tf.Session()
    OPS = sess.graph.get_operations()

    ops_dict = {}

    sys.stdout = open(output_txt_file, 'w')
    for i, op in enumerate(OPS):
      print(
            '---------------------------------------------------------------------------------------------------------------------------------------------')
      print("{}: op name = {}, op type = ( {} ), inputs = {}, outputs = {}".format(i, op.name, op.type, ", ".join(
            ), ", ".join()))
      print('@input shapes:')
      for x in op.inputs:
            print("name = {} : {}".format(x.name, x.get_shape()))
      print('@output shapes:')
      for x in op.outputs:
            print("name = {} : {}".format(x.name, x.get_shape()))
      if op.type in ops_dict:
            ops_dict += 1
      else:
            ops_dict = 1

    print(
      '---------------------------------------------------------------------------------------------------------------------------------------------')
    sorted_ops_count = sorted(ops_dict.items(), key=operator.itemgetter(1))
    print('OPS counts:')
    for i in sorted_ops_count:
      print("{} : {}".format(i, i))


if __name__ == "__main__":
    # 生成网络结构文件,可以通过这个文件查看你需要的输入和输出
    inspect(pbpath, infopath)
    # 转换成CoreML model
    # pbtomlmodel.convert()
    # 规范化CoreML model的输入输出名
    # tool.rename_var()


生成的文件为pb-info.txt,这里面存储了所有节点名称以及张量tensor,我们需要用的只是输出的节点名称,在最后可以看到输出名称为“SemanticPredictions:0”import那些不用管。
1035: op name = import/SemanticPredictions, op type = ( Identity ), inputs = import/Cast_2:0, outputs = import/SemanticPredictions:0
@input shapes:
name = import/Cast_2:0 : (1, ?, ?)
@output shapes:
name = import/SemanticPredictions:0 : (1, ?, ?)

至此,模型转换完毕。
其实这一章是把前面第二章建立的环境重新建了一遍。然后就是生成了.mlmodel。下一节开始使用这个模型进行实战测试。

天荒 发表于 2020-10-13 15:18:11

一脸懵逼,二脸懵逼。

ackyee 发表于 2020-10-13 15:26:15

配点效果图吧否则懵逼路上你和我

chun2495 发表于 2020-10-13 15:28:00

ackyee 发表于 2020-10-13 15:26
配点效果图吧否则懵逼路上你和我

下一节就有效果图了
页: [1]
查看完整版本: 【人工智能 图像分割 原创首发】第六章 将pb模型转换到移动端