【图像分类】如何转化模型文件

场景文字识别

图像相比文字能够提供更加生动、容易理解及更具艺术感的信息,是人们转递与交换信息的重要来源。图像分类是根据图像的语义信息对不同类别图像进行区分,是计算机视觉中重要的基础问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础,在许多领域都有着广泛的应用。如:安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。

在图像分类任务中,我们向大家介绍如何训练AlexNet、VGG、GoogLeNet、ResNet、Inception-v4、Inception-Resnet-V2和Xception模型。同时提供了能够将Caffe或TensorFlow训练好的模型文件转换为PaddlePaddle模型文件的模型转换工具。

Part1

将Caffe模型文件转换为

PaddlePaddle模型文件

| 使用说明

caffe2paddle.py提供了将Caffe训练的模型转换为PaddlePaddle可使用的模型的接口ModelConverter,其封装了图像领域常用的Convolution、BatchNorm等layer的转换函数,可以完成VGG、ResNet等常用模型的转换。模型转换的基本过程是:基于Caffe的Python API加载模型并依次获取每一个layer的信息,将其中的参数根据layer类型与PaddlePaddle适配后序列化保存(对于Pooling等无需训练的layer不做处理),输出可以直接为PaddlePaddle的Python API加载使用的模型文件。

可以按如下方法使用ModelConverter接口:

# 定义以下变量为相应的文件路径和文件名

caffe_model_file = "./ResNet-50-deploy.prototxt"

# Caffe网络配置文件的路径

caffe_pretrained_file = "./ResNet-50-model.caffemodel"

# Caffe模型文件的路径

paddle_tar_name = "Paddle_ResNet50.tar.gz"

# 输出的Paddle模型的文件名

# 初始化,从指定文件加载模型

converter = ModelConverter(caffe_model_file=caffe_model_file,

caffe_pretrained_file=caffe_pretrained_file,

paddle_tar_name=paddle_tar_name)

# 进行模型转换

converter.convert()

caffe2paddle.py中已提供以上步骤,修改其中文件相关变量的值后执行python caffe2paddle.py即可完成模型转换。此外,为辅助验证转换结果,ModelConverter中封装了使用Caffe API预测的接口caffe_predict,使用如下所示,将会打印按类别概率排序的(类别id, 概率)的列表:

# img为图片路径,mean_file为图像均值文件的路径

converter.caffe_predict(img="./cat.jpg", mean_file="./imagenet/ilsvrc_2012_mean.npy")

需要注意,在模型转换时会对layer的参数进行命名,这里默认使用PaddlePaddle中默认的layer和参数命名规则:以wrap_name_default中的值和该layer类型的调用计数构造layer name,并以此为前缀构造参数名,比如第一个InnerProduct层(相应转换函数说明见下方)的bias参数将被命名为___fc_layer_0__.wbias。

# 对InnerProduct层的参数进行转换,使用name值构造对应layer的参数名

# wrap_name_default设置默认name值为fc_layer

@wrap_name_default("fc_layer")

def convert_InnerProduct_layer(self, params, name=None)

为此,在验证和使用转换得到的模型时,编写PaddlePaddle网络配置无需指定layer name并且要保证和Caffe端模型使用同样的拓扑顺序,尤其是对于ResNet这种有分支的网络结构,要保证两分支在PaddlePaddle和Caffe中先后顺序一致,这样才能够使得模型参数正确加载。

如果不希望使用默认的命名,并且在PaddlePaddle网络配置中指定了layer name,可以建立Caffe和PaddlePaddle网络配置间layer name对应关系的dict并在调用ModelConverter.convert时作为name_map的值传入,这样在命名保存layer中的参数时将使用相应的layer name,不受拓扑顺序的影响。另外这里只针对Caffe网络配置中Convolution、InnerProduct和BatchNorm类别的layer建立name_map即可(一方面,对于Pooling等无需训练的layer不需要保存,故这里没有提供转换接口;另一方面,对于Caffe中的Scale类别的layer,由于Caffe和PaddlePaddle在实现上的一些差别,PaddlePaddle中的batch_norm层是BatchNorm和Scale层的复合,故这里对Scale进行了特殊处理)。

Part2

将TensorFlow模型文件转换为

PaddlePaddle模型文件

|1.使用说明

tf2paddle.py脚本中的工具类TFModelConverter实现了将TensorFlow训练好的模型文件转换为PaddlePaddle可加载的模型文件。目前能够支持图像领域常用的:卷积(Convolution)层、Batch Normalization层和全连接(Full Connection)层。图像领域常用的 ResNet VGG 网络都以这些层此为基础,使用TensorFlow训练的ResNet和VGG模型能够被转换为PaddlePaddle可加载的模型,进一步用于预训练或是预测服务的开发等。

模型转换的基本流程是:

  1. 将TensorFlow模型等价地使用PaddlePaddle Python API接口进行改写。
  2. 在TensorFlow中可学习参数用 Variable 表示,基于TensorFlow的Python API获取网络中的 Variable。
  3. 确定TensorFlow模型中Variable与PaddlePaddle中paddle.layer的可学习参数的对应关系。
  4. 对TensorFlow中的Variable进行一定的适配(详见下文),转化为PaddlePaddle中的参数存储格式并进行序列化保存。

|2. 需要遵守的约定

