强化学习之Q-learning

强化学习中最不好理解的就是Q表值的更新。我总结的更新为以下步骤:

1、首先,我知道的参数只有目前的状态S(初始位置)和初始化的Q

2、根据Q表,在状态S下假如有2个动作A1A2,分别对应两个值Q(S,A1)Q(S,A2)。在90%的概率范围内(概率可调,叫做贪婪值greedy policy)选择Q值较大的动作,而10%或者当两个Q值相等时随机选择其中一个。假如我在这一步选择了A1。

3、有了此时的状态S和选出的动作A1,获得新的位置S_和奖励值R。(这里存在一个函数(与Q表无关),根据S和A1可以得到S_和R------------------S_, R = function(S, A))

4、根据新的位置S_和Q表,可以得到在S_状态下更大的Q值,即max(Q(S,A1), Q(S,A2))

5、更新Q表(学习过程)需要用到目标值(Q预测)和实际值(Q实际),计算方式为:

        Q预测 = Q(S,A1)

        Q实际=R + gm*max(Q(S_,A1), Q(S_,A2))    # 注意是下一个状态S_的最大Q值

        这里gm为折减概率,为小于1的数,一般取为0.9

6、有了Q预测和Q实际即可对Q表进行更新:

        Q(S,A1)=Q(S,A1)+lr*(Q实际-Q预测)

        这里lr为学习率,也为小于1的数,例如取0.01

伪代码如下:

从以上分析可关注以下几点:

1、更新的Q表只会更新选择的位置,没选择的没更新;

2、Q估计用到了贪婪值的策略,而Q现实直接取Q表最大值;

3、Q实现可以理解为在这一状态且选择这一步后,使得整个过程接近目标的可能性大小;因此需要靠下一步和奖励值进行计算。

4、只有最后一步有奖励值R,因此,假如初始Q表全为0的情况下,当第一轮成功到达最后一步去时只有倒数第二行的值被更新,其他的全为0;第二轮更新时倒数第三行选到倒数第二行不会0的值时也会发生数的变化(不再为0);依次类推,可见Q表的值是反向更新的过程,约接近目标的Q表值更新约明显,而远离的则更新的越慢。最后的结果就是约接近且成果让智能体接近目标的Q值越大,对应了注意点3。

以下是Q-leaning的简单实现代码,摘自"莫烦Python"莫烦Python的个人空间-莫烦Python个人主页-哔哩哔哩视频

"""
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 = 6   # 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 = 13   # maximum episodes
FRESH_TIME = 0.3    # fresh time for one move


def build_q_table(n_states, actions):  # 用Pandas创建Q表
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),     # q_table initial values
        columns=actions,    # actions's name
    )
    # print(table)    # show table
    return table


def choose_action(state, q_table):  # 传入状态和Q表,根据状态和Q表选择行为
    # This is how to choose an action
    state_actions = q_table.iloc[state, :]
    if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  # act non-greedy or state-action have no value
        action_name = np.random.choice(ACTIONS)
    # 注意,当Q表中一个状态对应的值相等时应当随机,尤其是开始的时候
    else:   # act greedy
        action_name = state_actions.idxmax()    # replace argmax to idxmax as argmax means a different function in newer version of pandas
    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)  # str.join用于连接
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)


def rl():
    # main part of RL loop
    q_table = build_q_table(N_STATES, ACTIONS)
    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和Q表选择动作
            S_, R = get_env_feedback(S, A)  # 根据选择的动作A和现在的状态S得到下一个状态S_和奖励A
            q_predict = q_table.loc[S, A]  # 根据S和Q表得到Q预测
            if S_ != 'terminal':
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   # 这里有没有R+没关系
            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
            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)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值