本文是对莫烦的强化学习课程的总结以及自己的理解,若有侵权,请联系删除

强化学习方法汇总

不理解环境(model-free RL) 理解环境(model based RL)
只根据环境反馈进行学习 构建出环境的虚拟模型
Q Learning model-free能用的算法model based都能用,
只不过model based可以在虚拟世界里学习
Sarsa 根据想象预判接下来要发生的事情,然后选择最好的执行
Policy Gradient  
基于概率(policy-free RL) 基于价值(value based RL)
生成所有动作的概率,根据概率选动作 生成所有动作的价值,根据最高价值选动作
policy gradients Q Learning
  Sarsa
基于概率和基于价值结合构成Actor-Critic, Actor基于概率做出动作,Critic给出做出动作的价值。加速了学习过程
回合更新(Monte-Carlo update) 单步更新(Temporal-difference update)
基础版Policy Gradient Q Learning
Monte-Carlo Learning Sarsa
  升级版 Policy Gradient
在线学习(on-policy) 离线学习(off-policy)
本人自己玩,自己学习 可以看着别人玩,自己学习
Sarsa Q learning
Sarsa($\lambda$) Deep Q Network

课程要求

  1. 学习资料
    • OpenAI gym 官网
    • Numpy, pandas,Matplotlib, Tkinter, Tensorflow, OpenAI gym.

Q learning

什么是Q learning

状态s1 :写作业

动作a1:看电视,a2: 写作业

Q-Learning-intro

Q-Learning 算法

Q-Learning-algo

其中

  • $\varepsilon$-greedy 是一种决策方式,有$\varepsilon$的概率选择最优Q值得动作,但也有$1-\varepsilon$的概率随机选择动作。目的是能够探索新的动作。
  • $Q(s,a)\leftarrow Q(s,a)+\alpha[r+\gamma\max_{a’}Q(s’,a’)-Q(s,a)]$是Q值得更新公式
    • $\alpha$是学习率,$ r$是状态$s$进行动作$a$变到状态$s‘$的奖励,$\gamma$是记忆系数.
    • $r+\gamma\max_{a’}Q(s’,a’)$是当前的奖励与未来的奖励的和,也就是$Q(s,a)$的现实值
      • 因为$r+\gamma\max_{a’}Q(s’,a’)=r+\gamma[r’+\gamma \max_{a’‘}Q(s’‘,a’’)]=r+\gamma r’+\gamma^2 r’’+\cdots$, 也就是未来所有奖励的和, $\gamma$就是未来的奖励所占的比重系数,若$\gamma=1$,未来的奖励也同样重要, 若$\gamma=0$,就只看当前奖励,忽略未来的所有奖励。
      • $Q(s,a)$是当前的估计值,用现实值-估计值,就是可以得到更新值$r+\gamma\max_{a’}Q(s’,a’)-Q(s,a)$
    • 学习率$0<\alpha\le1$则决定了更新多少更新值,可以把更新值全部用上($\alpha=1$),也可以只用一部分$\alpha<1$

实战示例1 一维的贪吃蛇

import numpy as np
import pandas as pd
import time

np.random.seed(2)

N_STATES=6               #游戏的总长度
ACTIONS=['left','right'] #两个动作
EPSILON=0.9              #决策概率
ALPHA=0.10               # 学习概率
GAMMA=0.9               # 记忆系数
MAX_EPISODES =13         #最大的训练次数
FRESH_TIME =0.3          #0.3秒走一步

def build_q_table(n_satates,actions):   #初始化Q值表
    table=pd.DataFrame(
        np.zeros((n_satates,len(actions))),
        columns=actions,
    )
    return table

def choose_action(state,q_table):       #在state状态下根据Q值表选择下一个action
    state_actions=q_table.iloc[state,:]
    if (np.random.uniform()>EPSILON) or (state_actions.all()==0): #有1-EPSILON的概率随机选择
        action_name=np.random.choice(ACTIONS)
    else:                                                         #EPSILON的概率选择最大的
        action_name=state_actions.idxmax()
    return action_name

def get_env_feedback(S,A): #根据当前状态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):  #更新在屏幕上的显示
    # 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)  #创建初始化Q表
    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)   #选择action
            S_, R = get_env_feedback(S, A)  # 获取下个状态和奖励
            q_predict = q_table.loc[S, A]  #Q的估计值
            if S_ != 'terminal':     #如果没有停止,就计算目标值(现实值)
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   
            else:   #如果停止了就只记忆当前的奖励吧
                q_target = R     # next state is terminal
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # 更新Q值表
            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)

实战示例2 走迷宫

架构与上面一样,只是状态和动作值更多了,复制粘贴上来也没意思了。源码在这里:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/2_Q_Learning_maze。还是很有意思的。

Sarsa

与Q Learning很相似,不同的地方在于更新方式。

Q Learning是选择下一步的最大Q值即可,下一步走哪是另一说了,说到不一定做到, Sarsa是说到做到,直接取下一步该走的Q值,所以是on-policy的

sarsa_intro

Sarsa($\lambda$)

上面的Sarsa可以称之为Sarsa(0),每走一步立即更新, 是单步更新。$\lambda$是脚步衰减值,$\lambda=1$是回合更新。

3-3-1

  • 其中最主要的部分是加上了对访问过的路径的记忆,$\lambda$就是对以前的路径的重要性进行了刻画。然后更新的时候也会更新以前路径的Q值

  • $E(s,a)\leftarrow E(s,a)+1$可能会导致$E(s,a)$的值非常大,可能会影响收敛,可以修改为

    \(E(s,a)=1,E(s,A/a)=0\), 其中$A/a$代表所有动作$A$去除了当前动作外的其他所有动作