首页 > 技术文章 > 强化学习学习笔记——粗略版

fusheng-rextimmy 2021-10-01 10:02 原文

Reinforcement Learning

摘要

根据莫烦老师的强化学习课程整理的笔记

课程链接

https://mofanpy.com/tutorials/machine-learning/reinforcement-learning/

overview

  • policy——exploration&exploitation

    graph LR a[agent learner]--"action"-->b[environment] b[environment]--"state"-->a[agent learner] b[environment]--reward-->a[agent learner]
  • solutions

    • 分类1
      • 不理解环境 Model-Free RL 无需对世界建模,只能对现实世界采取行动,所见即所得
        • Q learning
        • Sarsa
        • Policy Gradients
      • 理解环境 Model-Based RL 需要对世界建模,可以在虚拟世界中根据预判选择最好的决策
        • Q learning
        • Sarsa
        • Policy Gradients
    • 分类2
      • 基于概率 Policy-Based RL
        • 根据感知环境选择概率最高的方案
        • 每种方案都可能被选择,只是可能性不同
        • 离散和连续动作都适用
        • Policy Gradients
      • 基于价值 Value-Based RL
        • 根据感知环境选择价值最高的方案
        • 只选择价值最高的方案,判断标准很强硬
        • 只适用于离散动作
        • Q learning
        • Sarsa
      • 将基于价值和概率的方法结合 Actor-Critic
        • actor基于概率做出动作
        • critic给动作打分进行择优
    • 分类3
      • 回合更新 Monte-Carlo update
        • 在每一阶段结束后才更新状态
        • 基础版Policy Gradients
        • Monte-Carlo Learning
      • 单步更新 Temporal-Difference update
        • 在每一阶段中的每一步后都更新状态,边进行边学习
        • Q Learning
        • Sarsa
        • 升级版Policy Gradients
    • 分类4
      • 在线学习 On-Policy
        • 只能从自身行为学习
        • Sarsa
        • Sarsa(\(\lambda\))
      • 离线学习 Off-Policy
        • 可以通过观察其他个体行为或者自己行为来学习
        • Q Learning
        • Deep Q Network

Q Learning —— Off-policy(离线学习型) —— 激进型

初始状态s1时,有两种行动方案可以选择

graph LR a[state1]-->b[action1] a[state1]-->c[action2]

Q表:

a1 a2
s1 -2 1

因为a2值更高,所以选择a2作为本次行动方案,此时进入新的状态s2

graph LR a[state2]-->b[action1] a[state2]-->c[action2]

Q表:

a1 a2
s2 -4 2

因为a2值更高,所以选择a2作为本次行动方案,此时进入新的状态s3,往复循环

