DQN算法的原理与复现

基本思路

先来解释下Q-learning
简单来说就是瞬时奖励+记忆经验奖励。

瞬时奖励:做了一个动作就能获得的奖励

经验奖励:按照训练时的经验,上一系列动作发生之后,接下来怎么做才能获得更大的奖励,换句话就是说根据复盘经验去研究如何更好地补刀,从而形成一系列的动作(连招)

DQN自然就是加入深度神经网络进行预测,我们先来看看Q-learning是如何运行的

1收集数据(即游戏记录)
在这里插入图片描述
2令目标等于以下公式(获得价值最高的选择):
在这里插入图片描述
3目标函数(获得最小的误差)
在这里插入图片描述

整体流程
在这里插入图片描述
伽马值(就是那个很像r的)用于减少下一步的贡献度,因为下一步与上一步紧密相连,故不能减少太多,我们也是将其设置为0.99
在这里插入图片描述
因为其是瞬时奖励,加的是记忆中价值量最大的动作,但也终归是记忆中的,我们要对其影响做一个削弱,构成一个估计值

举个通俗的例子,走迷宫
状态0,1,2,3,4,5,其中5是出口
目标就是能走出去
并非每个状态都是互通的(比如2到3)
通过不断地迭代让智能体逃出去
在这里插入图片描述
5是出口我们就直接把运行到状态5的奖励设为100,其余为0
在这里插入图片描述
数据的格式
对R与Q进行初始化
Q是一个由0构成的没有实际意义的空表,要不断地进行填充
行为state,列为action
在这里插入图片描述
-1表示此路不通,只要没到5,奖励都为0

开始迭代
假设初始化状态为1
根据右表action只能选择3和5
此时选择3还是5呢,当前的Q为空表,按理来说是要比较这两个选择的价值的,但是我们是从0开始训练,故我们只能先随机选一个,比如5
接下来就到了状态5,此时有三种选择,1,4,5,选哪个呢

在这里插入图片描述
在这里插入图片描述
其中0.8是伽马值,就是折扣因子,相当于经验记忆奖励的权重,然后由此我们就得到了Q(1,5),5亦代表了游戏结束
如此重复,尽可能地把每个可能性都试一遍,这也是为什么次数越多模型的准确度越高的原因,联想一波蒙特卡洛即可。

那么我们想一下,如果放到游戏画面,我们真的能做到穷举吗,那个像素点太多了,Q(s,a)就不能用表格来表达了,于是我们想到了用神经网络去表达,现在一般的方法是构建一个 replay buffers 到时候去里面取一个batch就行,其实就是off policy策略,这个策略的代码构建还是比较容易的,

在这里插入图片描述
对DQN的改进
在这里插入图片描述
在这里插入图片描述

第一种改进,double-dqn
在这里插入图片描述
红色为目标,蓝色为模型达到的程度
换句话说就是模型高估了自己
在这里插入图片描述

为了提升模型效果,我们在原来训练的基础上再用另一个神经网络训练一次
在这里插入图片描述

注意,里面的括号下方的小A与小B都代表一个神经网络

第二种改进,dueling-dqn

在同一个网络中分别嫁接两个全连接层,以此为原理使得网络能同时更新相同state下不同的行为(action)可能导致的结果
在这里插入图片描述

在这里插入图片描述
也就是说其实只有V(s)是变量用于微调

mulit-step-dqn策略
就像下围棋一样,
不光要看眼前的下一步,也要看下N步的结果,该算法就是在计算Q值得时候选择多个时间步

只看下一步
在这里插入图片描述
只看下N步
在这里插入图片描述
联想下梯度下降中的随机/批量,这个就是小批量

连续值的处理方法-连续动作
在这里插入图片描述
这就是一个求极值的问题,常用的解法有采样,梯度上升
不断地运行,并比较,选择一个最大值就可以了
在这里插入图片描述
问题来了,这样子不断地运算,动作越多计算的负担越大,于是我们要优化计算方法,改变数据的输入格式
在这里插入图片描述
即重新定义Q网络,输出三个结果分别是向量,矩阵,值

由此构成新的公式
在这里插入图片描述
在这里插入图片描述
这个是恒为正的,
在这里插入图片描述
此时代入Q(s,a)即可得出
在这里插入图片描述

部分代码复现

训练网络

