【强化学习算法】Q-learning原理及实现

实现代码github仓库:RL-BaselineCode
代码库将持续更新,希望得到您的支持⭐,让我们一起进步!

文章目录

    • 1. 原理讲解
      • 1.1 Q值更新公式
      • 1.2 ε-greedy随机方法
    • 2. 算法实现
      • 2.1 算法简要流程
      • 2.2 游戏场景
      • 2.3 算法实现
    • 3. 参考文章

1. 原理讲解

Q-learning算法实际上相当简单,仅仅维护一个Q值表即可,表的维数为(所有状态S,所有动作A),表的内容称为Q值,体现该状态下采取当前动作的未来奖励期望。智能体每次选择动作时都会查询Q值表在当前状态下采取何种动作得到的未来奖励可能最多,当然也会添加一些随机性,使智能体可能选择别的可能当前认为未来奖励并不多的动作,以便跳出局部最优解,尽量得到全局最优解。

1.1 Q值更新公式

Q值更新公式为:

Q [ S , A ] = ( 1 − α ) × Q [ S , A ] + α × ( R + γ × m a x ( Q [ S n e x t , : ] ) ) Q[S,A]=(1-\alpha)\times Q[S,A]+\alpha\times (R+\gamma\times max(Q[S_{next}, :])) Q[S,A]=(1α)×Q[S,A]+α×(R+γ×max(Q[Snext,:]))

其中,α为学习速率(learning rate),γ为折扣因子(discount factor)。根据公式可以看出,学习速率α越大,保留之前训练的效果就越少。折扣因子γ越大, m a x ( Q [ S n e x t , : ] ) max(Q[S_{next}, :]) max(Q[Snext,:])所起到的作用就越大。

其中, m a x ( Q [ S n e x t , : ] ) max(Q[S_{next}, :]) max(Q[Snext,:])指以前学习到的新状态下可能得到的最大奖励期望,也就是**记忆中的利益。**如果智能体在过去的游戏中于位置 S n e x t S_{next} Snext的某个动作上吃过甜头(例如选择了某个动作之后获得了100的奖赏),这个公式就可以让它提早地得知这个消息,以便使下回再通过位置S时选择正确的动作继续进入这个吃甜头的位置 S n e x t S_{next} Snext

但如果下一步就是终点,那么Q值更新公式变为: Q [ S , A ] = ( 1 − α ) × Q [ S , A ] + α × R Q[S,A]=(1-\alpha)\times Q[S,A]+\alpha\times R Q[S,A]=(1α)×Q[S,A]+α×R

其中,减少了最后一项 γ × m a x ( Q [ S n e x t , : ] ) \gamma\times max(Q[S_{next}, :]) γ×max(Q[Snext,:]),这是因为当下一个状态就是最终目标时我们不需要知道下个状态在未来可能的收益,因为下个状态就可以得到游戏结束的即时收益。一般Q值更新公式之所以多了这一步也正是因为对于下一步不是终点的状态,这一步的奖励R一般来说是0或-1,拿不到即时奖励,但是又需要记录该节点的该操作在未来的可能贡献。

1.2 ε-greedy随机方法

前面提到我们为了跳出局部最优解,尽量得到全局最优解,我们采用的方法为ε-greedy方法:每个状态以ε(epsilon 探索速率)的概率进行探索(Exploration),此时将随机选取动作,而剩下的1-ε的概率则进行利用(Exploitation),即选取当前状态下效用值较大的动作。

在这里插入图片描述

2. 算法实现

2.1 算法简要流程

算法流程:

