深度强化学习(DRL)三:从Q-learning到Deep Q Network(DQN)

本文深入探讨了强化学习的核心算法,从Q-learning的基础概念出发,逐步过渡到深度强化学习的DeepQNetwork(DQN)及其改进版DoubleDQN。详细解析了算法原理,包括Q-table的构建、Q值更新公式、神经网络的应用以及如何避免过估计等问题。

一、Q-learning

关于Q-learning,网上的资料很多。

在这里插入图片描述

Q-learning最核心的是有一个Q表,它记录了在环境中的 所有状态(s) 以及每个状态可以进行的 所有行为(a) 的Q值,初值设为0。

状态 \ 行为 a1 a2 a3 a4
s1
s2
s3
……

Q值的更新公式如下:

Q ( s , a ) ← Q ( s , a ) + α [ r + γ m a x a ′ ​ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a)←Q(s,a)+α[r+\gamma max_{a'}​Q(s^′,a^′)−Q(s,a)] Q(s,a)Q(s,a)+α[r+γmaxaQ(s,a)Q(s,a)]

  • 其中 α α α表示学习速率,取值小于1
  • r r r是设置的奖励
  • 智能体在状态s经过行为a转移到状态s’, m a x a ′ ​ Q ( s ′ , a ′ ) max_{a'}​Q(s^′,a^′) maxaQ(s,a) 是状态 s ′ s' s 那一行最大Q值
  • γ \gamma γ则是衰减速率,取值在0到1之间, γ \gamma γ越大,智能体就会越注重长期利益, γ \gamma γ越小,智能体越短视。

每改变一次状态就会更新一次Q值

Q-learning 是一个 off-policy 的算法,它可以离线学习。它可以随机进行若干次游戏,将游戏过程保存起来,学习的时候就可以避免陷入局部最优。

Q-learning 的代码实现:

# -*- coding: UTF-8 -*-
import numpy as np
import pandas as pd


class QLearningTable:
    def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
        self.actions = actions  # a list
        self.lr = learning_rate
        self.gamma = reward_decay
        self.epsilon = e_greedy
        self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64)

    def choose_action(self, observation):
        self.check_state_exist(observation)
        # action selection
        if np.random.uniform() < self.epsilon:
            # choose best action
            state_action = self.q_table.loc[observation, :]
            state_action = state_action.reindex(np.random.permutation(state_action.index))     # some actions have same value
            action = state_action.idxmax()
        else:
            # choose random action
            action = np.random.choice(self.actions)
        return action

    def learn(self, s, a, r, s_):
        self.check_state_exist(s_)
        q_predict = self.q_table.loc[s, a]
        if s_ != 'terminal':
            q_target = r + self.gamma * self.q_table.loc[s_, :].max()  # next state is not terminal
        else:
            q_target = r  # next state is terminal
        self.q_table.loc[s, a] += self.lr * (q_target - q_predict)  # update

    def check_state_exist(self, state):
        if state not in self.q_table.index:
            # append new state to q table
            self.q_table = self.q_table.append(
                pd.Series(
                    [0]*len(self.actions),
                    index=self.q_table.columns,
                    name=state,
                )
            )

二、Deep Q Network

如果想用Q-learning玩之前的CartPole-v0游戏,会发现CartPole-v0的状态值太多了,它的observation有 车的位置,车的速度,杆子的角度,杆子顶端的速度 四个值,并且是连续的数值,四个值再进行量化,Q表实在是太大了。用Q-learning玩游戏和随机玩游戏没区别,学习不到东西。可能Q-learning只适用于走迷宫类的游戏,每一步的状态都可以很简单的描述出来,4*4的迷宫只需要用16个状态就可以全部囊括。

我们用Deep Q Network来解决这个问题, Deep Q Network融合了神经网络和 Q learning。

  • 我们可以将状态和动作当成神经网络的输入, 然后经过神经网络分析后得到动作的 Q 值, 这样我们就没必要在表格中记录 Q 值, 而是直接使用神经网络生成 Q 值.
  • 或者只输入状态值, 输出所有的动作值, 然后按照 Q learning 的原则, 直接选择拥有最大值的动作当做下一步要做的动作.
    在这里插入图片描述

需要搭建两个神经网络,target_net 和 eval_net ,
target_net 用于预测 q_target 值, 他不会及时更新参数.
target_net 用于预测 q_eval, 这个神经网络拥有最新的神经网络参数.

两个神经网络结构是完全一样的, 只是里面的参数不一样. target_net 是 eval_net 的一个历史版本, 拥有 eval_net 很久之前的一组参数, 而且这组参数被固定一段时间, 然后再被 eval_net 的新参数所替换. 而 eval_net 是不断在被提升的。这样做是为了打乱数据间的相关性,避免陷入局部最优。

神经网络的输入数据是[s,a,r,s’],输出数据是状态s下所有行为a的Q值。
target_net 只会输出Q值(q_target ),不会进行训练,而eval_net 输出Q值(q_eval)之后会根据q_target和q_eval进行反向传播训练,更新eval_net 的参数。

Deep Q Network整个算法的运作:

  1. 初始化target_net 和 target_net。
  2. 观察游戏状态observation,选择合适的observation作为输入,一般情况会对observation做数据处理,使其更容易训练,这里不用。
  3. 设置合适的奖励reward。
  4. 先进行若干次游戏,将游戏数据存储到memory中。
  5. 从memory中随机选取训练数据batch_memory用于批量训练。
  6. 训练eval_net 一段时间后,将eval_net 的参数复制给target_net 。
  7. 训练过程中产生的新的游戏数据会替代memory中的旧数据。

回到游戏CartPole-v0

DQN.py:

import numpy as np
import tensorflow as tf

np.random.seed(1)
tf.set_random_seed(1)


# Deep Q Network off-policy
class DeepQNetwork:
    def __init__(
            self,
            n_actions,
            n_features,
            learning_rate=0.01,
            reward_decay=0.9,
            e_greedy=0.9
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值