百度paddle深度框架的安装及初步使用

paddle的安装

参考连接:

https://www.paddlepaddle.org.cn/#quick-start

注:文件较大,在新建的一个conda环境里安装




paddle的使用文档记录:

pp使用文档网址:

http://en.paddlepaddle.org/documentation/docs/zh/1.5/beginners_guide/quick_start_cn.html




Fluid编程指南:

使用Tensor表示数据:

Fluid和其他主流框架一样,使用Tensor数据结构来承载数据。

在神经网络中传递的数据都是Tensor,Tensor可以简单理解成一个多维数组,一般而言可以有任意多的维度。不同的Tensor可以具有自己的数据类型和形状,同一Tensor中每个元素的数据类型是一样的,Tensor的形状就是Tensor的维度。
下图直观地表示1~6维的Tensor:
(图片)
在 Fluid 中存在三种特殊的 Tensor:

1.模型中的可学习参数:

模型中的可学习参数(包括网络权重、偏置等)生存期和整个训练任务一样长,会接受
优化算法的更新,在 Fluid 中以 Variable 的子类 Parameter 表示
在Fluid中可以通过fluid.layers.create_parameter来创建可学习参数:

w = fluid.layers.create_parameter(name="w",shape=[1],dtype='float32')

一般情况下,您不需要自己来创建网络中的可学习参数,Fluid 为大部分常见的神经网络基本计算模块都提供了封装。以最简单的全连接模型为例,下面的代码片段会直接为全连接层创建连接权值(W)和偏置( bias )两个可学习参数,无需显式地调用 Parameter 相关接口来创建。

import paddle.fluid as fluid
y = fluid.layers.fc(input=x, size=128, bias_attr=True)

2. 输入输出Tensor:

整个神经网络的输入数据也是一个特殊的 Tensor,在这个 Tensor 中,一些维度的大小在定义模型时无法确定(通常包括:batch size,如果 mini-batch 之间数据可变,也会包括图片的宽度和高度等),在定义模型时需要占位。
Fluid 中使用fluid.layers.data来接收输入数据,fluid.layers.data 需要提供输入 Tensor 的形状信息,当遇到无法确定的维度时,相应维度指定为 None ,如下面的代码片段所示:

import paddle.fluid as fluid

#定义x的维度为[3,None],其中我们只能确定x的第一的维度为3,第二个维度未知,要在程序执行过程中才能确定
x = fluid.layers.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")

3. 常量 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并不具有值,它们仅表示将要执行的操作,如您直接打印data将会得到描述该data的一段信息:

print data

输出结果:

name: "fill_constant_0.tmp_0"
type {
    type: LOD_TENSOR
    lod_tensor {
        tensor {
            data_type: INT64
            dims: 1
        }
    }
}
persistable: false

具体输出数值将在Executor运行时得到,详细过程会在后文展开描述

数据传入:

Fluid有特定的数据传入方式:
您需要使用 fluid.layers.data 配置数据输入层,并在 fluid.Executor 或 fluid.ParallelExecutor 中,使用 executor.run(feed=…) 传入训练数据。

使用Operator表示对数据的操作:

在Fluid中,所有对数据的操作都由Operator表示,您可以使用内置指令来描述他们的神经网络。

为了便于用户使用,在Python端,Fluid中的Operator被一步封装入paddle.fluid.layerspaddle.fluid.nets等模块。

这是因为一些常见的对Tensor的操作可能是由更多基础操作构成,为了提高使用的便利性,框架内部对基础 Operator 进行了一些封装,包括创建 Operator 依赖可学习参数,可学习参数的初始化细节等,减少用户重复开发的成本。

例如用户可以利用paddle.fluid.layers.elementwise_add()实现两个输入Tensor的加法运算:

#定义网络:
import paddle.fluid as fluid

a = fluid.layers.data(name='a',shape=[1],dtype='float32')
b = fluid.layers.data(name='b',shape=[1],dtype='float32')


