0
点赞
收藏
分享

微信扫一扫

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}

代码链接:码云:​​https://gitee.com/dingding962285595/parl_work​​​  ;github:​​https://github.com/PaddlePaddle/PARL​​

​​一、AI Studio 项目详解【VisualDL工具】​​

​​二、AI Studio 项目详解【环境使用说明、脚本任务】​​

​​三、AI Studio 项目详解【分布式训练-单机多机】​​

​​四、AI Studio 项目详解【图形化任务】​​

​​五、AI Studio 项目详解【在线部署及预测】​​

1.前言铺垫


1.1值函数近似

用带参数的Q函数近似,比如使用:多项式函数,神经网络来代替Q表格。【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_深度学习

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_深度学习_02

这里近似可以有不同类别,如上图输入一个状态s和动作a得到一个q值,或者只输入状态s,有多少个动作就输出多少个Q值,右边容易求解最大Q值。

表格法的缺点:                                                        使用值函数近似的优点:

➊表格可能占用极大内存                                           ➊仅需存储有限的参数
②当表格极大时,查表效率低下                                ②状态泛化,相似的状态可以输出一样

神经网络可以逼近任意连续函数

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_03

线性加权+激活函数 就可以拟合非线性函数。

这是一个简单的线性回归模型,来帮助我们快速求解4元一次方程。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_04


代码对应如下:

#加载库
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])
# 定义数据
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(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 = "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(inference_program,
feed={"x": test},
fetch_list=fetch_targets)
# 给出题目为 【9,5,2,10】 输出y=4*9+6*5+7*2+10*2的值
print ("9a+5b+2c+10d={}".format(results[0][0]))


得到结果:

    9a+5b+2c+10d=[99.946]
输出结果应是一个近似等于100的值,每次计算结果略有不同。


2.DQN

先回顾一下Qlearing

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_05

1.首先查表所有动作对应q值取出来,最有动作就是q值最大对应动作,2.在输出给环境,然后输出r和下一状态s   Q(s,a)函数逼近目标值target,maxQ来更新。当然也用sample进行探索。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_06

DQN改进就是用神经网络替代Q表格。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_07

3.DQN创新点

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_08


  • 本质上​​DQN​​​还是一个​​Q-learning​​​算法,更新方式一致。为了更好的探索环境,同样的也采用​​ε-greedy​​方法训练。
  • 在​​Q-learning​​​的基础上,​​DQN​​​提出了两个技巧使得​​Q​​网络的更新迭代更稳定。

  • 经验回放 ​​Experience Replay​​​:主要解决样本关联性和利用效率的问题。使用一个经验池存储多条经验​​s,a,r,s'​​,再从中随机抽取一批数据送去训练。
  • 固定Q目标 ​​Fixed-Q-Target​​​:主要解决算法训练不稳定的问题。复制一个和原来​​Q​​​网络结构一样的​​Target Q​​​网络,用于计算​​Q​​目标值。


是预测的q和targetQ相近,通过loss更新神经网络。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_09

2.1 经验回放

import random
import collections #导入队列库,可以定义经验池队列
import numpy as np


class ReplayMemory(object):
def __init__(self, max_size):
self.buffer = collections.deque(maxlen=max_size) #长度就是经验池容量

def append(self, exp):
self.buffer.append(exp)#增加一条经验(obs, action, reward, next_obs, done )
def sample(self, batch_size):
mini_batch = random.sample(self.buffer, batch_size)
obs_batch, action_batch, reward_batch, next_obs_batch, done_batch = [], [], [], [], []

for experience in mini_batch: #每一条batch分解一下,加到对应数组里
s, a, r, s_p, done = experience
obs_batch.append(s)
action_batch.append(a)
reward_batch.append(r)
next_obs_batch.append(s_p)
done_batch.append(done)

return np.array(obs_batch).astype('float32'), \
np.array(action_batch).astype('float32'), np.array(reward_batch).astype('float32'),\
np.array(next_obs_batch).astype('float32'), np.array(done_batch).astype('float32')

def __len__(self):
return len(self.buffer)



2.2 固定Q目标

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_10

2.3 DQN流程

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_11

在parl里面单独把DQN算法提取出来

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_12

4.PARL的架构DQN详细讲解如下:

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_13

可以比较方便的应用在其他深度学习环境下。这样的算法看起来会比较整洁5个文件:

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_14

​Agent​​​把产生的数据传给​​algorithm​​​,​​algorithm​​​根据​​model​​​的模型结构计算出​​Loss​​​,使用​​SGD​​​或者其他优化器不断的优化,​​PARL​​这种架构可以很方便的应用在各类深度强化学习问题中。

4.1 model:

  • ​Model​​​用来定义前向(​​Forward​​)网络,用户可以自由的定制自己的网络结构。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_15 【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_16

4.2 algorithm:

  • ​Algorithm​​​ 定义了具体的算法来更新前向网络(​​Model​​​),也就是通过定义损失函数来更新​​Model​​​,和算法相关的计算都放在​​algorithm​​中。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_17

将model的参数同步到target_model中,调用这个API就好。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_18

预测:

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_19

4.3 learn():

                      【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_20

target Q计算公式 和Qlearing一样,if episode是最后一个则没有下一个状态,就是当前reward。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_21

分成三部分,得到Q目标值、在获取预测值,最后得到LOSS。

阻止梯度传递,target_q 用到的是target_model的值,而target_model的值需要固定不动的,所以切断联系,避免优化器找到所有和cost有关的参数进行一起优化。

  • 小技巧:terminal就是done,【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_22

     这行代码把if else都写出来了,如果是true就是1 false就是0 

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_23

      true的话就是1,后项式整体为0.

  • pred_value拿到的是pred_value = [[2.3, 5.7, 1.2, 3.9, 1.4]],拿到所有a对应的Q了,然后把Q先转换到onehot向量3 => [0,0,0,1,0]   2 => [0,0,1,0,0]

      【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_24

安位相乘再相加,就得到3.9了。即Q(s,a)

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_25

计算均方差、在用adm优化器优化。

  • ​Agent​​​ 负责算法与环境的交互,在交互过程中把生成的数据提供给​​Algorithm​​​来更新模型(​​Model​​),数据的预处理流程也一般定义在这里。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_26

每200step同步一次网络。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_27

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_强化学习_28

每运行一次run就完成一次网络的更新。

获取计算Q值

with fluid.program_guard(self.pred_program):  # 搭建计算图用于 预测动作,定义输入输出变量
obs = layers.data(
name='obs', shape=[self.obs_dim], dtype='float32')
self.value = self.alg.predict(obs)

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_29

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_30

5.cartpole测试

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_深度学习_31

5.1 main.py 代码流程图体现:


 【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_神经网络_32【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_33

每训练50个episode,评估5次【多次】再求平均,避免偶然性。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_深度学习_34

训练时运行learn更新Q算法。

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_机器学习_35

render为true,则显示需打印内容,等于设置了一个标记。



6.PARL常用APi

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_paddle_36

7.总结:

【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}_深度学习_37

软更新:​应该是指每次更新参数的时候利用一个衰减的比例

硬更新:​则是指每隔一定步数完全Copy参数



举报

相关推荐

DQN强化学习

0 条评论