强化学习QLearning

强化学习QLearning

我是看 B站莫烦的是视频学习的.

主要公式

Q ( s , a ) ⇐ Q ( s , a ) + α [ r + γ max a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a) \Leftarrow Q(s,a) + \alpha \left[ r + \gamma \text{max}_{a'}Q(s',a') - Q(s,a) \right] Q(s,a)Q(s,a)+α[r+γmaxaQ(s,a)Q(s,a)]
根据我的理解,QLearning算法的主要工作都是围绕着这个公式展开的,算法学习的知识是存储在这个Q表中,表示在这个过程中知识的积累。

  • Q Q Q表如下所示:存储着每一个状态下,每个动作的预估收益
  • γ \gamma γ:表示当前奖励对后面时刻的影响衰减系数
  • α \alpha α:表示学习效率,就是梯度下降的学习步长
  • Q ( s ′ , a ′ ) Q(s',a') Q(s,a):表示下一步的状态的动作的预估奖励。
  • r r r:表示当前动作的奖励,这是真实的收益
    这里Q表的更新策略,就是用当前的真实收益 + 下一步动作的预估下一步动作预估收益 x 衰减系数 - 下一步动作的预估收益 。
    说明白一点的道理,就是用后一时刻的预估状态去更新当前的状态,从后向前对Q表的数据进行学习。其实,这个思想是和我上面一篇博客的动态规划思想很相似的,用最后的状态去寻找初试状态,只是动态规划使用了穷举,这里是随机运行的。而且动态规划在这里不太灵活,运行步长是不定的,不容易实现。

Q表的内容示例

Q ( s , a ) Q(s,a) Q(s,a)表示在某一时刻的s状态下,采取动作a能够获得的期望收益。

QTableLeftRight
Step1 q ( s 1 , a 1 ) q(s_1,a_1) q(s1,a1) q ( s 1 , a 2 ) q(s_1,a_2) q(s1,a2)
Step2 q ( s 2 , a 1 ) q(s_2,a_1) q(s2,a1) q ( s 2 , a 2 ) q(s_2,a_2) q(s2,a2)
Step3 q ( s 3 , a 1 ) q(s_3,a_1) q(s3,a1) q ( s 3 , a 2 ) q(s_3,a_2) q(s3,a2)
Step4 q ( s 4 , a 1 ) q(s_4,a_1) q(s4,a1) q ( s 4 , a 2 ) q(s_4,a_2) q(s4,a2)
Step5 q ( s 5 , a 1 ) q(s_5,a_1) q(s5,a1) q ( s 5 , a 2 ) q(s_5,a_2) q(s5,a2)

程序

代码也是莫烦的小程序,我对参数进行了更改

"""
A simple example for Reinforcement Learning using table lookup Q-learning method.
An agent "o" is on the left of a 1 dimensional world, the treasure is on the rightmost location.
Run this program and to see how the agent will improve its strategy of finding the treasure.
View more on my tutorial page: https://morvanzhou.github.io/tutorials/
"""

import numpy as np
import pandas as pd
import time

np.random.seed(2)  # reproducible  设置随机数种子,种下一颗种子,只在下一次有效,相同的种子,得到的随机数是一样的


N_STATES = 10   # the length of the 1 dimensional world
ACTIONS = ['left', 'right']     # available actions
EPSILON = 0.9   # greedy police
ALPHA = 0.5     # learning rate
GAMMA = 1    # discount factor
MAX_EPISODES = 20   # maximum episodes
FRESH_TIME = 0.2    # fresh time for one move

## 初试化Q表,每一行表示一步,列表示每一步中的选择权重,这里n_states步,每一步有两种选择,向左走还是向右走
def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),     # 初始化Q表为0,这时表示知识为零
        columns = actions,    # actions's name
    )
    return table

## 这里是选择下一步动作的策略,EPSILON是一个阈值,当随机数大于这个数时就随机走一步,小于就按Q表中较大权重的走,也就是90%按表走,10%随机走
def choose_action(state, q_table):
    state_actions = q_table.iloc[state, :]
    if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):   #  当Q表全为零时也会随机选择
        action_name = np.random.choice(ACTIONS)
    else:   # act greedy
        action_name = state_actions.idxmax()    # 获取权值较大的动作
    return action_name

# 这是智能体在环境中的规则,当走到N_STATES-2时,就到达终点,并且奖励为1,走到0时,再向左走就原地踏步
def get_env_feedback(S, A):
    if A == 'right':    # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1     #奖励为R
        else:
            S_ = S + 1
          	R = 0
    else:   # move left
        R = 0     #没有遇到终点奖励为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(0.5)
        print('\r                                ', end='')
    else:   #出书当前的状态显示
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)

