导航菜单

飞桨上线万能转换小工具,教你玩转TensorFlow、Caffe等模型迁移

百度推出PaddlePaddle后,许多开发者开始转向国内的深入学习框架。但是代码的转换很容易。重写以前的工作是不现实的。数千行代码的手动转换相当于进行二次开发。

现在,有一个好消息:caffe、tensorflow和onnx可以很容易地迁移到飞桨平台。虽然pytorch模型目前还没有直接迁移,但pytorch本身支持导出到onnx模型,这相当于间接支持平台。

然而,有些人仍然有疑问:不同框架之间的api有什么区别吗?整个迁移过程是如何操作的,步骤是如何复杂的?如何保证偏移后的精度损失在可接受范围内?

每个人都会考虑很多问题,总结起来,还有更多的问题,只不过是以下几点:

1。api差异:模型的实现是如何迁移的,不同框架之间的api是否不同?如何避免这些差异造成的模型效应差异?

2。模型文件差异:如何迁移训练过的模型文件?如何保证转换后的精度损失在可接受范围内?

三。预测方法的差异:转换后的模型如何预测?转换前的预测效果和模型有什么不同?

飞行桨叶开发了一个新的功能模块x2桨叶(github见参考文献1),它可以支持主流的深度学习框架模型向飞行桨叶的转换,包括caffe、tensorflow、onnx等直接转换为桨叶流体可加载模型。发音模式。它还提供了三大框架之间的api比较,使得我们可以在直接复制模型时比较api之间的差异,并深入了解api的实现,减少模型迁移带来的损失。

以张量流转换为桨流模型为例,说明如何实现模型的偏移。

Tensorflow流体的API差异

在开始深入学习的过程中,每个人都熟悉手写数字识别演示。下面是实现手写数字识别的最简单代码:

在这段代码中,第一步是导入mnist数据集,然后设置一个占位符x来表示输入的图像数据,然后分别设置两个变量w和b来表示要计算的权重和偏移量,最后由softmax计算输出的y值,我们的实际label是变量y。

在前向传播完成后,可以计算预测值y和标签y之间的交叉熵。

然后选择合适的优化函数,在这里对梯度进行降阶,最后开始一个会话,将数据填充到批中,计算acc得到精度。

这是一个非常简单的代码。如果我们想把这个代码变成一个飞行桨代码,有人可能会认为这是非常麻烦的。每个实现api都会经过相应的实现,但在这里我可以告诉大家,不!使用!这个!什么!妈妈!烦人的!因为在X2pDLE中有一个与流体API表相对应的常用的TysFooFund,( /X2Pald/Trime/Mealth/TysFrace2Fix/doc)如下所示:

对于常用的TensorFlow API,有一个相应的飞桨接口。如果两者的功能没有区别,则会标记该功能。如果实现或支持的功能和参数不同,则会标记差异。并详细说明。

例如,在上面非常简单的代码中,这些TensorFlow API出现:

在这些apis的出现中,大多数函数是一致的,只有两个函数是不同的,分别是tf.placeholder和tf.nn.softmax_cross_entropy_with_logits,分别对应于fluid.layers.data和fluid.layers.softmax_with_cross_entropy。看看具体的差异:

Tf.placeholder V.S fluid.layers.data

使用TensorFlow的学生熟悉占位符。中文翻译是占位符。你什么意思?在TensorFlow 2.0之前,它是静态图的设计理念。整个设计理念是计算流程图。编写程序时,首先构建整个系统。图,代码没有直接生效,这不同于Python的其他数值计算库(如Numpy等),图是静态的,在实际运行时,启动一个会话,程序实际上会运行。这样做的好处是避免重复切换底层程序实际运行的上下文,tensorflow可以帮助您优化整个系统的代码。我们知道许多Python程序的底层是C语言或其他语言。要执行脚本,您需要切换一次。需要付费。 Tensorflow可以通过计算流程图来帮助您优化需要在整个会话中执行的代码。

在代码级别,每个张量值都是图表上的op。当我们将列车数据划分为minibatch然后将其发送到网络进行培训时,每个小批量将是一个操作,在这种情况下,在一对图表上。操作太多了,也会产生巨大的开销;所以有tf.placeholder,我们每次都可以将一个小批量传递给x=tf.placeholder(tf.float32,[None,32]),下次传入的x替换最后传递的x,这样只生成一个op对于所有传入的minibatch x,并且不生成额外的操作,这减少了图的开销。

参数比较

Tf.placeholder

桨叶.流体.层.数据

从图中可以看出,飞桨的api参数较多,具体区别如下:

·批量尺寸加工

TensorFlow:要求用户为形状中的批次维度指定None;

飞桨:将第一个维度设置为-1以指示批次维度;如果第一个维度为正,则默认情况下批次维度插入到开头。要避免批处理维度,请将参数append_batch_size设置为false。

·坡度是否返回?

