强化学习(探险者寻宝藏)

前言

  • 学习莫凡python强化学习中的第一个例子,探险者寻宝藏
  • 因为视频时间久远,视频中很多函数已经被弃用,导致代码报错
  • 这里将报错代码进行更正,并附上详细注释
  • 结合《强化学习》(第二版)分别使用 ϵ − \epsilon- ϵ贪心算法与UCB算法

ϵ − \epsilon- ϵ贪心算法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
import time

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

# 初始参数
# 探索者离宝藏距离
N_STATES = 6
# 探索者行为动作
ACTIONS = ["left", "right"]
# 有90%的概率选择最优价值
EPSILON = 0.9
# Q Learning的学习率
ALPHA = 0.1
# 奖励衰减度
LAMBDA = 0.9
# 迭代次数
MAX_EPISODES = 13
# 移动速度
FRESH_TIME = 0.2


# 建立Q表
def build_q_table(n_states, actions):
    table = pd.DataFrame(
        # 全0初始化Q表
        np.zeros((n_states,len(actions))),
        # 列名为动作
        columns=actions,
    )
    return table


# 选择动作
def choose_action(state, q_table):
    # 取对应状态价值列
    state_actions = q_table.iloc[state, :]
    # 如果随机概率大于0.9或对应行为价值均为0
    if (np.random.uniform() > EPSILON) or (state_actions.all() == 0):
        # 随机选择动作
        action_name = np.random.choice(ACTIONS)
    else:
        # 否则选择价值最大状态
        action_name = state_actions.idxmax()
    return action_name


# 对各行为的反应
def get_env_feedback(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):
    env_list = ['_']*(N_STATES-1) + ['T']
    if S == 'terminal':
        interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(1)
        print('\r                ', end='')
    else:
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)


# 创建训练过程
def rl():
    step = []
    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_, R = get_env_feedback(S, A)
            # Q表估计值
            q_predict = q_table.loc[S, A]
            # 如果没有结束
            if S_ != 'terminal':
                # Q表真实值
                q_target = R + LAMBDA * q_table.iloc[S_, :].max()
            else:
                q_target = R
                # 回合终止
                is_terminated = True
            q_table.loc[S, A] += ALPHA * (q_target - q_predict)
            S = S_
            # 环境更新
            update_env(S, episode, step_counter+1)
            step_counter += 1
        step.append(step_counter)
    plt.figure(dpi=600)
    plt.plot(np.arange(1, MAX_EPISODES+1, 1), step)
    plt.xlabel("训练次数")
    plt.ylabel("步数")
    plt.show()
    return q_table


if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-table:\n')
    print(q_table)
  • 训练次数以及到达宝藏步数如图所示:
    强化学习(探险者寻宝藏)_第1张图片

置信度上界(UCB)算法

  • 置信度算法动作选择依照以下公式:
    A t ≐ arg ⁡ min ⁡ a [ Q t ( a ) + c l n   t N t ( a ) ] A_t \doteq \mathop{\arg\min}\limits_{a}\left[Q_t(a) + c\sqrt{\frac{ln\ t}{N_t(a)}}\right] Ataargmin[Qt(a)+cNt(a)ln t ]
    其中 l n   t ln\ t ln t表示 t t t的自然对数, N t ( a ) N_t(a) Nt(a)表示在时刻 t t t之前动作 a a a被选择的次数。 c c c是一个大于0的数,它控制试探的程度。如果 N t ( a ) = 0 N_t(a) = 0 Nt(a)=0,则 a a a就被任务是满足最大化条件的动作。
  • 这种基于置信度上界的动作选择的思想是,平方根项是对 a a a动作值估计的不确定性方差的度量。
  • 代码中主要更改动作选择函数choose_action()

你可能感兴趣的:(python,人工智能,机器学习)