# QLearning算法的执行
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)   # 选择动作
            S_, R = get_env_feedback(S, A)  # take action & get next state and reward 获取下一步动作和当前的奖励
            q_predict = q_table.loc[S, A]   #获取下一步动作的奖励
            #################################Q表更新#####################################################
            if S_ != 'terminal':
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   # next state is not terminal  当前的奖励 + 下一步的奖励(下一步默认按Q表) = 当前奖励
            else:
                q_target = R     # next state is terminal
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # update 用(预测两步的奖励 - 预测一步的奖励)作为更新Q表的误差 ,乘以学习效率,对Q表进行更新
            ##################################上面这些动作时,还没有更新状态########################################################
            S = S_  # move to next state                         #更新到下一步

            update_env(S, episode, step_counter+1)     #更新环境的变化
            step_counter += 1
        print(q_table)
    return q_table
if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-table:\n')
    print(q_table)

实验

通过对莫烦程序的理解,就这个案例可以进行一些小小的参数改进,加深对Qlearning的理解。

N_STATES = 10   # the length of the 1 dimensional world  环境长度设置为10
ACTIONS = ['left', 'right']     # available actions
EPSILON = 0.9   # greedy police  #90%概率随机选
ALPHA = 0.1     # learning rate  #学习效率0.1
GAMMA = 0.9    # discount factor  #衰减0.9
MAX_EPISODES = 50  # maximum episodes          循环长度为50
FRESH_TIME = 0    # fresh time for one move

这个参数,将程序运行,并打印每个周期的step_counter
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

把程序刚开始种的随机种子去掉,可以让程序每次都随机。这里刚开始用的次数较多是因为,Q表的值都为0,智能体是以随机运行的方法找到终点的,我们可以计算一下找到终点的期望次数,不过这里种下了一颗随机种子,因此每次运行得到的结果不会因为随机性变化,可以将程序第一行注释掉,就会有随机性。
程序基本上到达10次之后就会到达稳定,但是还是会有小的起伏,这是因为有10%随机选择的概率,现在把随机选择的概率设置为0,再次实验。
在这里插入图片描述
此时符合我们的预期,当稳定之后,就不会有起伏可了。
其实这里还是有问题的,刚开始我们是完全随机的去寻找终点,10的距离都需要上百次,如果是100的距离可能就要尝试很多次了,所以需要改进刚开始知识为零的寻找方法。
这里可以改进奖励值的方法,上面程序中,智能体没有找到终点是没有任何奖励,也没有任何惩罚的,我们可以给智能体一个惩罚,当智能体没有走到终点,那就惩罚。

def get_env_feedback(S, A):
    if A == 'right':    # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1     #奖励为R
        else:
            S_ = S + 1
          	R = -0.1  #惩罚
    else:   # move left
        R = -0.1     #没有遇到终点奖励为-0.1
        if S == 0:
        	R = -0.1     #没有遇到终点奖励为-0.1
            S_ = S  # reach the wall
        else:
            S_ = S - 1
    return S_, R

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时,可以看到第一次找到终点的次数明显降低,但是有造成了一个缺点,就是智能体的进化速度变慢了,此时可以尝试增加学习效率解决。
ALPHA = 0.5 # learning rate #学习效率0.5在这里插入图片描述
此时,进化速度可以看出就可以了。

随机期望的计算

这里的随机期望次数我还是不太会算,希望有大佬解答:
当 N_STATES = 2 时,情况是下面这样

起点终点

期望的计算方法为: ∑ n = 1 ∞ 1 2 n ⋅ n = 2 \sum\limits_{n=1}^\infty {{\frac{1}{2}}^n \cdot n}=2 n=121nn=2
当 N_STATES = 3 时,情况是下面这样

起点1终点

期望的计算方法为: ∑ n = 1 ∞ n 2 2 n + 1 = 2.75 \sum\limits_{n=1}^\infty {{\frac{n^2}{2^{n+1}}}}=2.75 n=12n+1n2=2.75
当 N_STATES = 4 时,情况是下面这样

起点12终点

期望的计算方法为: ∑ n = 1 ∞ n 2 2 n + 1 = 3 \sum\limits_{n=1}^\infty {{\frac{n^2}{2^{n+1}}}}=3 n=12n+1n2=3
** 这是错的**

Saras

主要公式

