Q-learning代码详解

最近,正好有空,就想着把莫烦讲解的强化学习再复习一遍,我就边看边在这做笔记。而且我发现虽然有很多人分析莫烦的代码,但不够详细,不能让入门选手开盖即食,所以我对代码的每一行进行了注释。还有特别对于刚学习python的同学,不了解python的函数的用法,就很烦,很耗费时间去查找,所以我在文章末尾也添加了各种函数的链接,方便学习。

Q-learning

import numpy as np
import pandas as pd
import time  # 用来控制探索者速度有多快

np.random.seed(2)  # 随机种子


N_STATES = 6   # 一维世界的宽度
ACTIONS = ['left', 'right']     # 探索者的可用动作,在一维世界只有左右
EPSILON = 0.9   # 贪婪度,即探索者有90%的情况会按照Q表的最优值选择行为,10%的时间会随机选择行为
ALPHA = 0.1     # 学习率,用来决定误差有多少需要被学习的,ALPHA是一个小于1的数
GAMMA = 0.9    # 奖励递减值,表示对未来reward的衰减值
MAX_EPISODES = 13   # 最大回合数
FRESH_TIME = 0.001    # 移动间隔时间

#DataFrame是Python中Pandas库中的一种数据结构,它类似excel,是一种二维表。
#建立q表
def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),     # q_table为一个6x2的表格,并初始化值都为0
        columns=actions,    # actions's name
    )
    # print(table)    # show 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
	'''
    return table


def choose_action(state, q_table):
    # 根据输入的状态及q表,输出动作
    state_actions = q_table.iloc[state, :]   # iloc函数提取行数据 
    if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  # 随机数大于0.9(即10%的时间会随机选择行为)或q表中某状态下左右两个动作的值都为0,此时随机选择动作
        action_name = np.random.choice(ACTIONS)
    else:    # 随机数小于等于0.9(即探索者有90%的情况会按照Q表的最优值选择行为)
        action_name = state_actions.idxmax()    # 在q表中取得该状态下值最大的动作的name
    return action_name


def get_env_feedback(S, A):
    # 探索者与环境互动,由当前的状态与动作获取奖励及探索者的下一状态
    if A == 'right':    # 探索者当前状态下向右移动
        if S == N_STATES - 2:   # 探索者当前状态如果是到达宝藏的前一步,则向右移动一步找到宝藏,获得奖励
            S_ = 'terminal'
            R = 1
        else:  # 探索者当前状态不是到达宝藏的前一步,则向右移动一步,奖励为0
            S_ = S + 1
            R = 0
    else:   # 探索者当前状态下向左移动
        R = 0  # 因为宝藏在最右边,探索者当前状态下向左移动,必定拿不到宝藏,所以奖励为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():
    # q-learning的主要部分
    q_table = build_q_table(N_STATES, ACTIONS)  # 建立一个q表,且初始值都为0
    for episode in range(MAX_EPISODES):  # 训练 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]   # 根据当前的状态及动作,取出当前q表中对应位置的值,即Q估计
            if S_ != 'terminal':  # next state is not terminal
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   # 计算下一状态不是 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)  # 对q表进行更新
            S = S_  # move to next state

            update_env(S, episode, step_counter+1)  # 环境的更新
            step_counter += 1  # 探索者移动的步数加1
    return q_table


if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-table:\n')
    print(q_table)  # 输出训练完成后的q表

代码中出现的函数:
loc和iloc函数的用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值