Q-learning实例二维


在这里插入图片描述
探索者学会走迷宫. 黄色的是天堂 (reward 1),
黑色的地狱 (reward -1).

算法

在这里插入图片描述
整个算法就是一直不断更新 Q table 里的值, 然后再根据新的值来判断要在某个 state 采取怎样的 action.
Qlearning 是一个 off-policy 的算法, 因为里面的 max action 让 Q table 的更新可以不基于正在经历的经验(可以是现在学习着很久以前的经验,甚至是学习他人的经验).
不过这一次的例子, 我们没有运用到 off-policy, 而是把 Qlearning 用在了 on-policy 上, 也就是现学现卖, 将现在经历的直接当场学习并运用.

代码形式

在这里插入图片描述
三个py文件。 maze_env 环境模块(python 自带的简单 GUI 模块 tkinter 来编写虚拟环境.教程),RL_brain如何决策,run_this# 如何提升循环

Qlearning 迭代更新部分

# 如何提升循环
from maze_eny import Maze

from RL_brain import QLearningTable




def update():
    for episode in range(100):#100个回合
        observation = env.reset()#环境给出的观测值(红点坐标(1,1),(1,2)。。)
        while True:#,每个episode回合里
            env.render()#环境重新刷新(要跟环境互动就要进行刷新)
            action = RL.choose_action(str(observation))#基于观测值挑选动作   用str方式放在table中可以当做索引
            observation_, reward, done = env.step(action)#在env中施加动作返回下一个状态  done代表跳到黑的部分回
            # 合结束跳出while循环进入下个episode
            RL.learn(str(observation), action, reward, str(observation_))#从(第一个observation,第一个observation
            #施加的动作,施加动作得到的reward和跳到下一个状态)进行强化学习
            observation = observation_
            # break while loop when end of this episode
            if done:
                break
    # end of game

    print('game over')

    env.destroy()


if __name__ == "__main__":
    env = Maze()
    RL = QLearningTable(actions=list(range(env.n_actions)))

    env.after(100, update)
    env.mainloop()

思维决策

代码主结构

class QLearningTable:
    # 初始化
    def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):

    # 选行为
    def choose_action(self, observation):

    # 更新Q表值
    def learn(self, s, a, r, s_):

    # 检测 state 是否存在
    def check_state_exist(self, state):
# QLearning如何决策
import numpy as np
import pandas as pd


class QLearningTable:
    def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
        self.actions = actions  # a list
        self.lr = learning_rate
        self.gamma = reward_decay
        self.epsilon = e_greedy
        self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64)#纵轴是有多少个state横轴标签是可用action
        #初始化qtable是一个空的dataframe
    def choose_action(self, observation):
        self.check_state_exist(observation)#检验传入的observation中有没有在qtable中
        if np.random.uniform() < self.epsilon:
            # 根据最优选action
            state_action = self.q_table.loc[observation, :]
            action = np.random.choice(state_action[state_action == np.max(state_action)].index)#打乱action的位置
            #因为选最优相同时永远选第一个位置上的
        else:
            # 随机选择action
            action = np.random.choice(self.actions)

        return action

    def learn(self, s, a, r, s_):
        self.check_state_exist(s_)#多了s_检验是否在qtable当中
        q_predict = self.q_table.loc[s, a]
        if s_ != 'terminal':
            q_target = r + self.gamma * self.q_table.loc[s_, :].max()  # next state is not terminal
        else:
            q_target = r  # next state is terminal
        self.q_table.loc[s, a] += self.lr * (q_target - q_predict)  # 要修改的值

    def check_state_exist(self, state):#检验下一个经历的state是不是之前已经经过的或者是从没经历过的state
        #如果从来没有经历过state放到table中去
        if state not in self.q_table.index:
            # append new state to q table
            self.q_table = self.q_table.append(#若不存在加入
                pd.Series(
                    [0] * len(self.actions),#state在任何时候都是全0的
                    index=self.q_table.columns,
                    name=state,
                )
            )
发布了20 篇原创文章 · 获赞 16 · 访问量 1726

猜你喜欢

转载自blog.csdn.net/komorebi6/article/details/104710383