强化学习(RL)中的Q-learning在拿奖杯游戏的表现

总的来说就是对问题进行建模,对policy,value,q值,environment进行不同程度上的构建,然后经过不同算法的训练更新比如(时序差分,蒙特卡洛),其核心思想是bellman方程,最后经过收敛判断得出结果。每次迭代中,我们都让代理人(agent)从state = 8出发,根据ε-greedy选择动作,再贪心地根据Q(S,A)
摘要由CSDN通过智能技术生成

RL中的Q-learning在拿奖杯游戏的表现

强化学习与Q-learning

随着知识的学习AI的面纱也被慢慢揭开,强化学习的详细解释其他blog上有详尽的入门解释。但是文章的主题是这方面,就说一说我的理解,下面的描述可能更针对对RL已经有一定了解的群体。总的来说就是对问题进行建模,对policy,value,q值,environment进行不同程度上的构建,然后经过不同算法的训练更新比如(时序差分,蒙特卡洛),其核心思想是bellman方程,最后经过收敛判断得出结果。当然对于大型的问题有更加复杂的解法,价值函数逼近,策略函数逼近等等。大一些的应用的问题代码量多,模型建立更加复杂(这里指数学模型,而不是RL里的model),但万变不离其中。当然后人是站在前面巨人的肩膀之上的,后面的创新肯定会搭高人类知识的阶梯。
下面再八股式地介绍一下Q-learning:
首先Q-learning可以被视为离轨策略的时序学习,下面解释一下什么是同轨学习和离轨学习
目标策略:用来学习并成为最优策略
行动策略:用来智能体的行动样本
同轨学习:目标策略和行动策略在同一个训练模型中产生
离轨学习:目标策略和行动策略不在同一个模型中产生,行动策略可能会单独产生
对于行动策略单独产生的迭代,由于与问题相关性更低,收敛的速度会更长,但效果在同等情况下会更好
下面是Q-learning算法

算法参数:步长α∈(0,1],取很小的ε>0
对所有的s∈S,a∈A(s),初始化Q(s,a),其中Q(终止状态) = 0
对每幕:
	初始化S
	对幕中的每一步循环:
		使用从Q得到的策略(ε-greedy),在S处选择A
		执行A,观察到R和S‘
		Q(S,A) <-- Q(S,A) + α[R+γmax{Q(S',A)} - Q(S,A)]
		S <-- S'
	直到S是终止状态

现在提出问题,为什么Q-learning是离轨策略?找了一些资料,网上貌似没有解答,个人认为是Q值的迭代中的max选择,这就是自己产生了行动策略,与模型无关。
直观来看,S,A,S’和A‘的动作关系如下图
在这里插入图片描述
在下面的奖杯游戏中马上就可以看到形象的例子:

拿奖杯游戏与建模

游戏和文章的灵感思路是从这里引出的,因为感觉这篇文章的博主讲的不是很清楚,关键部分跳过且感觉代码是copy的(没有冒犯的意思)。花了一些时间学习,看懂了模型和代码,想在此基础上再进一步,所以也吃水不忘挖井人。下面的一些图会引用原文章的示意图。
在这里插入图片描述
状态从上到下从左到右进行编号,我们的目标是从左下角(蓝色的点出发)花最小的代价走到终点,即红色的地方
黑色的state=5是障碍物,无法通过;绿色的state=7是骷髅,到达了会有负奖励。白色格子的路就是通道。
只有两个最终状态会有奖励reward,分别是+和-1.其他时候奖励都是0.
根据算法,我们要初始化状态矩阵s,q值矩阵qtable,还有一些参数
然后设定总的迭代次数,将上面的Q-learning伪代码实现。每次迭代中,我们都让代理人(agent)从state = 8出发,根据ε-greedy选择动作,再贪心地根据Q(S,A) <-- Q(S,A) + α[R+γmax{Q(S’,A)} - Q(S,A)]公式来更新当前的Q值,直到走到最终状态(最终状态包括3和7);依次重复以上动作,直至迭代完设定的次数。(当然我们可以根据q值变化大小的绝对上限来终止循环,为了简单还是设置了迭代次数)
下面是对代码的剖析:

代码分析

笔者在源码的基础上,加上了详细的注释,请食用
代码只要依次粘贴到python的一个文件中,运行即可,因为篇幅原因,笔者最后就不再重新整合到一起占用篇幅了
如果读者都嫌整合到一起复制粘贴麻烦,直接私聊我,我给你发源文件。

首先进行导包操作,设置好随机数以备后面的使用

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches    # 图形类
plt.xkcd()      # 设置画图风格(漫画)
np.random.seed(2022)    # 随机数种子

定义一个代理人agent类,由他在环境中不断从状态中采取动作再到下一个动作,一直学习下去循环往复,直到迭代结束得出最终结果。
首先定义全局变量,最终状态terminal state
初始化变量,定义选择动作函数,和对Q值进行更新的learn函数

class Agent:

    terminal_states = (3, 7)    # 终止状态
    # 3对应奖杯的位置,7对应骷髅的位置,从上往下,从左往右的顺序数,且从0开始

    def __init__(self, num_actions, num_states, exp_rate=0.2, lr=0.1, gamma=0.9):
        self.num_actions = num_actions
        self.num_states = num_states
        self.exp_rate = exp_rate
        self.lr = lr
        self.gamma = gamma

        self.q_table = np.zeros((self.num_states, self.num_actions))

    def choose_action(self, state):     # ε-greedy
        # choose action with most expected value

        if np.random.uniform(0, 1) <= self.exp_rate:    # 如果随机数小于exp_rate
            action = np.random.choice(self.num_actions)     # 在动作集中随机选择一个动作
        else:
            # greedy action, choose the agent with highest q
            # if there are multiple max, we randomly choose one
            qs = self.q_table[state, :]     # 取出动作状态值函数
            action = np.random.choice(np.where(qs == qs.max())[0])
        return action

    def learn(self, s, a, r, s_):
        # s状态,a动作,r即时奖励,s_演化的下一个动作
        q_old = self.q_table[s, a]
        if s_ not in self.terminal_states:
            q_new = r + self.gamma * self.q_table[s_, :].max()  # Q-learning取最大的动作状态值
        else:
            q_new = r

        # update
        self.q_table[s, a] += self.lr * (q_new - q_old)

然后定义环境(网格世界)
定义坐标和状态的互相转化函数
设置好rewards矩阵,qtabel矩阵
然后定义了状态转移的get_transition_model函数,之后的状态转移就根据这个transition model进行转移
reset函数用来重置每幕中的agent位

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原创小白变怪兽

帮助原创小白成为怪兽吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值