初始化 Q = {};
while Q 未收敛:
    初始化智能体的位置S,开始新一轮游戏
    while S != 终结状态:
        使用策略π,获得动作a=π(S) 
        使用动作a进行游戏,获得智能体的新位置S',与奖励R(S,a)
        Q[S,A] ← (1-α)*Q[S,A] + α*(R(S,a) + γ* max Q[S',a]) // 更新Q
        S ← S'

在这里插入图片描述

2.2 游戏场景

在这里插入图片描述

假设机器人必须越过迷宫并到达终点。有地雷,机器人一次只能移动一个地砖。如果机器人踏上矿井,机器人就死了。机器人必须在尽可能短的时间内到达终点。
得分/奖励系统如下:

  • 机器人在每一步都失去1点。这样做是为了使机器人采用最短路径并尽可能快地到达目标。

  • 如果机器人踩到地雷,则点损失为100并且游戏结束。

  • 如果机器人获得动力⚡️,它会获得1点。

  • 如果机器人达到最终目标,则机器人获得100分。
    现在,显而易见的问题是:我们如何训练机器人以最短的路径到达最终目标而不踩矿井?

2.3 算法实现

  1. 超参数设置
np.random.seed(2)  # 确保结果可复现
row = 5  # 游戏表格行数
col = 6  # 游戏表格列数
ACTIONS = ['up', 'right', 'down', 'left']  # 可采取的动作
EPSILON = 0.9  # ε-greedy随机方法中的ε
ALPHA = 0.1  # learning rate
GAMMA = 0.9  # discount factor
MAX_EPISODES = 5000  # 游戏共学多少轮
targetXY = [4, 4]  # 游戏的最终目标位置
env_list = ['--+---', '-*--*-', '--+--+', '*--*--', '-+--T-']  # 游戏地图
  1. 初始化Q值表
def build_q_table(row, col, actions):
  table = pd.DataFrame(
      np.zeros((row * col, len(actions))),  # q_table initial values
      columns=actions,  # actions' name
  )
  # print(table)    # show table
  return table
  1. 选择动作A
def choose_action(state, q_table):  # ε-greedy随机方法
  # This is how to choose an action
  state_actions = q_table.iloc[state[0] * col + state[1], :]
  if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  # act non-greedy or state-action have no value
      action_name = np.random.choice(ACTIONS)
  else:  # act greedy
      action_name = state_actions.idxmax()
      # replace argmax to idxmax as argmax means a different function in newer version of pandas
  return action_name
  1. 状态S下采取动作A到达新位置A’,并得到奖励/惩罚
def getR(S):
  str = env_list[S[0]][S[1]]
  if str == '-':
      return -1
  elif str == '*':
      return -100
  elif str == '+':
      return 1
  else:
      return 100
    
def get_env_feedback(S, A):
  # This is how agent will interact with the environment
  if A == 'up':  # move up
      if S[0] == targetXY[0]+1 and S[1] == targetXY[1]:  # 到达终点
          S_ = 'terminal'
          R = 100
      elif S[0] == 0:  # 向上碰壁
          S_ = S
          R = -1
      else:  # 正常移动
          S_ = [S[0] - 1, S[1]]
          R = getR(S_)
          if R == -100:  # 碰到炸弹直接结束
              S_ = 'terminal'
  elif A == 'right':  # move right
      if S[0] == targetXY[0] and S[1] == targetXY[1] - 1:  # 到达终点
          S_ = 'terminal'
          R = 100
      elif S[1] == col - 1:  # 向右碰壁
          S_ = S
          R = -1
      else:  # 正常移动
          S_ = [S[0], S[1] + 1]
          R = getR(S_)
          if R == -100:  # 碰到炸弹直接结束
              S_ = 'terminal'
  elif A == 'down':  # move down
      if S[0] == row - 1:  # 向下碰壁
          S_ = S
          R = -1
      elif S[0] == targetXY[0] - 1 and S[1] == targetXY[1]:  # 到达终点
          S_ = 'terminal'
          R = 100
      else:  # 正常移动
          S_ = [S[0] + 1, S[1]]
          R = getR(S_)
          if R == -100:  # 碰到炸弹直接结束
              S_ = 'terminal'
  else:  # move left
      if S[0] == targetXY[0] and S[1] == targetXY[1] + 1:  # 到达终点
          S_ = 'terminal'
          R = 100
      elif S[1] == 0:  # 向左碰壁
          S_ = S
          R = -1
      else:  # 正常移动
          S_ = [S[0], S[1] - 1]
          R = getR(S_)
          if R == -100:  # 碰到炸弹直接结束
              S_ = 'terminal'
  return S_, R
  1. 更新Q值表
q_predict = q_table.loc[S[0] * col + S[1], A]  # 当前位置的动作价值
if S_ != 'terminal':  # next state is not terminal
  q_target = R + GAMMA * q_table.iloc[S_[0] * col + S_[1], :].max()  
else:
  q_target = R  # next state is terminal
  is_terminated = True  # terminate this episode
# 当前位置的动作价值+新位置的状态价值
q_table.loc[S[0] * col + S[1], A] = (1 - ALPHA) * q_predict + ALPHA * q_target  
S = S_  # move to next state

3. 参考文章

  1. 强化学习入门:基本思想和经典算法

  2. Q-learning 的具体过程

  3. 【强化学习】Q-Learning算法详解以及Python实现【80行代码】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/214514.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据挖掘实战-基于word2vec的短文本情感分析

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

专业爬虫框架 -- scrapy初识及基本应用

scrapy基本介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。 但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域…

HCIP —— 双点重发布 + 路由策略 实验

目录 实验拓扑: 实验要求: 实验配置: 1.配置IP地址 2.配置动态路由协议 —— RIP 、 OSPF R1 RIP R4 OSPF R2 配置RIP、OSPF 双向重发布 R3配置RIP、OSPF 双向重发布 3.查询路由表学习情况 4.使用路由策略控制选路 R2 R3 5.检…

【Google2023】利用TiDE进行长期预测实战(时间序列密集编码器)

一、本文介绍 大家好,最近在搞论文所以在研究各种论文的思想,这篇文章给大家带来的是TiDE模型由Goggle在2023.8年发布,其主要的核心思想是:基于多层感知机(MLP)构建的编码器-解码器架构,核心创…

GEE:梯度卷积

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上,进行梯度卷积操作的代码框架、核心函数和多种卷积核,比如 Roberts、Prewitt、Sobel、各向同性算子、Compass算子、拉普拉斯算子、不同方向线性检测算子等。 结果如下图所示, 文章目录 一、常用的梯度…

实现一个简单的网络通信下(udp)

时间过去好久了,先回忆一下上一篇博客的代码!! 目前来看,我们客户端发一条消息,我服务器收到这一条消息之后呢,服务器也知道了是谁给我发来的消息,紧接这就把这条消息放进buffer当中&#xff0c…

POJ 3734 Blocks 动态规划(矩阵的幂)

一、题目大意 我们要给排成一行的区块涂颜色,可以选择红、绿、蓝、黄四种,要求红和绿的块都必须是偶数个,求出最终的涂色方式,对10007取余。 二、解题思路 我们设三个数列A,B和C: 1、A代表红色和绿色都…

百度收录批量查询工具,免费SEO优化排名工具

拥有一个在搜索引擎中得到良好收录的网站对于个人和企业都至关重要。而百度,作为中国最大的搜索引擎,其收录情况直接影响着网站的曝光度和流量。 百度搜索引擎是中文用户获取信息的重要途径之一。而在这个竞争激烈的网络环境中,了解自己网站…

QT 中 QTimer 类 备查

基础 // 指定了父对象, 创建的堆内存可以自动析构 QTimer::QTimer(QObject *parent nullptr);// 根据指定的时间间隔启动或者重启定时器, 需要调用 setInterval() 设置时间间隔 void QTimer::start();// 启动或重新启动定时器,超时间隔为msec毫秒。 void QTimer::…

游泳馆会员服务预约管理系统预约小程序效果如何

游泳馆在各地每天都有大量用户前往,夏季室外、冬季室内也是学习游泳技术和休闲娱乐的好地方,而消费者大多是年轻人和家长带的孩子,这部分群体更显年轻化,因此在如今互联网环境下,传统商家需要进一步赋能客户消费路径。…

共识问题:区块链如何确认记账权?

区块链可以说是最近几年最热的技术领域之一,区块链起源于中本聪的比特币,作为比特币的底层技术,本质上是一个去中心化的数据库,其特点是去中心化、公开透明,作为分布式账本技术,每个节点都可以参与数据库的…

力扣 --- 最长公共前缀

题目描述: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入:strs ["flower","flow","flight"] 输出:"fl"…

蓝桥杯物联网竞赛_STM32L071_8_ADC扩展模块

原理图: 扩展模块原理图: RP1和RP2分别对应着AIN1和AIN2,扭动它们,其对应滑动变阻器阻值也会变化 实验板接口原理图: 对应实验板接口PB1和PB0 即AN1对应PB1, AN2对应PB0 CubMx配置: ADC通道IN8和IN9才对…

Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(二)视图模板、静态资源访问

学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅 衔接上文Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(一) SpingMVC中…

智慧灯杆系统平台架构设计需要考虑的几个要点

智慧灯杆是一种集成了各种先进技术的道路照明设施。它不仅提供照明服务,还可以具有物联网技术、视频监控、环境监测、广播通讯、无线网络覆盖等多种功能。这些智能功能可以通过互联网进行控制和管理,从而实现智慧城市的建设。智慧灯杆能够提升城市的智能…

费解的开关

费解的开关 模拟一下开关的过程: 直接对第一行进行开关灯即可,那么第一行开关等的方案有多少个呢? 可以第一个想到的是5次,但实际上是25次,因为没有规定说只能开关一次吧。 那么如何获得这32种方案呢? 可…

【算法】前后缀分解题单⭐

文章目录 题单来源题目列表42. 接雨水238. 除自身以外数组的乘积2256. 最小平均差2483. 商店的最少代价代码1——前后缀数组代码2—— O ( 1 ) O(1) O(1)空间🐂 2420. 找到所有好下标2167. 移除所有载有违禁货物车厢所需的最少时间代码1——前后缀分解代码2——简洁…

【一个超简单的爬虫demo】探索新浪网:使用 Python 爬虫获取动态网页数据

探索新浪网:使用 Python 爬虫获取动态网页数据 引言准备工作选择目标新浪网的结构 编写爬虫代码爬取example.com爬取新浪首页部分内容解析代码注意: KeyError: href结果与展示 其他修改和适应注意事项 总结 引言 可以实战教爬虫吗,搭个环境尝…

利用STM32内置温度传感器实现温度监测系统

STM32微控制器是一款强大的嵌入式处理器,具有广泛的应用领域。其中,一些STM32微控制器内置了温度传感器,可以方便地实现温度监测功能。本文将详细介绍如何利用STM32内置温度传感器实现温度监测系统,并提供相应的示例代码。 一、硬…

python爬虫AES魔改案例:某音乐素材下载网

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly93d3cuYWlnZWkuY29tL3NvdW5kL2NsYXNzLw’) 拿到网址,F12打开调…