result = fluid.layers.elementwise_add(a,b)
print("result:")
print(result)
print("type:",type(result))

#定义Executor
cpu = fluid.CPUPlace()  #定义运算场所,这里在cpu上运算
exe = fluid.Executor(cpu) #创建执行器
exe.run(program=fluid.default_startup_program())  #网络参数初始化

#准备数据
import numpy as np
data_1 = int(input("please enter an integer a="))
data_2 = int(input("please enter an integer b="))
x = np.array([[data_1]])
y = np.array([[data_2]])

#执行计算
outs = exe.run(
    feed={'a':x,'b':y}, #输入的数据
    fetch_list= [result.name]  #用户想得到的数据,如果想看到计算过程中a、b的值可以令 fetch_list=[a,b,result.name]

)
print("outs:",outs)   # outs: [array([[10]], dtype=int32)]
print("%d+%d=%d" % (data_1,data_2,outs[0][0]))  # 输入了3,7,输出3+7=10

使用Program描述神经网络模型:

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_global_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.Switch() as switch:
    with switch.case(global_step == zero_var):
        fluid.layers.tensor.assign(input=one_var, output=lr)
    with switch.default():
        fluid.layers.tensor.assign(input=two_var, output=lr)

使用Executor执行Program:

Fluid的设计思想类似于高级编程语言C++和JAVA等。程序的执行过程被分为编译和执行两个阶段。

用户完成对 Program 的定义后,Executor 接受这段 Program 并转化为C++后端真正可执行的 FluidProgram,这一自动完成的过程叫做编译。

编译过后需要 Executor 来执行这段编译好的 FluidProgram。

例如上文实现的加法运算,当构建好 Program 后,需要创建 Executor,进行初始化 Program 和训练 Program:

#定义Exector
cpu = fluid.core.CPUPlace() #定义运算场所,这里选择在CPU下训练
exe = fluid.Executor(cpu) #创建执行器
exe.run(fluid.default_startup_program()) #用来进行初始化的program

#训练Program,开始计算
#feed以字典的形式定义了数据传入网络的顺序
#fetch_list定义了网络的输出
outs = exe.run(
    feed={'a':x,'b':y},
    fetch_list=[result.name])

代码实例:

至此,您已经对Fluid核心概念有了初步认识了,不妨尝试配置一个简单的网络吧。如果感兴趣的话可以跟随本部分,完成一个非常简单的数据预测。已经掌握这部分内容的话,可以跳过本节阅读What’s next。

从逻辑层面明确了输入数据格式、模型结构、损失函数以及优化算法后,需要使用 PaddlePaddle 提供的 API 及算子来实现模型逻辑。一个典型的模型主要包含4个部分,分别是:输入数据格式定义,模型前向计算逻辑,损失函数以及优化算法

在这里插入图片描述

import numpy as np
import paddle.fluid as fluid
import paddle
#定义数据: 假设输入数据X=[1 2 3 4],Y=[2,4,6,8],在网络中定义:


#定义数据
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) #act 激活应用于该层的输出 , size输出的单元数

#损失函数:
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.CPUPlace()  #运行位置
exe = fluid.Executor(cpu)  #创建执行器
exe.run(program = fluid.default_startup_program())  #初始化网络
#开始训练
for i in range(100):
    outs = exe.run(
        feed = {'x':train_data,'y':y_true},
        fetch_list = [y_predict.name,avg_cost.name]
    )
    print("avg_cost:",outs[1][0])
#观察结果:
print(outs)





快速使用paddle:

import paddle.fluid as fluid
import numpy as np


#Tensor 操作

# 1:通过fluid创建一个有5哥元素的一维数组,其中每个元素都为1
#定义数组维度和数据类型,可以修改shape参数定义任意大小的数组
data = fluid.layers.ones(shape = [5],dtype = 'int64') # The shape's type should be list or tuple.
#在cpu上执行运算
place = fluid.CPUPlace()
# #创建执行器
exe = fluid.Executor(place)
#执行运算
ones_result = exe.run(
    program = fluid.default_main_program(), # 需要运行的程序,默认为default的
    #获取数据data
    fetch_list = [data],  #需要获取的变量列表或变量名称列表
    return_numpy = True  #将获取的张量转化为numpy
)