为使TensorFlow模型中的Variable能够正确对应到paddle.layer中的可学习参数,目前版本在使用时有如下约束需要遵守:

  • 目前仅支持将TensorFlow中 conv2d,batchnorm,fc这三种带有可学习Variable的Operator训练出的参数向PaddlePaddle模型参数转换。
  • TensorFlow网络配置中同一Operator内的Variable属于相同的scope,以此为依据将Variable划分到不同的paddle.layer。
  • conv2d、batchnorm、fc的scope需分别包含conv、bn、fc,以此获取对应paddle.layer的类型。也可以通过为TFModelConverter传入layer_type_map的dict,将scope映射到对应的paddle.layer的type来规避此项约束。
  • conv2d、fc中Variable的顺序为:先可学习Weight后Bias;batchnorm中Variable的顺序为:scale、shift、mean、var,请注意参数存储的顺序将Variable对应到paddle.layer.batch_norm相应位置的参数。
  • TensorFlow网络拓扑顺序需和PaddlePaddle网络拓扑顺序一致,尤其注意网络包含分支结构时分支定义的先后顺序,如ResNet的bottleneck模块中两分支定义的先后顺序。这是针对模型转换和PaddlePaddle网络配置均使用PaddlePaddle默认参数命名的情况,此时将根据拓扑顺序进行参数命名。
  • 若PaddlePaddle网络配置中需要通过调用param_attr=paddle.attr.Param(name="XX"))显示地设置可学习参数名字,这时可通过为TFModelConverter传入layer_name_map或param_name_map字典(类型为Python dict),在模型转换时将Variable的名字映射为所对应的paddle.layer.XX中可学习参数的名字。
  • 要求提供build_model接口以从此构建TensorFlow网络,加载模型并返回session。可参照如下示例进行编写:

def build_model():

build_graph()

sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))

sess.run(tf.tables_initializer())

saver = tf.train.Saver()

saver.restore(sess, 'model/model.ckpt')

return sess

按照以上原则操作后,tf2paddle.py 脚本的main函数提供了一个调用示例,将TensorFlow训练的ResNet50模型转换为PaddlePaddle可加载模型。若要对其它各种自定义的模型进行转换,只需修改相关变量的值,在终端执行python tf2paddle.py即可。

下面是一个简单的调用示例:

# 定义相关变量

tf_net = "TF_ResNet50"

# 提供build_model的module名

paddle_tar_name = "Paddle_ResNet50.tar.gz"

# 输出的Paddle模型的文件名

# 初始化并加载模型

converter = TFModelConverter(tf_net=tf_net,

paddle_tar_name=paddle_tar_name)

# 进行模型转换

converter.convert()

|3. 注意事项

  • 由于TensorFlow中的padding机制较为特殊,在编写PaddlePaddle网络配置时,对paddle.layer.conv这种需要padding的层可能需要推算size后在paddle.layer.conv外使用paddle.layer.pad进行padding。
  • 与TensorFlow图像输入多使用NHWC的数据组织格式有所不同,PaddlePaddle按照NCHW的格式组织图像输入数据。

原文发布于微信公众号 - PaddlePaddle(PaddleOpenSource)

原文发表时间:2018-03-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mathor

LeetCode258. 各位相加

 ab = (a*10+b)  ab%9 = (a*9+a+b)%9 = (a+b)%9  abc = (a*100+b*10+c)  abc%9 = ...

1061
来自专栏云时之间

深度学习与TensorFlow:VGG论文复现

3508
来自专栏杨熹的专栏

TensorFlow-2: 用 CNN 识别数字

---- 本文结构: CNN 建立模型 code ---- 昨天只是用了简单的 softmax 做数字识别,准确率为 92%,这个太低了,今天用 CNN 来提高...

3605
来自专栏ACM算法日常

第五篇:《机器学习之逻辑回归(下)》

https://pan.baidu.com/s/1tnMHvLWB_qXyuoPiBgnhaQ

923
来自专栏杨熹的专栏

TensorFlow -2: 用 CNN 识别数字

昨天只是用了简单的 softmax 做数字识别,准确率为 92%,这个太低了,今天用 CNN 来提高一下准确率。关于 CNN,可以看这篇:图解何为CNN简单看一...

1.6K0
来自专栏人工智能LeadAI

构建并用 TensorFlow Serving 部署 Wide & Deep 模型

4926
来自专栏Jack-Cui

Caffe学习笔记(一):CIFRA-10在Caffe上进行训练学习

运行平台:Ubuntu14.04     安装完Caffe后,如何开始学习Caffe呢?一个不错的方法就是从Caffe自带的examples开始学起。在caff...

3137
来自专栏李智的专栏

Deep learning基于theano的keras学习笔记(0)-keras常用的代码

这里不推荐使用pickle或cPickle来保存Keras模型。 1. 一般使用model.save(filepath)将Keras模型和权重保存在一个HD...

961
来自专栏PaddlePaddle

【FAQ】参数设置相关问题汇总

在使用指南的最后一部分,我们汇总了使用PaddlePaddle过程中的常见问题,本部分推文目录如下: 2.22:【FAQ】模型配置相关问题汇总 2.23:【FA...

4106
来自专栏机器之心

教程 | TensorEditor :一个小白都能快速玩转的神经网络搭建工具

2136

扫码关注云+社区

领取腾讯云代金券