简易解读:PARL与强化学习基础教程
最编程
2024-07-19 09:22:27
...
PARL与强化学习笔记
- 1.预习
- 1.1MNIST手写识别
- 1.2 python基础知识
- 1.3paddle基础知识
- 1.3.1计算常量的加法:1+1
- 1.3.2计算变量的加法:1+1
- 1.3.3使用PaddlePaddle做线性回归,满足规律y = 2 * x + 1
- 1.3.4用PaddlePaddle做房价预测
- 2.初识
- 3.基于表格型求解RL
- 3.1 sarsa
- 3.2q_learning
- 4.DQN基于神经网络求解RL
- 5.PolicyGradient-基于策略梯度求解RL
- 6.连续动作空间上求解RL
最近打算学习强化学习,看到了百度的公开课(https://aistudio.baidu.com/aistudio/education/group/info/1335),所以跟着学习记录一些笔记。
1.预习
1.人的视觉系统处理信息是分级的。
2.边缘特征 —–> 基本形状和目标的局部特征——>整个目标 这个过程其实和我们的常识是相吻合的,因为复杂的图形,往往就是由一些基本结构组合而成的。同时我们还可以看出:大脑是一个深度架构,认知过程也是深度的。
3.低层次特征 - - - - (组合) - - ->抽象的高层特征
1.1MNIST手写识别
1.基于anconda安装parl环境
conda create -n paddle python=3.7#创建3.7虚拟环境
conda info -e #查看自己创建的化境是否成功
conda activate paddle #进入此环境
pip install paddlepaddle #安装百度的paddle库
pip install parl #安装算法parl库
pip install gym #安装游戏环境库
2.搭建神经网络识别手写数字
首先搭建网络训练数据,后保存模型
#1.导包
from xml.sax.handler import property_declaration_handler
import numpy as np
import paddle as paddle
paddle.enable_static()#paddle2.0以上需要加这一行代码
import paddle.fluid as fluid
from PIL import Image
import matplotlib.pyplot as plt
import os
#2.下载手写数据集
train_data=paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.train(),buf_size=512),batch_size=128)#下载训练集数据并打乱,缓冲512,batch128
test_data=paddle.batch(paddle.dataset.mnist.test(),batch_size=128)#下载测试集,batch128
"""
#观察一张手写的数据格式
temp_data=paddle.batch(paddle.dataset.mnist.train(),batch_size=1)
print(next(temp_data()))
"""
#3.搭建神经网络结构
##3.1网络结构
image=fluid.layers.data(name="image",shape=[1,28,28],dtype="float32")#定义输入层的数据格式
label=fluid.layers.data(name="label",shape=[1],dtype="int64")
def multilayer_perceptron(input):#定义多层感知机的结构(两个100和一个10)
hidden1=fluid.layers.fc(input=input,size=100,act="relu")#第一个隐层是:100个神经元的全连接层和relu激活层
hidden2=fluid.layers.fc(input=hidden1,size=100,act="relu")#第二个隐藏层:100个神经元的全连接层和relu激活层
prediction=fluid.layers.fc(input=hidden2,size=10,act="softmax")#第三层:10个神经元的全连接和softmax激活层
return prediction
model=multilayer_perceptron(image)
##3.2网络的损失函数和准确率函数
cost=fluid.layers.cross_entropy(input=model,label=label)#交叉熵损失函数
avg_cost=fluid.layers.mean(cost)
acc=fluid.layers.accuracy(input=model,label=label)
##3.3网络训练的优化方式
optimizer=fluid.optimizer.AdamOptimizer(learning_rate=0.001)#学习率位0.001的Adam优化器
opts=optimizer.minimize(avg_cost)#优化器优化均熵值
#4.模型训练与评估
##4.1定义解析器(cpu、gpu)并初始化参数
place=fluid.CPUPlace()
exe=fluid.Executor(place)#实例化了一个cpu解析器
exe.run(fluid.default_startup_program())#初始化解析器参数
feeder=fluid.DataFeeder(place=place,feed_list=[image,label])#定义输入数据的维度【图片,标签】
##4.2开始训练与测试
for epoch in range(5):
for batch_id,data in enumerate(train_data()):#每次拿一个batch的训练数据
train_cost,train_acc=exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost,acc])#训练一个batch后拿到avg_cost和acc
if batch_id%100==0:
print("epoch:%d,batch:%d,cost:%0.5f,accuracy:%0.5f"%(epoch,batch_id,train_cost[0],train_acc[0]))
test_costs=[]#测试,每一个epoch测试一次网络
test_accs=[]
for batch_id,data in enumerate(test_data()):
test_cost,test_acc=exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost,acc])
test_costs.append(test_cost[0])
test_accs.append(test_acc[0])
test_cost=(sum(test_costs)/len(test_costs))#求一个epoch里面测试集的所有batch的均值
test_acc=(sum(test_accs)/len(test_accs))
print("test:%d,cost:%0.5f,accuracy:%0.5f"%(epoch,test_cost,test_acc))
model_save_dir="C:\\Users\\Administrator\\Desktop\\parl\\out"#保存模型
if not os.path.exists(model_save_dir):
os.makedirs(model_save_dir)
print("save models to %s"%(model_save_dir))
fluid.io.save_inference_model(model_save_dir,#保存推理model的路径
['image'],#模型feed的数据
[model],#模型的ariables
exe)#保存inference mode
3.然后用此模型进行手写数据图片的预测
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import paddle as paddle
paddle.enable_static()#paddle2.0以上需要加这一行代码
import paddle.fluid as fluid
#1.首先对拿到的图片进行预处理,转化为网络数据的数据格式
def load_image(file):
im=Image.open(file).convert("L")#将RGB转化为灰度图像,L代表灰度图像,灰度图像的像素值在0~255之间
im=im.resize((28,28),Image.ANTIALIAS)#resize image with high-quality 图像大小为28*28
im=np.array(im).reshape(1,1,28,28).astype(np.float32)#返回新形状的数组,把它变成一个 numpy 数组以匹配数据馈送格式。
im=im/255.0*2.0-1.0#归一化到【-1~1】之间
print(im)
return im
img=Image.open("C:\\Users\\Administrator\\Desktop\\parl\\data\\6.png")
plt.imshow(img)#根据数组绘制图像
plt.show()#显示图像
#2.加载模型进行预测
place=fluid.CPUPlace()
exe=fluid.Executor(place)#实例化了一个cpu解析器
scope=fluid.core.Scope()#实例化
img=load_image("C:\\Users\\Administrator\\Desktop\\parl\\data\\6.png")
with fluid.scope_guard(scope):
#推理Program,targetname是一个str列表,它包含需要在推理 Program 中提供数据的变量的名称。fetch_targets:是一个 Variable 列表,从中我们可以得到推断结果。model_save_dir:模型保存的路径
[inference_program,feed_target_names,fetch_targets]=fluid.io.load_inference_model("C:\\Users\\Administrator\\Desktop\\parl\\out",exe)
results = exe.run(program=inference_program, #运行推测程序
feed={feed_target_names[0]: img}, #喂入要预测的img
fetch_list=fetch_targets) #得到推测结果,
lab = np.argsort(results) #argsort函数返回的是result数组值从小到大的索引值
print("该图片的预测结果的label为: %d" % lab[0][0][-1]) #-1代表读取数组中倒数第一列
1.2 python基础知识
#1.字符串
print(firstVariable.lower())
print(firstVariable.upper())
print(firstVariable.title())
# To look up what each method does
firstVariable.lower?
help(firstVariable.lower)
#2.列表
print(min(z), max(z), len(z), sum(z))
random_list = [4, 1, 5, 4, 10, 4]
random_list.count(4)
random_list.index(4)#返回列表第一个指针
# you can specify where you start your search
random_list.index(4, 3)
# random_list.index(value, [start, stop])
random_list.index(4, 5, 6)
x.sort()#列表排序
print(x)
x.sort(reverse = True)
new_list = sorted(y)
new_list
x.insert(4, [4, 5])#[11, 8, 7, 3, [4, 5], 2, 3, 4, 5]
#3.字典
webstersDict.update({'shirt': 'a', 'shoe': 'b'})#添加
del webstersDict['resist']#删除
storyCount.get('Michael', 0)#获取M的值,如果没有添加值为0
count = storyCount.pop('the')#删除键,但同时可以返回值
print(storyCount.keys())
print(storyCount.values())
for key, value in webstersDict.items():
print(key, value)
#4.元组,元组是不可变的,这意味着在初始化元组之后,不可能更新元组中的单个项。
tup1 = ('Michael',)#重要的是要记住,如果要创建仅包含一个值的元组,则需要在项目后面添加一个逗号。
print(animals.index('lama'))#index方法返回对应值的第一个索引
print(animals.count('lama'))#count方法返回值在元组中出现的次数。
#元组比列表更快。
import timeit
print('Tuple time: ', timeit.timeit('x=(1,2,3,4,5,6,7,8,9,10,11,12)', number=1000000))
print('List time: ', timeit.timeit('x=[1,2,3,4,5,6,7,8,9,10,11,12]', number=1000000))
#一些元组可以用作字典键(特别是包含不可变值的元组,如字符串,数字和其他元组)。列表永远不能用作字典键,因为列表不是不可变的
#isinstance()函数用于确定实例是否也是某个父类的实例。
1.3paddle基础知识
1.3.1计算常量的加法:1+1
import paddle as paddle
paddle.enable_static()#paddle2.0以上需要加这一行代码
import paddle.fluid as fluid
#1.定义张量
x1=fluid.layers.fill_constant(shape=[2,2],value=1,dtype='int64')#常量形状是[2, 2],并赋值为1铺满整个张量,类型为int64.
x2=fluid.layers.fill_constant(shape=[2,2],value=1,dtype='int64')
y1=fluid.layers.sum(x=[x1,x2])# 将两个张量求和,fluid.layers加减乘除、三角函数等张量操作。
#2.初始化解释器
place=fluid.CPUPlace()# 创建一个使用CPU的解释器,当使用CPUPlace()时使用的是CPU,如果是CUDAPlace()使用的是GPU
exe=fluid.executor.Executor(place)
exe.run(fluid.default_startup_program())# 解释器进行参数初始化
#3.执行
result=exe.run(program=fluid.default_main_program(),fetch_list=[y1])#执行计算,program的参数值是主程序,program默认一共有两个,分别是default_startup_program()和default_main_program()。fetch_list参数的值是在解析器在run之后要输出的值,最后计算得到的也是一个张量。
print(result)#[array([[2, 2],[2, 2]])]
1.3.2计算变量的加法:1+1
import paddle as paddle
paddle.enable_static()#paddle2.0以上需要加这一行代码
import paddle.fluid as fluid
import numpy as np
#1.定义变量
a=fluid.layers.create_tensor(dtype="int64",name="a")#不指定该张量的形状和值,它们是之后动态赋值的。这里只是指定它们的类型和名字,这个名字是我们之后赋值的关键。
b=fluid.layers.create_tensor(dtype="int64",name="b")
y=fluid.layers.sum(x=[a,b])
#2.初始化解释器
place=fluid.CPUPlace()# 创建一个使用CPU的解释器,当使用CPUPlace()时使用的是CPU,如果是CUDAPlace()使用的是GPU
exe=fluid.executor.Executor(place)
exe.run(fluid.default_startup_program())# 解释器进行参数初始化
#3.执行
a1=np.array([3,2]).astype("int64")#使用numpy创建两个张量值,之后我们要计算的就是这两个值
b1=np.array([1,1]).astype("int64")
out_a,out_b,result=exe.result=exe.run(program=fluid.default_main_program(),feed={"a":a1,"b":b1},fetch_list=[a,b,y])#feed参数对张量变量进行赋值的。赋值的方式是使用了键值对的格式,key是定义张量变量是指定的名称,value就是要传递的值。
print(out_a,"+",out_b,"=",result)#[3 2] + [1 1] = [4 3]
1.3.3使用PaddlePaddle做线性回归,满足规律y = 2 * x + 1
import paddle as paddle
paddle.enable_static()#paddle2.0以上需要加这一行代码
import paddle.fluid as fluid
import numpy as np
#1.定义网络结构和损失优化
##1.1网络结构,一个简单的线性网络
x=fluid.layers.data(name="x",shape=[13],dtype="float32")#输入13维数据,这里使用输入fluid.layers.data()定义的输入层类似fluid.layers.create_tensor(),也是有name属性,之后也是根据这个属性来填充数据的。
hidden=fluid.layers.fc(input=x,size=100,act="relu")#100个神经元,激活函数是ReLU的全连接层
net=fluid.layers.fc(input=hidden,size=1,act=None)#输出一个预测值
##1.2损失函数,复制主程序用于预测
y=fluid.layers.data(name="y",shape=[1],dtype="float32")
cost=fluid.layers.square_error_cost(input=net,label=y)#这里使用了平方差损失函数(square_error_cost),PaddlePaddle提供了很多的损失函数的接口,比如交叉熵损失函数(cross_entropy)
avg_cost=fluid.layers.mean(cost)#因为fluid.layers.square_error_cost()求的是一个Batch的损失值,所以我们还要对他求一个平均值。
test_program=fluid.default_main_program().clone(for_test=True)#在主程序(fluid.default_main_program)中克隆一个程序作为预测程序,用于训练完成之后使用这个预测程序进行预测数据。
##1.3优化
optimizer=fluid.optimizer.SGDOptimizer(learning_rate=0.01)#使用的随机梯度下降法(SGD),还有Momentum、Adagrad、Adagrad等等
opts=optimizer.minimize(avg_cost)
#2.创建并初始化解释器
place=fluid.CPUPlace()# 创建一个使用CPU的解释器,当使用CPUPlace()时使用的是CPU,如果是CUDAPlace()使用的是GPU
exe=fluid.executor.Executor(place)
exe.run(fluid.default_startup_program())# 解释器进行参数初始化
#3.给训练和测试的张量数据
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]
推荐阅读
-
揭开多智能体强化学习的秘密:理解MADDPG算法的工作机制与简易实现步骤
-
揭开多智能体强化学习的秘密:理解MADDPG算法的工作机制与简易实现步骤
-
【第四课】轻松上手强化学习 - PaddlePaddle与PARL框架的引导教程
-
简易解读:PARL与强化学习基础教程
-
实战入门强化学习RL:初体验GYM与PARL结合应用
-
用百度飞桨PaddlePaddle和PARL平台实践:从基础到进阶——探索强化学习中的PG与PPO算法
-
简易学习:快速掌握 PARL 强化学习框架
-
轻松上手强化学习(1):基础概念解析与Gym、Parl库简介
-
全新解读 PaddlePaddle 的升级亮点:PARL1.1如何通过一个简练修饰器实现高效并行强化学习算法
-
【5】深度解析强化学习中的Sarsa与Q-learning:基于PaddlePaddle(飞桨)的PARL框架详解