TensorFlow和Pythorch都支持输入梯度,stop_gradient=false可以直接在飞行桨中设置。如果在某一层使用stop_gradient=true,则该层之前的层将自动stop_gradient=true,该gradient将不参与返回,一些不需要参与损失计算的信息可以设置为stop_gradient=true。对于具有batchnormalization层的cnn网络,梯度也可以应用于输入,例如

tf.nn.softmax_cross_entropy_with_logits v.s

流体.层.带交叉熵的softmax

参数比较

Paddle.fluid.layers.softmax_with_cross_entropy

功能差异

标签类型

TensorFlow:标签只能使用软标签,其形状为[batch,num_classes],表示每个类别中样本的概率分布;

飞桨:通过设置soft_label,您可以选择软标签或硬标签。使用硬标签时,标签的形状为[batch,1],dtype为int64;使用软标签时,形状为[batch,num_classes],dtype为int64。

返回值

TensorFlow:返回批处理中每个样本的日志丢失;

飞桨:当return_softmax为False时,它会批量返回每个样品的对数损失;当return_softmax为True时,它返回logtis的标准化值。

问题点?

硬标签,单热标签,每个样品只能分为一个类别

软标签,每个样本可以分配到多个类别

Numeric_stable_mode:这个参数是什么?指示是否使用具有更好数学稳定性的算法的标志。它仅在soft_label为False的GPU模式下生效。如果soft_label为True或执行位置为CPU,则算法始终在数学上稳定。请注意,使用稳定算法时速度可能会变慢。默认值为True。

Return_softmax:指示是否返回附加softmax值并返回交叉熵计算的结果。默认值为False。

如果return_softmax为False,则返回交叉熵损失

如果return_softmax为True,则返回元组(loss,softmax),其中交叉熵损失是[N x 1]形式的二维张量,softmax是[N x K] <的二维张量/p>

代码示例

因此,通过API映射表,我们可以直接将TensorFlow代码转换为Paddle Fluid代码。但是如果项目现在在线,代码是几千行甚至几万行,或者已经训练了可预测的模型。如果您想直接转换API,这是一个非常耗时且劳动密集的事情。有办法吗?将经过训练的可预测模型直接转换为另一个框架,只要转换后的损失精度在可接受的范围内,就可以直接替换。我们来谈谈训练模型的迁移方式。

模型迁移

VGG_16是CV领域的经典模型。我在tensorflow/models下使用VGG_16作为示例来说明如何将TensorFlow训练模型转换为飞桨模型。

下载预训练模型

提取下载的压缩文件

将模型保存为检查点格式

TensorFlow2fluid目前支持检查点格式模型或序列化网络结构和参数的pb格式模型。下载的vgg_16.ckpt只存储模型参数,因此我们需要重新加载参数并将网络结构和参数一起保存为检查点。模型

将模型转换为飞桨模型

注意:某些OP需要在转换时将参数写入文件,或运行tensorflow模型进行推断以获得张量值。在这两种情况下,IO或计算都需要一定的时间。对于后一种情况,

打印出日志信息(拦截部分)

此时,我们已将tensorflow/models下的vgg16模型转换为Paddle Fluid模型。转换模型和原始模型的准确性是否有任何损失?怎么预测呢?我们来看看以下内容。

预测结果的差异

加载转换的飞桨模型并进行预测

在上一步中转换的模型目录名为“paddle_model”。这里我们通过ml.ModelLoader加载模型。请注意,转换的飞桨模型的输出格式从NHWC转换为NCHW,因此我们需要转向输入数据。组。处理完数据后,您可以使用model.inference进行预测。具体代码如下:

对比模型丢失

转换模型存在一个无法避免的问题,即从Tesorflow模型到Paddle Fluid模型的损失。如果模型的精度损失太大,那么转换模型实际上没有意义,只有损失的准确性在我们可接受的范围内。在内部,模型转换可以在实践中应用。在这里,您可以通过加载两个模型文件找到numpy.fabs的两个模型结果之间的差异。

打印

要注意的要点

1.转换后的模型需要注意输入格式。飞桨中的输入格式必须为NCHW格式。

在这种情况下,不涉及输入中间层,例如卷积层的输出。需要理解的是飞行螺旋桨中的卷积层输出。卷积核的形状与TensorFlow不同。

2.转换模型后,检查转换前后模型的差异,以及需要测试的最大差异是否满足转换要求。

总结

X2Paddle提供了一种非常方便的转换方式,因此您可以直接将训练过的模型转换为Paddle Fluid版本。

转换模型最初需要通过API比较表直接重新实现代码。然而,在实际生产过程中操作非常麻烦,甚至需要二次开发。

如果有一个可以轻松转换模型的新框架,快速运行调试并迭代结果,为什么不呢?

虽然飞桨比其他AI平台晚,但使用X2Paddle小工具,它可以快速吸引AI开发人员到他们自己的平台,随后的优势将变得更加明显。

除了本文中提到的tensoflow2流体,Paddle Fluid还支持caffe2fluid和onnx2fluid。您可以根据自己的需要体验它。如果您有任何疑问,请留言

参考文献:

1. X2Paddle Github:

2. tensorflow2fluid:

——