欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

简易解读: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]