print(ones_result[0])  #输出 [1 1 1 1 1]  ,只有一个元素的列表,列表中是一个numpy格式的数组


#---------------------------------------------------------------------------------------------------


# 2:使用Fluid将两个数组按位相加
#调用elementwise_add将生成的一维数组按位相加
add = fluid.layers.elementwise_add(data,data)
#定义运算场所
place_1 = fluid.CPUPlace()              #运算硬件:cpu
exe_1 = fluid.Executor(place=place_1)  #执行器
#执行计算
add_result = exe_1.run(
    program = fluid.default_main_program(),#运行程序
    fetch_list = [add],     #获取数据
    return_numpy = True,    #返回numpy数组
)
print(add_result[0])  # 输出结果 [2 2 2 2 2]


#-------------------------------------------------------------------------------------------------


# 3:使用Fluid转化数据类型
#将一维数组整型转化为float64
cast = fluid.layers.cast(data,dtype='float64')
#定义运算场所
place_2 = fluid.CPUPlace()
exe_2 = fluid.Executor(place_2)
#执行运算
cast_result = exe_2.run(
    program = fluid.default_main_program(),
    fetch_list= [cast],
    return_numpy= True
)

print(cast_result[0])  #输出了 [1. 1. 1. 1. 1.]

线性回归模型测试

#线性回归模型测试
import paddle.fluid as fluid
import numpy as np

#生成数据

np.random.seed(0)
outputs = np.random.randint(5,size=(10,4))
res = []

for i in range(10):
    #设 y = 4a + 6b + 7c + 2d
    y = 4 * outputs[i][0] + 6 * outputs[i][1] + 7 * outputs[i][2] + 2 * outputs[i][3]
    res.append([y])    #小坑,此处要注意传入的y是 [y]。否则会报错:paddle.fluid.core_avx.EnforceNotMet: Invoke operator elementwise_sub error.

#定义数据
train_data = np.array(outputs).astype('float32')
y_true = np.array(res).astype('float32')

#定义网络
x = fluid.layers.data(
    name="x",
    shape=[4],
    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.05)
sgd_optimizer.minimize(avg_cost)

#参数初始化
cpu = fluid.CPUPlace()
exe = fluid.Executor(cpu)
exe.run(program = fluid.default_startup_program())

#开始训练,迭代500次
for i in range(500):
    outs = exe.run(
        feed = {'x':train_data,'y':y_true},
        fetch_list = [y_predict.name,avg_cost.name]
    )
    if i % 50  == 0:
        print('iter={:.0f},cost={}'.format(i, outs[1][0]))

#储存训练结果
params_dirname = r'result'
fluid.io.save_inference_model(params_dirname,['x'],[y_predict],exe)

#开始预测
infer_exe = fluid.Executor(cpu)  #执行器
inference_scope = fluid.Scope()  #范围

#加载训练好的模型
with fluid.scope_guard(inference_scope):
    [inference_program,feed_target_names,fetch_targets] = fluid.io.load_inference_model(params_dirname,infer_exe)

#生成测试数据
test = np.array([[[9],[5],[2],[10]]]).astype('float32')

#进行预测
results = infer_exe.run(
    program = inference_program,
    feed = {'x':test,},
    fetch_list = fetch_targets
)

#给出题目为9,5,2,10,结果应该为 y = 4 * 9 + 6 * 5 + 7 * 2 + 2 * 10 = 100
print ("9a+5b+2c+10d = {}".format(results[0][0]))  #输出结果为:9a+5b+2c+10d = [99.941414] (接近100的值)


ERNIE介绍:

http://m.elecfans.com/article/1015091.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值