相关文章:
【一】飞桨paddle【GPU、CPU】安装以及环境配置 python入门教学
【二】-Parl基础命令
【三】-Notebook、&pdb、ipdb 调试
【四】-强化学习入门简介
【五】-Sarsa&Qlearing详细讲解
【六】-DQN
【七】-Policy Gradient
【八】-DDPG
【九】-四轴飞行器仿真
- 飞桨paddle遇到bug调试修正【迁移工具、版本兼容性】
- paddle DeBug 三步定位PARL飞桨报错原因,快速解决程序问题
一、AI Studio 项目详解【VisualDL工具】
二、AI Studio 项目详解【环境使用说明、脚本任务】
三、AI Studio 项目详解【分布式训练-单机多机】
四、AI Studio 项目详解【图形化任务】
五、AI Studio 项目详解【在线部署及预测】
常遇见代码错误{https://blog.csdn.net/sinat_39620217/article/details/114847578?spm=1001.2014.3001.5501}
1.PaddlePaddle基础命令
PaddlePaddle是百度开源的深度学习框架,类似的深度学习框架还有谷歌的Tensorflow、Facebook的Pytorch等,在入门深度学习时,学会并使用一门常见的框架,可以让学习效率大大提升。在PaddlePaddle中,计算的对象是张量,我们可以先使用PaddlePaddle来计算一个[1, 1, 1, 1] * [1, 1, 1, 1]。
1.2 计算常量的加法:1 1
首先导入PaddlePaddle库
In
代码语言:javascript复制import paddle.fluid as fluid
定义两个张量的常量x1和x2,并指定它们的形状是2, 2,并赋值为1铺满整个张量,类型为int64.
In
代码语言:javascript复制# 定义两个张量
x1 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64')
x2 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64')
接着定义一个操作,该计算是将上面两个张量进行加法计算,并返回一个求和的算子。PaddlePaddle提供了大量的操作,比如加减乘除、三角函数等,读者可以在fluid.layers找到。
In
代码语言:javascript复制# 将两个张量求和
y1 = fluid.layers.sum(x=[x1, x2])
然后创建一个解释器,可以在这里指定计算使用CPU或GPU。当使用CPUPlace()时使用的是CPU,如果是CUDAPlace()使用的是GPU。解析器是之后使用它来进行计算过的,比如在执行计算之前我们要先执行参数初始化的program也是要使用到解析器的,因为只有解析器才能执行program。
In
代码语言:javascript复制# 创建一个使用CPU的解释器
place = fluid.CPUPlace()
exe = fluid.executor.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())
代码语言:javascript复制[]
最后执行计算,program的参数值是主程序,不是上一步使用的是初始化参数的程序,program默认一共有两个,分别是default_startup_program()和default_main_program()。fetch_list参数的值是在解析器在run之后要输出的值,我们要输出计算加法之后输出结果值。最后计算得到的也是一个张量。
In
代码语言:javascript复制# 进行运算,并把y的结果输出
result = exe.run(program=fluid.default_main_program(),
fetch_list=[y1])
print(result)
代码语言:javascript复制[array([[2, 2],
[2, 2]])]
1.3 计算变量的加法:1 1
上面计算的是张量常量的1 1,并不能随意修改常量的值,所以下面我们要编写一个使用张量变量作为乘数的程序,类似是一个占位符,等到将要计算时,再把要计算的值添加到占位符中进行计算。
导入PaddlePaddle库和numpy的库。
In
代码语言:javascript复制import paddle.fluid as fluid
import numpy as np
定义两个张量,并不指定该张量的形状和值,它们是之后动态赋值的。这里只是指定它们的类型和名字,这个名字是我们之后赋值的关键。
In
代码语言:javascript复制# 定义两个张量
a = fluid.layers.create_tensor(dtype='int64', name='a')
b = fluid.layers.create_tensor(dtype='int64', name='b')
使用同样的方式,定义这个两个张量的加法操作。
In
代码语言:javascript复制# 将两个张量求和
y = fluid.layers.sum(x=[a, b])
这里我们同样是创建一个使用CPU的解析器,和进行参数初始化。
In
代码语言:javascript复制# 创建一个使用CPU的解释器
place = fluid.CPUPlace()
exe = fluid.executor.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())
代码语言:javascript复制[]
然后使用numpy创建两个张量值,之后我们要计算的就是这两个值。
In
代码语言:javascript复制# 定义两个要计算的变量
a1 = np.array([3, 2]).astype('int64')
b1 = np.array([1, 1]).astype('int64')
这次exe.run()的参数有点不一样了,多了一个feed参数,这个就是要对张量变量进行赋值的。赋值的方式是使用了键值对的格式,key是定义张量变量是指定的名称,value就是要传递的值。在fetch_list参数中,笔者希望把a, b, y的值都输出来,所以要使用3个变量来接受返回值。
In
代码语言:javascript复制# 进行运算,并把y的结果输出
out_a, out_b, result = exe.run(program=fluid.default_main_program(),
feed={'a': a1, 'b': b1},
fetch_list=[a, b, y])
print(out_a, " ", out_b," = ", result)
代码语言:javascript复制(array([3, 2]), ' ', array([1, 1]), ' = ', array([4, 3]))
1.4 使用PaddlePaddle做线性回归
在上面的教学中,教大家学会用PaddlePaddle做基本的算子运算,下面来教大家如何用PaddlePaddle来做简单的线性回归,包括从定义网络到使用自定义的数据进行训练,最后验证我们网络的预测能力。
首先导入PaddlePaddle库和一些工具类库。
In
代码语言:javascript复制import paddle.fluid as fluid
import paddle
import numpy as np
定义一个简单的线性网络,这个网络非常简单,结构是:输出层-->>隐层-->>输出层__
,这个网络一共有2层,因为输入层不算网络的层数。更具体的就是一个大小为100,激活函数是ReLU的全连接层和一个输出大小为1的全连接层,就这样构建了一个非常简单的网络。这里使用输入fluid.layers.data()定义的输入层类似fluid.layers.create_tensor()
,也是有name
属性,之后也是根据这个属性来填充数据的。这里定义输入层的形状为13,这是因为波士顿房价数据集的每条数据有13个属性,我们之后自定义的数据集也是为了符合这一个维度。
In
代码语言:javascript复制# 定义一个简单的线性网络
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
hidden = fluid.layers.fc(input=x, size=100, act='relu')
net = fluid.layers.fc(input=hidden, size=1, act=None)
接着定义神经网络的损失函数,这里同样使用了fluid.layers.data()
这个接口,这个可以理解为数据对应的结果,上面name
为x的fluid.layers.data()
为属性数据。这里使用了平方差损失函数(square_error_cost)
,PaddlePaddle提供了很多的损失函数的接口,比如交叉熵损失函数(cross_entropy)
。因为本项目是一个线性回归任务,所以我们使用的是平方差损失函数。因为fluid.layers.square_error_cost()
求的是一个Batch的损失值,所以我们还要对他求一个平均值。
In
代码语言:javascript复制# 定义损失函数
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
cost = fluid.layers.square_error_cost(input=net, label=y)
avg_cost = fluid.layers.mean(cost)
定义损失函数之后,可以在主程序(fluid.default_main_program)
中克隆一个程序作为预测程序,用于训练完成之后使用这个预测程序进行预测数据。这个定义的顺序不能错,因为我们定义的网络结构,损失函数等等都是更加顺序记录到PaddlePaddle的主程序中的。主程序定义了神经网络模型,前向反向计算,以及优化算法对网络中可学习参数的更新,是我们整个程序的核心,这个是PaddlePaddle已经帮我们实现的了,我们只需注重网络的构建和训练即可。
In
代码语言:javascript复制# 复制一个主程序,方便之后使用
test_program = fluid.default_main_program().clone(for_test=True)
接着是定义训练使用的优化方法,这里使用的是随机梯度下降优化方法。PaddlePaddle提供了大量的优化函数接口,除了本项目使用的随机梯度下降法(SGD),还有Momentum、Adagrad、Adagrad等等,读者可以更加自己项目的需求使用不同的优化方法。
In
代码语言:javascript复制# 定义优化方法
optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.01)
opts = optimizer.minimize(avg_cost)
然后是创建一个解析器,我们同样是使用CPU来进行训练。创建解析器之后,使用解析器来执行fluid.default_startup_program()初始化参数。
In
代码语言:javascript复制# 创建一个使用CPU的解释器
place = fluid.CPUPlace()
exe = fluid.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())
代码语言:javascript复制[]
我们使用numpy定义一组数据,这组数据的每一条数据有13个,这是因为我们在定义网络的输入层时,shape是13,但是每条数据的后面12个数据是没意义的,因为笔者全部都是使用0来填充,纯粹是为了符合数据的格式而已。这组数据是符合y = 2 * x 1,但是程序是不知道的,我们之后使用这组数据进行训练,看看强大的神经网络是否能够训练出一个拟合这个函数的模型。最后定义了一个预测数据,是在训练完成,使用这个数据作为x输入,看是否能够预测于正确值相近结果。
In
代码语言:javascript复制# 定义训练和测试数据
x_data = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32')
y_data = np.array([[3.0], [5.0], [7.0], [9.0], [11.0]]).astype('float32')
test_data = np.array([[6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32')
定义数据之后,我们就可以使用数据进行训练了。我们这次训练了10个pass,读者可根据情况设置更多的训练轮数,通常来说训练的次数越多,模型收敛的越好。同样我们使用的时profram是fluid.default_main_program(),feed中是在训练时把数据传入fluid.layers.data()定义的变量中,及那个键值对的key对用的就是fluid.layers.data()中的name的值。我们让训练过程中输出avg_cost的值。
在训练过程中,我们可以看到输出的损失值在不断减小,证明我们的模型在不断收敛。
In
代码语言:javascript复制# 开始训练100个pass
for pass_id in range(10):
train_cost = exe.run(program=fluid.default_main_program(),
feed={'x': x_data, 'y': y_data},
fetch_list=[avg_cost])
print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0]))
代码语言:javascript复制Pass:0, Cost:60.79917
Pass:1, Cost:20.51965
Pass:2, Cost:4.12735
Pass:3, Cost:0.14202
Pass:4, Cost:0.02519
Pass:5, Cost:0.02464
Pass:6, Cost:0.02412
Pass:7, Cost:0.02361
Pass:8, Cost:0.02311
Pass:9, Cost:0.02262
训练完成之后,我们使用上面克隆主程序得到的预测程序了预测我们刚才定义的预测数据。预测数据同样作为x在feed输入,在预测时,理论上是不用输入y的,但是要符合输入格式,我们模拟一个y的数据值,这个值并不会影响我们的预测结果。fetch_list的值,也就是我们执行预测之后要输出的结果,这是网络的最后一层,而不是平均损失函数(avg_cost),因为我们是想要预测程序输出预测结果。根据我们上面定义数据时,满足规律y = 2 * x 1,所以当x为6时,y应该时13,最后输出的结果也是应该接近13的。
In
代码语言:javascript复制# 开始预测
result = exe.run(program=test_program,
feed={'x': test_data, 'y': np.array([[0.0]]).astype('float32')},
fetch_list=[net])
print("当x为6.0时,y为:%0.5f" % result[0][0][0])
代码语言:javascript复制当x为6.0时,y为:13.22840