Q ( s , a ) ⇐ Q ( s , a ) + α [ r + γ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a) \Leftarrow Q(s,a) + \alpha \left[ r + \gamma Q(s',a') - Q(s,a) \right] Q(s,a)Q(s,a)+α[r+γQ(s,a)Q(s,a)]

  • Q Q Q表如下所示:存储着每一个状态下,每个动作的预估收益
  • γ \gamma γ:表示当前奖励对后面时刻的影响衰减系数
  • α \alpha α:表示学习效率,就是梯度下降的学习步长
  • Q ( s ′ , a ′ ) Q(s',a') Q(s,a):表示下一步的状态的动作的预估奖励。
  • r r r:表示当前动作的奖励,这是真实的收益
    这里Sarsa和Qlearning唯一的区别就是 Q ( s ′ , a ′ ) Q(s',a') Q(s,a),Sarsa用的是预估动作收益,这个动作是一定在下一次会执行的,而Qlearning这里使用了最大预估,但是下一步的动作不一定执行这个最大的预估值,因为他还有10%的可能选择,随机选择。
    这里就可以推测Sarsa和Qlearning在结果上的区别,由于Sarsa选择执行的全部是预估奖励最大的动作,因此在这应该会有更快的收敛速度,同时当存在负面惩罚时,Sarsa也能很好的去避免惩罚,这里也就是莫烦说的胆小的原因,但是这样也应该会有一个缺点,就是容易陷入局部最优。
    Qlearning,离线学习,预估一步的奖励但是智能体并不一定执行,因此也可以叫做看别人做着学习。
    Sarsa,在线学习,预估一步的奖励并且智能体一定执行,因此智能体是说到做到的学习。

程序

程序只需要改一点点就好了

def rl_Sara():
    # main part of RL loop
    q_table = build_q_table(N_STATES, ACTIONS)  # 初始化空的Q表,表示此时没有知识
    print(q_table)
    for episode in range(MAX_EPISODES):           #循环
        step_counter = 0
        S = 0
        is_terminated = False
        update_env(S, episode, step_counter)
        A = choose_action(S, q_table)                  # 选择动作
        while not is_terminated:   #当到达终点结束一次

            S_, R = get_env_feedback(S, A)  # take action & get next state and reward 获取下一步状态和当前的奖励

            q_predict = q_table.loc[S, A]   # 获取当前动作的奖励
            #################################Q表更新#####################################################
            if S_ != 'terminal':
                A_ = choose_action(S_, q_table)  # 获取下一步状态下,做的动作
                q_target = R + GAMMA * q_table.loc[S_, A_]   # next state is not terminal  当前的奖励 + 下一步的奖励(下一步默认按Q表) = 当前奖励
            else:
                q_target = R     # next state is terminal
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # update 用(预测两步的奖励 - 预测一步的奖励)作为更新Q表的误差 ,乘以学习效率,对Q表进行更新
            ##################################上面这些动作时,还没有更新状态########################################################
            S = S_  # move to next state                         #更新到下一步
            A = A_

            update_env(S, episode, step_counter+1)     #更新环境的变化
            step_counter += 1

        step_counter_table[episode] = step_counter
        #print(step_counter)
       # print(q_table)
    return q_table

实验

可以来验证一下,是否收敛速度加快了,这里需要将状态设置多一点容易看出区别,因此参数如下:

N_STATES = 30   # the length of the 1 dimensional world
ACTIONS = ['left', 'right']     # available actions
EPSILON = 0.9   # greedy police
ALPHA = 0.1     # learning rate
GAMMA = 0.9    # discount factor
MAX_EPISODES = 50  # maximum episodes
FRESH_TIME = 0    # fresh time for one move

Sarsa请添加图片描述arsa请添加图片描述请添加图片描述

Qlearning

请添加图片描述请添加图片描述请添加图片描述
从上面的图大致可以看出Sarsa次数是相对平稳的,而Qlearning波动比较大,但是收敛速度区别还是不大,不过还是初步验证我上面的推测。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
强化学习中的Q-Learning是一种记录行为值的方法,用于解决智能体在与环境交互过程中通过学习策略以达成回报最大化的问题。Q-Learning基于马尔可夫决策过程的假设,通过记录智能体在不同状态下采取不同动作所获得的收益的期望值,即Q值。算法的目标是寻找一个策略,使得智能体能够最大化未来获得的回报。Q-Learning的算法流程主要是通过构建一个Q-table来存储Q值,并根据Q值选择能够获得最大收益的动作。\[2\] 强化学习是一种通过与环境交互获得奖赏指导行为的学习方法。与监督学习不同,强化学习中的强化信号是环境提供的对动作好坏的评价,而不是告诉系统如何产生正确的动作。强化学习的目标是使智能体获得最大的奖赏。由于外部环境提供的信息有限,强化学习系统必须通过自身的经验进行学习。通过不断试错的方式,强化学习系统在行动-评价的环境中逐渐获得知识,并改进行动方案以适应环境。\[3\] 总结来说,强化学习是一种通过与环境交互获得奖赏指导行为的学习方法,而Q-Learning强化学习中的一种主要算法,用于记录行为值并寻找最优策略。 #### 引用[.reference_title] - *1* *3* [强化学习--QLearning](https://blog.csdn.net/wangaolong0427/article/details/124241284)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【强化学习】 Q-Learning](https://blog.csdn.net/haha0332/article/details/112967024)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值