Q表值更新的过程为:

  • 先判断Q表中哪个行动的值最大,然后乘以一个衰减值\(\gamma\) ,并加上到达s2时获得的奖励R

    \(Q(s1,a2)现实=R+\gamma*maxQ(S2)\)

    \(Q(s1,a2)估计=Q(s1,a2)\)

    差距=现实-估计

    \(新Q(s1,a2)=老Q(s1,a2)+\alpha*差距\)

  • 伪代码

    Initialize \(Q(s,a)\) arbitrarily
    Repeat (for each episode):
    Initialize \(s\)
    Repeat (for each step of episode):
    choose \(a\) from \(s\) using policy derived from \(Q\)(e.g.,\(\varepsilon\)-greedy)
    Take action \(a\),observe \(r,s'\)
    \(Q(s,a)\leftarrow Q(s,a)+\alpha[r+\gamma max_{a'}Q(s',a')-Q(s,a)]\)
    \(s\leftarrow s'\);
    until \(s\) is terminal

    • 注释
      • \(r+γmax_{a'}Q(s',a')\) —— Q(s1,a2)现实
      • \(Q(s',a')\) —— Q(s2)最大估计
      • \(Q(s,a)\) —— Q(s1,s2)估计
      • \(\varepsilon\)-greedy是决策概率,例如\(\varepsilon\)-greedy=0.9则我们会按照90%概率按照Q表的最优值选择行为,另外10%随机选择行为
      • \(\alpha\)表示学习率,决定这次误差有多少要被学习,\(\alpha<1\)
      • \(\gamma\)是对未来奖励的衰减值
        • \(Q(s1)=r2+\gamma Q(s2)=r2+\gamma [r3+\gamma Q(s3)]=...=r2+\gamma r3+\gamma^2r4+\gamma^3r5+...\)
        • 可以看出Q表中的s1值与往后的所有奖励都有关,但是影响都是不断衰减的
        • \(\gamma=0\)时agent只能看到眼前的奖励\(Q(s1)=r2\),看不到后期的奖励
        • \(\gamma=1\)时agent能看到后期所有的奖励\(Q(s1)=r2+r3+r4+...\)
        • \(\gamma\in(0,1)\)时agent能够逐渐看到后期所有的奖励,会变得有远见,为自己未来的利益着想
例子

Q-learning 是一种记录行为值 (Q value) 的方法, 每种在一定状态的行为都会有一个值 Q(s, a), 就是说 行为 as 状态的值是 Q(s, a). s 在上面的探索者游戏中, 就是 o 所在的地点了. 而每一个地点探索者都能做出两个行为 left/right, 这就是探索者的所有可行的 a 啦.

如果在某个地点 s1, 探索者计算了他能有的两个行为, a1/a2=left/right, 计算结果是 Q(s1, a1) > Q(s1, a2), 那么探索者就会选择 left 这个行为. 这就是 Q learning 的行为选择简单规则.

import numpy as np
import pandas as pd
import time

from pandas import DataFrame


N_STATES = 6  # the length of the 1 dimensional world
ACTIONS = ['left', 'right']  # available actions
EPSILION = 0.9  # greedy police 贪婪程度
ALPHA = 0.1  # learning rate
LAMBDA = 0.9  # discount factor 奖励递减值
MAX_EPISODES = 13  # maximum episodes 最大游戏回合数
FRESH_TIME = 0.01  # fresh time for one move


def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))), # q_table 全 0 初始
        columns=actions,  # actions' name
    )
    return table


def choose_action(state, q_table):
    # this is how to choose an action
    state_actions = q_table.iloc[state, :]
    if (np.random.uniform() > EPSILION) or (state_actions.all() == 0):
        action_name = np.random.choice(ACTIONS) # act randomly
    else: # act greedy
        action_name = state_actions.idxmax()
    return action_name


def get_env_feedback(S, A):
    # this is how agent will interact with the environment
    if A == 'right':  # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1
        else:
            S_ = S + 1
            R = 0
    else:   # move left
        R = 0
        if S == 0:
            S_ = S  # reach the wall
        else:
            S_ = S - 1
    return S_, R


def update_env(S, episode, step_counter):
    # this is how environment be updated
    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():
    # main part of RL loop
    q_table = build_q_table(N_STATES, ACTIONS)   # create 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)  # take action & get next state and reward
            q_predict = q_table.loc[S, A]    # 估计值
            if S_ != 'terminal':
                q_target = R + LAMBDA * q_table.iloc[S_, :].max()    # next state is not terminal
            else:
                q_target = R    # next state is terminal
                is_terminated = True

            q_table.loc[S, A] += ALPHA*(q_target - q_predict)     # update
            S = S_  # move to next state

            update_env(S, episode, step_counter+1)
            step_counter += 1
    return q_table


if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-TABLE:\n')
    print(q_table)
    
    
--------------------------RUN---------------------------------------
Q-TABLE:

       left     right
0  0.000001  0.005655
1  0.000001  0.029346
2  0.000076  0.115616
3  0.002236  0.343331
4  0.000810  0.745813
5  0.000000  0.000000

right对应的值都比left高,反应了对奖励的反馈

Sarsa —— On-policy(在线学习型) —— 保守型

我们会经历正在写作业的状态 s1, 然后再挑选一个带来最大潜在奖励的动作 a2, 这样我们就到达了 继续写作业状态 s2, 而在这一步, 如果你用的是 Q learning, 你会观看一下在 s2 上选取哪一个动作会带来最大的奖励, 但是在真正要做决定时, 却不一定会选取到那个带来最大奖励的动作, Q-learning 在这一步只是估计了一下接下来的动作值. 而 Sarsa 是实践派, 他说到做到, 在 s2 这一步估算的动作也是接下来要做的动作. 所以 Q(s1, a2) 现实的计算值, 我们也会稍稍改动, 去掉maxQ, 取而代之的是在 s2 上我们实实在在选取的 a2 的 Q 值. 最后像 Q learning 一样, 求出现实和估计的差距 并更新 Q 表里的 Q(s1, a2).

和Q learning的不同在于更新方式,Q learning在做出下一步决策前会估算一下哪个行为会带来最大奖励,但是却不一定会选择这个对应最大奖励的行为,Sarsa则不同,他说到做到,此时的估计值也是他接下来要做的行为,因此也称Sarsa为在线学习型,他所学习的是他自己的行为

On-policy方法在一定程度上解决了exploring starts这个假设,让策略既greedy又exploratory,最后得到的策略也一定程度上达到最优。Off-policy方法就更加直接了,分别在策略估计和策略提升的时候使用两种策略,一个具有探索性的策略专门用于产生episode积累经验,称为behavior policy,另一个则是更具贪婪性,用来学习成为最优策略的target policy。

Q表值更新的过程为:

  • 先判断Q表中哪个行动的值最大,然后乘以一个衰减值\(\gamma\) ,并加上到达s2时获得的奖励R

    \(Q(s1,a2)现实=R+\gamma*Q(S2)\)

    \(Q(s1,a2)估计=Q(s1,a2)\)

    差距=现实-估计

    \(新Q(s1,a2)=老Q(s1,a2)+\alpha*差距\)

  • 伪代码

    Initialize \(Q(s,a)\) arbitrarily
    Repeat (for each episode):
    Initialize \(s\)
    Repeat (for each step of episode):

    ​ Take action \(a\),observe \(r,s'\)

    ​ choose \(a'\) from \(s'\) using policy derived from \(Q\)(e.g.,\(\varepsilon\)-greedy)

    \(Q(s,a)\leftarrow Q(s,a)+\alpha[r+\gamma Q(s',a')-Q(s,a)]\)
    \(s\leftarrow s'\);\(a\leftarrow a'\)
    until \(s\) is terminal

    • 注释
      • \(r+γQ(s',a')\) —— Q(s1,a2)现实
      • \(Q(s',a')\) —— Q(s2)最大估计
      • \(Q(s,a)\) —— Q(s1,s2)估计
      • \(\varepsilon\)-greedy是决策概率,例如\(\varepsilon\)-greedy=0.9则我们会按照90%概率按照Q表的最优值选择行为,另外10%随机选择行为
      • \(\alpha\)表示学习率,决定这次误差有多少要被学习,\(\alpha<1\)
      • \(\gamma\)是对未来奖励的衰减值
        • \(Q(s1)=r2+\gamma Q(s2)=r2+\gamma [r3+\gamma Q(s3)]=...=r2+\gamma r3+\gamma^2r4+\gamma^3r5+...\)
        • 可以看出Q表中的s1值与往后的所有奖励都有关,但是影响都是不断衰减的
        • \(\gamma=0\)时agent只能看到眼前的奖励\(Q(s1)=r2\),看不到后期的奖励
        • \(\gamma=1\)时agent能看到后期所有的奖励\(Q(s1)=r2+r3+r4+...\)
        • \(\gamma\in(0,1)\)时agent能够逐渐看到后期所有的奖励,会变得有远见,为自己未来的利益着想

推荐阅读