python实现Q-Learning算法

先贴源码:
莫烦python强化学习

此算法实现的背景是一个人找宝藏T,且只有向左和向右两种action。如下图:


image.png

用到的三个库:numpy、pandas、time。

import numpy as np
import pandas as pd
import time # 控制探索者移动速度

生成相同的随机序列(这句代码产生的效果还没弄明白):

np.random.seed(2) # 如果括号内的数字相同,则可以使numpy随机生成的序列相同

设置一些算法需要的常量:

N_STATES = 6   #共有6种状态,如图1所示,有6个格子
ACTIONS = ['left', 'right']    # 两种动作,向左向右
EPSILON = 0.9  # 90%选择最优的动作,10%选择随机的动作
ALPHA = 0.1    # 学习率
GAMMA = 0.9    # 衰减率
MAX_EPISODES = 13  # 最大回合数
FRESH_TIME = 0.3   # 每次移动间隔时间

本问题一共需要5个模块,举一反三,再复杂的问题也大致需要这5个模块。

  • 1.Q表的构建
  • 2.环境的构建和更新(更新主要用于展示探索的每一步效果可视化)
  • 3.奖励机制或者说与环境的交互
  • 4.动作的选择
  • 5.Q-Learning算法主体

Q表的构建

def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),   # Q表的行和列 也就是6行2列
        columns=actions,    # 列名字 也就是right left
    )
    # print(table)    # 显示表格
    return table

动作的选择

def choose_action(state, q_table):
    # This is how to choose an action
    state_actions = q_table.iloc[state, :] # 将此时状态的Q表 行值赋给state_actions
    if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  # 如果大于0.9这个概率或者全部Q值都为0的时候我们进行随机选择动作 
        action_name = np.random.choice(ACTIONS) #随机选择动作
    else:  #如果不是随机选择的话
        action_name = state_actions.idxmax()    # 就选Q值最大的那个动作
    return action_name

环境的交互

def get_env_feedback(S, A):
    # This is how agent will interact with the environment
    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' 
    if S == 'terminal':  #如果已经到达终点 取得宝藏 那么就输出当前第几次探索episode 和 一共走的步数steps
        interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(2) # 时间间隔2秒
        print('\r                                ', end='')
    else:
        env_list[S] = 'o' # 如果没有到终点 那么就把当前agent的位置由'-'改为'o',更好的可视化探索过程
        interaction = ''.join(env_list) #将序列连接成字符串 并且 输出到屏幕
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME) # 移动速度间隔为0.2秒

主函数体

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 #将到达终点设为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表的[S,A]的值
            if S_ != 'terminal': #如果下一步不是终点 
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   # 这是公式的一部分
            else:
                q_target = R     # 若下一步是终点 因为终点处的状态没有可选的动作 所以公式后半部分都为0
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # 更新Q[S,A]值
            S = S_  # 更新到下一个状态

            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)

你可能感兴趣的:(python实现Q-Learning算法)