PaddlePaddle的基本操作
目录
第一篇博客主要是从paddlepaddle的简介,安装和基本语法三个方面进行简介(如果是接触过其他框架的话是很容易上手paddlepaddle的)。
PaddlePaddle简介
PaddlePaddle是百度研发的开源开放的深度学习平台,有全面的官方支持的工业级应用模型,涵盖自然语言处理、计算机视觉、推荐引擎等多个领域,并开放多个领先的预训练中文模型。
PaddlePaddle同时支持稠密参数和稀疏参数场景的大规模深度学习并行训练,支持千亿规模参数、数百个几点的高效并行训练,也可提供深度学习并行技术的深度学习框架。PaddlePaddle拥有多端部署能力,支持服务器端、移动端等多种异构硬件设备的高速推理,预测性能有显著优势。目前PaddlePaddle已经实现了API的稳定和向后兼容,具有完善的中英双语使用文档。
版本发展(目前最新的版本是fluid1.4版本,博主使用的是1.3版本的,功能和模块接口都比较稳定)
PaddlePaddle安装
PaddlePaddle目前支持的Python版本包括:Python 2.7-3.7
PaddlePaddle目前支持以下环境:
Ubuntu 14.04 /16.04 /18.04
CentOS 7 / 6
MacOS 10.11 / 10.12 / 10.13 / 10.14
Windows7 / 8/ 10(专业版/企业版)
pip安装
在配置好anaconda环境,可以直接使用pip的情况下,直接在cmd命令框中输入
pip install paddlepaddle
可以安装cpu版。如果要安装GPU版本,使用指令
pip install paddlepaddle-gpu
注意直接使用pip安装的是Fluid版本的,pip默认安装最新版本。如果安装旧版V1或者V2版本,需要使用其他指令,0.12版及之前是V2
安装旧版本使用指令:
pip install paddlepaddle==[PaddlePaddle版本号]
pip install paddlepaddle-gpu==[PaddlePaddle版本号]
Docker安装
docker run --name [Name of container] -it -v $PWD:/paddle hub.baidubce.com/paddlepaddle/paddle:[docker版本号] /bin/bash
PaddlePaddle基本语法
1. 数据结构
Paddle以Tensor作为基本数据结构来承载数据。搭建神经网络的过程中都是以Tensor的形式传递数据。Tensor可以简单的理解程一个多维数组,Tensor一般可以有任意多的维度。不同的Tensor有自己的数据类型和形状。同一Tensor中的每个元素的数据类型是一样的,Tensor的形状就是Tensor的维度。
下图表示一个1-6维的Tensor:
- 模型中可学习参数的设置方法
在模型设置中,诸如像网络权重、偏置等可学习参数在网络设置的整个周期中存在,会接受优化算法的更新,在Fluid
中以Variable
中的子类Parameter
表示,在Fluid
中以fluid.layers.create_parameter
来创建可学习参数:
w=fluid.layers.create_parameter(name="w",shape=[1],dtype="int32")
在神经网络的搭建过程中,由于
Fluid
对大部分常见的神经网络提供了封装,所以一般不需要使用者再去创建网络中的可学习参数。比如下面的例子,代码会直接为全连接层创建连接权值(w)和偏置(bias) 两个可学习参数,无需显式调用Parameter
相关接口来创建。
import paddle.fluid as fluid
y=fluid.layers.fc(input=x,size=128,bias_attr=True)
#bias_attr参数设置为True,就默认会创建一个偏置
- Tensor的基本设置
在fluid
中使用fluid.layers.data
来接收输入数据,fluid.layers.data
需要提供输入Tensor的形状信息,当遇到无法确定的维度时,相应的维度指定为None。
整个神经网络的输入数据是一个特殊的Tensor,在这个Tensor中,一些维度的大小在定义模型时无法直接确定(通常包括:batchsize,如果mini-batch之间的数据可变,也会包括图片的宽度和高度等),需要在定义模型时进行占位。个人理解,
fluid.layers.data
就是建立了一个空的容器,之后进行数据赋值就可以参与神经网络的各种计算。
例子:
import paddle.fluid as fluid
#定义x的维度为[3,None],其实我们只能确定x的第一维度为3,第二维度未知,要在程序执行中才能确定
x=fluid.layer.data(name="x",shape=[3,None],dtype='int64')
#batch_size无需显示指定,框架会自动补全第0维为batch size,并在运行时填充正确的数值
a=fluid.layers.data(name="a",shape=[3,4],dtype='int64')
#若图片的宽度和高度在运行时可变,将宽度和高度定义为None。
#shape的三个维度含义分别是:channel、图片的宽度、图片的高度
b=fluid.layers.data(name="image",shape=[3,None,None],dtype="float32")
- 常量Tensor的设置
Fluid中使用
fluid.layers.fill_constant
来实现常量Tensor,用户可以指定Tensor的形状,数值类型和常量值。
import paddle.fluid as fluid
data=fluid.layers.fill_constant(shape=[1],value=0,dtype='int64'
不过上述定义的tensor并不具备值,仅仅表示要执行的操作,具体的输出数值会在Executor运行时得到。打印data可以得到描述data的一段信息:
name: “fill_constant_0.tmp_0”
type {
type: LOD_TENSOR
lod_tensor {
tensor {
data_type: INT64
dims: 1
}
}
}
persistable: false
2. 数据的传入
Fluid有特定的数据传入的方式:
- 同步feed的方式
首先,要先使用fluid.layers.data
中配置数据输入层,并在fluid.Executor
或fluid.ParallelExecutor
中,使用executor.run()
传入训练数据。数据准备和模型训练/预测的过程是同步进行的,效率较低。 - 异步py_reader接口方式
用户需要先使用fluid.layers.py_reader
配置数据输入层,然后使用py_reader
的decorate_paddle_reader
或decorate_tensor_provider
方法配置数据源,再通过fluid.layers.read_file
读取数据。数据传入与模型训练/预测过程是异步进行的,效率较高。
3. 数据操作
在Fluid中,所有对数据的操作都由Operator
表示,您可以使用内置指令来描述他们的神经网络。
为了便于用户使用,在Python端,Fluid中的Operator
被一步封装入paddle.fluid.layers
,paddle.fluid.nets
等模块。
这是因为一些常见的对Tensor
的操作可能是由更多基础操作构成,为了提高使用的便利性,框架内部对基础Operator
进行了一些封装,包括创建 Operator
依赖可学习参数,可学习参数的初始化细节等,减少用户重复开发的成本。
- 定义执行器的操作
#定义一个Exector
cpu=fluid.core.CPUPlace()#定义运算场所,这里选择在CPU下训练
exe=fluid.Executor(cpu)#创建执行器
exe.run(fluid.default_satrtup_program())#网络参数初始化
2.综合案例-定义一个加法器
#导入依赖库
import paddle.fluid as fluid
import paddle
import numpy as np
#设置a,b两个容器,用来存储加法输入的变量
a=fluid.layers.data(name='a',shape=[1],dtype='float32')
b=fluid.layers.data(name='b',shape=[1],dtype='float32')
#定义计算过程
result=fluid.layers.sum([a,b])
#定义执行器
cpu=fluid.core.CPUPlace()#定义运算场所,这里选择在CPU下进行训练
exe=fluid.Executor(cpu)#创建执行器
exe.run(fluid.default_startup_program())#网络参数初始化
#准备数据
data_1=float(input("Please enter an num: a="))
data_2=float(input("Please enter an num: a="))
x=np.array([data_1])
y=np.array([data_2])
#执行计算
outs=exe.run(feed={'a':x,'b':y},fetch_list=[result.name])#fetch_list控制输出的结果,可以加入其他变量输出
#验证结果
print("%d+%d=%d" %(data_1,data_2,outs[0][0]
运行结果:
4. 神经网络相关操作
Fluid不同于其他大部分深度学习框架,去掉了静态计算图的概念,代之以Program的形式动态描述计算过程。这种动态的计算描述方式,兼具网络结构修改的灵活性和模型搭建的便捷性,在保证性能的同时极大地提高了框架对模型的表达能力。
开发者的所有 Operator 都将写入 Program ,在Fluid内部将自动转化为一种叫作 ProgramDesc 的描述语言,Program 的定义过程就像在写一段通用程序,有开发经验的用户在使用 Fluid 时,会很自然的将自己的知识迁移过来。
其中,Fluid通过提供顺序、分支和循环三种执行结构的支持,让用户可以通过组合描述任意复杂的模型。
- 顺序执行
用户可以使用顺序执行的方式搭建网络:
x=fluid.layers.data(name='x',shape=[13],dtype='float32'
y_predict=fluid.layers.fc(input=x,size=1,act=None)
y=fluid.layers.data(name='y',shape=[1],dtype='float32')
cost=fluid.layers.square_error_cost(input=y_predict,label=y)
- 条件分支–switch,if else
Fluid 中有 switch 和 if-else 类来实现条件选择,用户可以使用这一执行结构在学习率调节器中调整学习率或其他希望的操作:
lr=fluid.layers.tensor.create_gloabl_var(
shape=[1],
value=0.0,
dtype='float32',
persistable=True,
name="learning_rate")
one_var=fluid.layers.fill_constant(
shape=[1],dtype='float32',value=1.0)
two_var=fluid.layers.fill_constant(
shape=[1],dtype='float32',value=2.0)
with fluid.layers.control_flow.Swith() as swith:
with swith.case(global_step==zero_var):
fluid.layers.tensor.assign(input=one_var,output=lr)
PaddlePaddle案例实战
1. 问题描述
2. 定义数据
3. 搭建网络
4. 添加损失函数
5. 网络优化
最后附上完整代码:
#加载库
import paddle.fluid as fluid
import numpy as np
#定义数据
train_data=np.array([[1.0],[2.0],[3.0],[4.0]]).astype('float32')
y_true=np.array([[2.0],[4.0],[6.0],[8.0]]).astype('float32')
#定义网络
x=fluid.layers.data(name='x',shape=[1],dtype='float32')
y=fluid.layers.data(name='y',shape=[1],dtype='float32')
y_predict=fluid.layers.fc(input=x,size=1,act=None)
#定义损失函数
cost=fluid.layers.square_error_cost(input=y_predict,label=y)
avg_cost=fluid.layers.mean(cost)
#定义优化方法
sgd_optimizer=fluid.optimizer.SGD(learning_rate=0.01)
sgd_optimizer,minimize(avg_cost)
#参数初始化
cpu=fluid.core.CPUPlace()
exe=fluid.Executor(cpu)
exe.run(fluid.default_startup_program())
#开始训练,迭代100次
for i in range(100):
out=exe.run(feed={'x':train_data,'y':y_true},
fetch_list=[y_predict.name,avg_cost.name])
#观察结果
print(outs)