while True:

	env.render()
	action = RL.choose_action(observation)#根据状态选择行动
	observation_,reward,done = env.step(action)#定义更新环境
	RL.store_transition(observation,action,reward,observation_)
	if (step>x) and (step%y== 0):#一定的次数后学习
		RL.learn()
		observation = observation_
	if done:
		break
	step += 1
	

在这里插入图片描述

行动参数更新


def choose_action(self,observation):
	observation = observation[np.newaxis,:]
	if np.random.uniform() < self.epsilon:
		actions_value = self.sess.run(self.q_eval,feed_dict = {self.s:observation})
		action = np.argmax(actions_value)#选择最高价值的行动
	else:
		action = np.random.randint(0,self.n_actions)
	return action

经验池


def store_transition(self,s,a,r,s_):

	if not hasattr(self,'memory_counter'):
		self.memory_counter = 0#计数器
		transition = np.hstack(s,[a,r],s_)
		index = self.memory_counter%self.memory_size#样本数量超过经验池大小时开始覆盖
		self.memory[index,:] = transition
		self.memory_counter += 1

学习函数

#学习函数
def leran(self):
	q_traget = q_eval.copy()
	batch_index = np.arange(self.batch_size,dtype = np.int32)
	eval_act_index = batch_memory[:,self.n_fextures].astype(int)
	reward = batch_memory[;self.n_fextures +1]
	q_traget[batch_index,eval_act_index] = reward + self.gamma * np.max(q_next,axis = 1)
	-,self.cost = self.sess.run([self._train_op,self.loss],feed_dict = {self.s:batch_memory[:,:self.n_fextures],self.q_traget:q_traget})
	self.cost_his.append(self.cost)

网络搭建

def _build_net(self):
        #----------------构建评估网络------------------
        self.s = tf.placeholder(tf.float32, [None, self.n_features], name='s')  # 输入
        self.q_target = tf.placeholder(tf.float32, [None, self.n_actions], name='Q_target')  #计算loss
        with tf.variable_scope('eval_net'):
            # c_names(collections_names) )是存储变量的集合
            c_names, n_l1, w_initializer, b_initializer = \
                ['eval_net_params', tf.GraphKeys.GLOBAL_VARIABLES], 10, \
                tf.random_normal_initializer(0., 0.3), tf.constant_initializer(0.1)  #网络层的参数

            # 第一层。稍后分配给目标网络时使用集合
            with tf.variable_scope('l1'):
                w1 = tf.get_variable('w1', [self.n_features, n_l1], initializer=w_initializer, collections=c_names)
                b1 = tf.get_variable('b1', [1, n_l1], initializer=b_initializer, collections=c_names)
                l1 = tf.nn.relu(tf.matmul(self.s, w1) + b1)

            # 第二层。稍后分配给目标网络时使用集合
            with tf.variable_scope('l2'):
                w2 = tf.get_variable('w2', [n_l1, self.n_actions], initializer=w_initializer, collections=c_names)
                b2 = tf.get_variable('b2', [1, self.n_actions], initializer=b_initializer, collections=c_names)
                self.q_eval = tf.matmul(l1, w2) + b2

        with tf.variable_scope('loss'):
            self.loss = tf.reduce_mean(tf.squared_difference(self.q_target, self.q_eval))
        with tf.variable_scope('train'):
            self._train_op = tf.train.RMSPropOptimizer(self.lr).minimize(self.loss)

        # ------------------ 构建目标网络 ------------------
        self.s_ = tf.placeholder(tf.float32, [None, self.n_features], name='s_')    # input
        with tf.variable_scope('target_net'):
            # c_names(collections_names) 是存储变量的集合
            c_names = ['target_net_params', tf.GraphKeys.GLOBAL_VARIABLES]

            # 第一层。稍后分配给目标网络时使用集合
            with tf.variable_scope('l1'):
                w1 = tf.get_variable('w1', [self.n_features, n_l1], initializer=w_initializer, collections=c_names)
                b1 = tf.get_variable('b1', [1, n_l1], initializer=b_initializer, collections=c_names)
                l1 = tf.nn.relu(tf.matmul(self.s_, w1) + b1)

            # 第二层。稍后分配给目标网络时使用集合
            with tf.variable_scope('l2'):
                w2 = tf.get_variable('w2', [n_l1, self.n_actions], initializer=w_initializer, collections=c_names)
                b2 = tf.get_variable('b2', [1, self.n_actions], initializer=b_initializer, collections=c_names)
                self.q_next = tf.matmul(l1, w2) + b2
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丰。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值