美文网首页
强化学习之Q-learning

强化学习之Q-learning

作者: CristianoC | 来源:发表于2019-07-17 16:18 被阅读0次

    部分专有名词在上一篇文章有介绍,本文不作过多赘述。

    目录

    • 前言
    • 算法思想
    • 算法详解
    • 算法公式
    • 探险者寻宝藏实战(一维)

    前言

    image

    我们做事情都会有自己的一个行为准则,比如小时候爸妈常说“不写完作业就不准看电视”。所以我们在写作业的状态(state)下,好的行为就是继续写作业,直到写完它,我们还可以得到奖励(reward),不好的行为就是没写完作业就跑去看电视了,被爸妈发现就会被惩罚,这种事情做的多了,也变成了我们不可磨灭的记忆,这其实就是一个Q-learning的决策过程。

    算法思想

    Q-Learning是强化学习算法中value-based的算法,Q即为Q(s,a),就是在某一个时刻的state状态下,采取动作a能够获得收益的期望,环境会根据agent的动作反馈相应的reward奖赏,所以算法的主要思想就是将stateaction构建成一张Q_table表来存储Q值,然后根据Q值来选取能够获得最大收益的动作。

    Q-learning的主要优势就是使用了时间差分法(融合了蒙特卡洛和动态规划)能够进行off-policy的学习,使用贝尔曼方程可以对马尔科夫过程求解最优策略,本文对其中算法不进行推导,会另外写一篇推导的文章。

    image

    算法详解

    我们还是用一开始举的做作业的例子来说明:

    image
    假设我们的行为准侧已经学习好了,现在我们处于状态s1,我在写作业,我有两个行为a1,a2,分别是看电视和写作业,根据我的经验(Q-table)知道,在s1的状态下,我选择a2写作业带来的reward奖赏比a1看电视高,在我的Q-table中,Q(s1,a1)=-2要小于Q(s1,a2)=1,所以我们判断要选择a2写作业作为我们的下一个行为。现在我们的状态更新成s2,我们还是有两个同样的选择,重复上面的过程,在行为准则Q-table中寻找Q(s2,a1)Q(s2,s2)的值,并比较他们的大小,选取较大的一个。接着根据a2我们到达s3并重复上述的决策过程,Q-learning的方法就是这样抉择的。那我们的Q-table这张行为决策表又是如何决策的呢?我们来看看。
    image
    回到之前的流程,根据Q表的估计,因为在s1中,a2的值比较大,通过之前的决策方法我们在s1选择了a2,并到达s2,这时我们开始更新用于决策的Q表,接着我们并没有在实际中采取任何行为,而是在想象自己在s2上采取了a1,a2两个行为,分别看看两种行为哪一个的Q值大,比如说Q(s2,a2)的值比Q(s2,a1)的大,所以我们把大的Q(s2,a2)乘上一个衰减值gamma(eg 0.9)并加上到达s2时所获得的奖励Reward(这里没有获取到我们的棒棒糖,所以奖励为0),因为会获取实实在在的奖励Reward,所以我们将这个作为我们现实中Q(s1,a2)的值,但是我们之前是根据Q表估计Q(s1,a2)的值。所以有了现实值和估计值,我们就可以更新Q(s1,a2)的值,变成新的值。但时刻记住,我们虽然用maxQ(s2)估算了一下s2的状态,但还没有在S2做出任何行为,s2的行为决策要等到更新完了以后再重新另外做,这就是off-policyQ-learning是如何决策和学习优化决策过程。

    算法公式

    image
    这一张图概括了我们之前所有的内容。这也就是Q-learning算法,每次更新我们都用到了Q现实Q估计,而且Q-learning迷人之处就是在Q(s1,a2)现实中,包含了一个Q(s2)的最大估计值,将对下一步衰减的最大估计和当前所得到的奖励作为这一步的现实。

    参数介绍

    • Epsilon greedy:是用在决策上的一个策略,比如epsilon = 0.9的时候,就说明百分之90的情况我会按照Q表的最优值选择行为,百分之10的时间随机选择行为。
    • alpha:学习率,决定这次的误差有多少是要被学习的。
    • gamma:对未来reward的衰减值。gamma越接近1,机器对未来的reward越敏感

    探险者寻宝藏实战(一维)

    背景

    在一个一维时间,在世界的右边有宝藏,探险者只要得到宝藏尝到了甜头,以后就会记住得到宝藏的方法,这就是他用强化学习所学习到的行为。

    image
    在这个游戏中,o所在的每个地点就是每个状态,而每个地点探险者所可以做出left/right两个行为,这就是探险者可以做出的action,而每种行为在每个状态下都会有一个值,也就是Q(s,a),如果在某个地点s1,探险者计算了Q(s1,a1)和Q(s1,a2),如果前者大于后者,那么探险者就会选择left这个行为,这就是行为准则

    预设参数

    import numpy as np
    import pandas as pd
    import time
    
    np.random.seed(2)  # reproducible
    
    N_STATES = 6 #一维世界的宽度
    ACTIONS = ['left','right'] #探索者可用的动作
    EPSILON = 0.9 #greedy贪婪度
    ALPHA = 0.1 #学习率
    GAMMA = 0.9 #奖励递减值
    MAX_EPISODES = 13 #最大回合数
    FRESH_TIME = 0.3 #每回合移动间隔时间
    

    Q表

    我们要将所有Q values放在q_table中,更新q_table也是在更新他的行为准则。q_tableindex是所有对应的state(o所在的位置)columns是对应的action(探险者选择left或者right)

    def build_q_table(n_states, actions):
        table = pd.DataFrame(
            np.zeros((n_states, len(actions))),     # q_table 全 0 初始
            columns=actions,    # columns 对应的是行为名称
        )
        return table
    
    # q_table:
    """
       left  right
    0   0.0    0.0
    1   0.0    0.0
    2   0.0    0.0
    3   0.0    0.0
    4   0.0    0.0
    5   0.0    0.0
    """
    

    定义action

    接着定义探险者是如何挑选行为的,这就是我们引入epsilon greedy的概念。因为在初始阶段,随机的探索环境,往往比固定的行为模式要好,所以这也是累积经验的阶段,我们希望探险者不那么贪婪(greedy),所以EPSILON就是用来控制贪婪程度的值。EPSILON可以随着探险时间不断提升(越来越贪婪),不过在这个例子中,我们就固定EPSILON=0.9,90%的时间是选择最优策略,10%的时间来探索。

    def choose_action(state, q_table):
        state_actions = q_table.iloc[state, :]  # 选出这个state的所有 action的value值
        if (np.random.uniform() > EPSILON) or (state_actions.all() == 0):  #非贪婪 or 或者这个 state 还没有探索过
            action_name = np.random.choice(ACTIONS)
        else:
            action_name = state_actions.idxmax()    # 贪婪模式
        return action_name
    

    环境的反馈S_,R

    做出行为后,环境也要给我们的行为一个反馈,反馈出下一个state(S_)和上一个state(S)做出action(A)所得到的reward(R)。这里定义的规则是,只有当o移动到了T(探险者获取了宝藏),探险者才会得到唯一的奖励,奖励值R=1,其他情况没有奖励。

    def get_env_feedback(S,A):
        if A== 'right': #往右探险
            if S == N_STATES - 2: #找到宝藏
                S_ = 'terminal'
                R = 1
            else:
                S_ = S + 1
                R = 0
        else: #往左探险
            R = 0
            if S == 0:
                S_ = S #碰壁
            else:
                S_ = S - 1
        return S_,R
    

    环境更新

    接下来就是环境的更新了,这里不多赘述。

    def update_env(S, episode, step_counter):
        env_list = ['-']*(N_STATES-1) + ['T']   # '---------T' our environment
        if S == 'terminal':
            interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
            print('\r{}'.format(interaction), end='')
            time.sleep(2)
            print('\r                                ', end='')
        else:
            env_list[S] = 'o'
            interaction = ''.join(env_list)
            print('\r{}'.format(interaction), end='')
            time.sleep(FRESH_TIME)
    

    强化学习的主循环

    最重要的地方就是这里,将刚才理论部分我们讲解到的算法实现出来。

    def rl():
        q_table = bulid_q_table(N_STATES,ACTIONS) #初始化q_table
        for episode in range(MAX_EPISODES): #回合
            step_counter = 0
            S = 0 #回合初始的位置
            is_terminated = False
            update_env(S,episode,step_counter) #环境更新
            while not is_terminated:
    
                A = choose_action(S,q_table) #选择行为
                S_,R = get_env_feedback(S,A) #实施行为并得到环境的反馈
                q_predict = q_table.loc[S,A] #估算的(状态-行为)值
                if S_ != 'terminal':
                    q_target = R + GAMMA*q_table.iloc[S_,:].max() #实际的(状态-行为)值
                else:
                    q_target = R #实际的(状态-行为值)
                    is_terminated = True
    
                q_table.loc[S,A] += ALPHA*(q_target - q_predict) #q_table更新
                S = S_ #更新探索者位置
    
                update_env(S,episode,step_counter+1)
    
                step_counter += 1
        return q_table
    

    结果

    我们可以看到,一开始没有任何经验的探险者需要非常多次的尝试才能找到宝藏,而随着探险次数的增多,最后就可以自己走到宝藏的地方了。


    image
    image
    image

    参考:
    https://github.com/MorvanZhou

    相关文章

      网友评论

          本文标题:强化学习之Q-learning

          本文链接:https://www.haomeiwen.com/subject/beqclctx.html