从Paddle Fluid架构重新学习PaddlePaddle

我接触飞桨框架是在2019年年底左右,到现在已经有大半年了,这段时间里,我通过飞桨框架学习了很多关于机器学习的理论和方法,也跑过不少项目了。但是,在往更深的领域去做时,我发现越来越吃力了,其实问题就在于基础不够扎实,我在找解决办法的时候,翻阅了AI Studio社区里很多大佬的文章。在翻阅这些文章的过程中,我发现我对飞桨确实不够了解,并且飞桨是2016年开源的,有些文章的内容稍微有一点点过时的,所以借此机会,我打算重新开始学习飞桨框架:

  1. 关于PaddlePaddle的版本
  2. Fluid的核心思想
  3. 开发机器学习模型的全流程

在这里插入图片描述

1. 关于PaddlePaddle的版本

这里的版本都是指大方向,即出现之前的版本和出现之后的版本

Fluid

出现Fluid前的版本和出现Fluid后的版本做比较,重点介绍出现Fluid以后的版本

最开始的PaddlePaddle还没有Fluid

如果你翻看PaddlePaddle以前的文档,就会发现PaddlePaddle已经有很多版本了,并且最初的版本是没有Fluid这个概念的:
在这里插入图片描述
Fluid这个概念是在0.13.0才开始出现的,这里我简单讲讲Fluid出现前的PaddlePaddle是什么样的:

# network config
x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(2))
y_predict = paddle.layer.fc(input=x, size=1, act=paddle.activation.Linear())
y = paddle.layer.data(name='y', type=paddle.data_type.dense_vector(1))
cost = paddle.layer.mse_cost(input=y_predict, label=y)

定义一层全连接网络,输入x,输出y,拿网络输出的y(y_predict)和期望的y做比较,计算损失cost

再来看一下训练的代码:

# training
trainer.train(
    reader=paddle.batch(
       train_reader(), batch_size=1),
    feeding=feeding,
    event_handler=event_handler,
    num_passes=100)

训练是通过调用trainer的train方法启动的

Fluid的出现让PaddlePaddle焕发生机

下面是对比图
在这里插入图片描述
官方给的区别是从有模型变为无模型,我理解的是,最大的改变就在于程序的编译过程里。

文档的原文是这么描述的:

When a Fluid application program runs, it generates a ProgramDesc protobuf message as an intermediate representation of itself. The C++ class Executor can run this protobuf message as an interpreter.

换句话说,Fluid能让PaddlePaddle的执行速度变的更快

静态图和动态图

PaddlePaddle引入动态图是在1.5之后,即从1.6开始支持动态图

因为静态图和动态图的内容较多,所以我将在下一篇文章内整理

2. Fluid的核心思想

上面的版本其实只是做了一个铺垫,现在使用PaddlePaddle都是需要用到Fluid

Fluid使用一种编译器式的执行流程,分为编译时运行时两个部分,具体包括:编译器定义 Program ,创建Executor 运行 Program 。

Fluid内部执行流程

  1. 编译时,用户编写一段python程序,通过调用 Fluid 提供的算子,向一段 Program 中添加变量(Tensor)以及对变量的操作(Operators 或者 Layers)。用户只需要描述核心的前向计算,不需要关心反向计算、分布式下以及异构设备下如何计算。

  2. 原始的 Program 在平台内部转换为中间描述语言: ProgramDesc。

  3. 编译期最重要的一个功能模块是 Transpiler。Transpiler 接受一段 ProgramDesc ,输出一段变化后的 ProgramDesc ,作为后端 Executor 最终需要执行的 Fluid Program

  4. 后端 Executor 接受 Transpiler 输出的这段 Program ,依次执行其中的 Operator(可以类比为程序语言中的指令),在执行过程中会为 Operator 创建所需的输入输出并进行管理。

Executor与Program的设计思想

Program

用户完成网络定义后,一段 Fluid 程序中通常存在 2 段 Program:

  1. fluid.default_startup_program:定义了创建模型参数,输入输出,以及模型中可学习参数的初始化等各种操作
    default_startup_program 可以由框架自动生成,使用时无需显示地创建
    如果调用修改了参数的默认初始化方式,框架会自动的将相关的修改加入default_startup_program

  2. fluid.default_main_program :定义了神经网络模型,前向反向计算,以及优化算法对网络中可学习参数的更新
    使用Fluid的核心就是构建起 default_main_program

Programs and Blocks

Fluid 的 Program 的基本结构是一些嵌套 blocks,形式上类似一段 C++ 或 Java 程序。

blocks中包含:

  • 本地变量的定义
  • 一系列的operator

block的概念与通用程序一致,例如在下列这段C++代码中包含三个block:

int main(){
    //block 0
    int i = 0;
    if (i<10){
    //block 1
        for (int j=0;j<10;j++){
    //block 2
        }
    }
    return 0;
}

类似的,在下列 Fluid 的 Program 包含3段block:

import paddle.fluid as fluid  # block 0

limit = fluid.layers.fill_constant_batch_size_like(
    input=label, dtype='int64', shape=[1], value=5.0)
cond = fluid.layers.less_than(x=label, y=limit)

ie = fluid.layers.IfElse(cond)
with ie.true_block(): # block 1
    true_image = ie.input(image)
    hidden = fluid.layers.fc(input=true_image, size=100, act='tanh')
    prob = fluid.layers.fc(input=hidden, size=10, act='softmax')
    ie.output(prob)

with ie.false_block(): # block 2
    false_image = ie.input(image)
    hidden = fluid.layers.fc(
        input=false_image, size=200, act='tanh')
    prob = fluid.layers.fc(input=hidden, size=10, act='softmax')
    ie.output(prob)

prob 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.郑先生_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值