QLearning算法实现(python)

2023-05-16

文章目录

  • 环境要求
  • QLearning算法简介
  • 算法实现
    • 预设值
    • Q表
    • 定义行为
    • 环境反馈
    • 环境更新
    • Q学习主循环

环境要求

开发环境:python3

需要导入的包:

numpy
pandas
time

QLearning算法简介

Q学习算法会根据所经历的状态和所选择的行为建立一张Q表,如下表,表格中每个单元格的初值均为0

# q_table:
"""
     left  right
s0   0.0    0.0
s1   0.0    0.0
s2   0.0    0.0
s3   0.0    0.0
s4   0.0    0.0
s5   0.0    0.0
"""

Q学习算法会根据每一轮学习得到的奖励值更新Q表,简单地讲就是:在拿到最终奖励后,这一轮学习结束,会将得到的奖励值按比率传递给前一个状态时所选择的行为,这样Q表就记住了是什么状态下选择了什么行为才拿到最终奖励,Q表中该状态下行为的值可在下一轮学习中传递给上一个状态的行为,直至初始状态的行为值被更新。
经过一轮一轮的更新,Q表中从初始状态到最终状态每一步应该选择的行为都会有较高的分值,也就完成了训练。
Q学习算法的实现要比上述过程稍微复杂一点,因为算法中加入了贪婪度、学习率以及奖励衰减等参数,具体流程如下图:
在这里插入图片描述

如上图所示,Q表的更新是用下一个状态的所能拿到的最大奖励,作为当前状态行为的目标值,与Q表中记录的实际值做比较后,对当前值进行更新。用下个状态更新当前状态,也就形成了最终奖励的反向传递,形成一条由最终状态指向初始状态的通路。由于每次更新都由下一个状态的所能拿到的最大奖励作为目标值,这使得Q学习算法具有很强的贪婪性,可以很快完成训练。

算法实现

这一次我们会用 tabular Q-learning 的方法实现一个小例子, 例子的环境是一个一维世界, 在世界的右边有宝藏, 探索者只要得到宝藏尝到了甜头, 然后以后就记住了得到宝藏的方法, 这就是他用强化学习所学习到的行为.

-o---T
# T 就是宝藏的位置, o 是探索者的位置

预设值

这一次需要的模块和参数设置:

import numpy as np
import pandas as pd
import time

N_STATES = 6   # 1维世界的宽度
ACTIONS = ['left', 'right']     # 探索者的可用动作
EPSILON = 0.9   # 贪婪度 greedy
ALPHA = 0.1     # 学习率
GAMMA = 0.9    # 奖励递减值
MAX_EPISODES = 13   # 最大回合数
FRESH_TIME = 0.3    # 移动间隔时间

Q表

对于 tabular Q learning, 我们必须将所有的 Q values (行为值) 放在 q_table 中, 更新 q_table 也是在更新他的行为准则. q_table 的 index 是所有对应的 state (探索者位置), columns 是对应的 action (探索者行为).

def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),     # q_table 全 0 初始
        columns=actions,    # columns 对应的是行为名称
    )
    return table

# q_table:
"""
   left  right
0   0.0    0.0
1   0.0    0.0
2   0.0    0.0
3   0.0    0.0
4   0.0    0.0
5   0.0    0.0
"""

定义行为

接着定义探索者是如何挑选行为的. 这是我们引入 epsilon greedy 的概念. 因为在初始阶段, 随机的探索环境, 往往比固定的行为模式要好, 所以这也是累积经验的阶段, 我们希望探索者不会那么贪婪(greedy). 所以 EPSILON 就是用来控制贪婪程度的值. EPSILON 可以随着探索时间不断提升(越来越贪婪), 不过在这个例子中, 我们就固定成 EPSILON = 0.9, 90% 的时间是选择最优策略, 10% 的时间来探索.

# 在某个 state 地点, 选择行为
def choose_action(state, q_table):
    state_actions = q_table.iloc[state, :]  # 选出这个 state 的所有 action 值
    if (np.random.uniform() > EPSILON) or (state_actions.all() == 0):  # 非贪婪 or 或者这个 state 还没有探索过
        action_name = np.random.choice(ACTIONS)
    else:
        action_name = state_actions.argmax()    # 贪婪模式
    return action_name

环境反馈

做出行为后, 环境也要给我们的行为一个反馈, 反馈出下个 state (S_) 和 在上个 state (S) 做出 action (A) 所得到的 reward( R ) . 这里定义的规则就是, 只有当 o 移动到了 T, 探索者才会得到唯一的一个奖励, 奖励值 R=1, 其他情况都没有奖励.

def get_env_feedback(S, A):
    # This is how agent will interact with the environment
    if A == 'right':    # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1
        else:
            S_ = S + 1
            R = 0
    else:   # move left
        R = 0
        if S == 0:
            S_ = S  # reach the wall
        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' our environment
    if S == 'terminal':
        interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(2)
        print('\r                                ', end='')
    else:
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)

Q学习主循环

def rl():
    q_table = build_q_table(N_STATES, ACTIONS)  # 初始 q table
    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_predict = q_table.loc[S, A]    # 估算的(状态-行为)if S_ != 'terminal':
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   #  实际的(状态-行为)(回合没结束)
            else:
                q_target = R     #  实际的(状态-行为)(回合结束)
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  #  q_table 更新
            S = S_  # 探索者移动到下一个 state

            update_env(S, episode, step_counter+1)  # 环境更新

            step_counter += 1
    return q_table

具体代码如下:

import numpy as np
import pandas as pd
import time

np.random.seed(2)

N_STATES = 6  # 1维世界的宽度
ACTIONS = ['left', 'right']  # 探索者的可用动作
EPSILON = 0.9  # 贪婪度 greedy
ALPHA = 0.1  # 学习率
GAMMA = 0.9  # 奖励递减值
MAX_EPISODES = 13  # 最大回合数
FRESH_TIME = 0.3  # 移动间隔时间


def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),  # q_table 全 0 初始
        columns=actions,  # columns 对应的是行为名称
    )
    return table


# q_table:
"""
   left  right
0   0.0    0.0
1   0.0    0.0
2   0.0    0.0
3   0.0    0.0
4   0.0    0.0
5   0.0    0.0
"""


# 在某个 state 地点, 选择行为
def choose_action(state, q_table):
    state_actions = q_table.iloc[state, :]  # 选出这个 state 的所有 action 值
    if (np.random.uniform() > EPSILON) or (state_actions.any() == 0):  # 非贪婪 or 或者这个 state 还没有探索过
        action_name = np.random.choice(ACTIONS)
    else:
        action_name = state_actions.idxmax()  # 贪婪模式
    return action_name


def get_env_feedback(S, A):
    # This is how agent will interact with the environment
    if A == 'right':  # move right
        if S == N_STATES - 2:  # terminate
            S_ = 'terminal'
            R = 1
        else:
            S_ = S + 1
            R = 0
    else:  # move left
        R = 0
        if S == 0:
            S_ = S  # reach the wall
        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' our environment
    if S == 'terminal':
        interaction = 'Episode %s: total_steps = %s' % (episode + 1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(2)
        print('\r                                ', end='')
    else:
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)


def rl():
    q_table = build_q_table(N_STATES, ACTIONS)  # 初始 q table
    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_predict = q_table.loc[S, A]  # 估算的(状态-行为)if S_ != 'terminal':
                q_target = R + GAMMA * q_table.iloc[S_, :].max()  # 实际的(状态-行为)(回合没结束)
            else:
                q_target = R  # 实际的(状态-行为)(回合结束)
                is_terminated = True  # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # q_table 更新
            S = S_  # 探索者移动到下一个 state

            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)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QLearning算法实现(python) 的相关文章

  • T265学习之路(4)---realsense_ros安装及案例实现

    一 Realsense ros功能包的安装 1 1下载realsense ros源码 在Ros工作空间的src文件夹下输入命令 xff1a span class token function git span clone https git
  • 想进大厂必看的计算机类书单

    从大一开始 xff0c 我就很喜欢看各种各样的书 xff0c 不仅是技术的 xff0c 也有散文 越读感触越深 xff0c 发现书不在多 xff0c 而在于经典 xff0c 例如计算机传统黑皮书 xff0c CSAPP等等 你在不同时间读同
  • 数组

    数组 常用创建数组方式 xff1a span class token number 1 span 创建数组的同时 xff0c 制定数组中的内容 数据类型 span class token punctuation span span clas
  • Zookeeper的安装

    Zookeeper的安装 注意 xff1a 安装 zookeeper 前一定要先安装 jdk 在Linux上安装 装备一个本地虚拟机 xff0c 我使用的是 VMware Workstation 新建 CentOS7 的虚拟机 xff08
  • docker的安装

    安装docker 第 1 步 xff1a 将 yum 包更新到最新 xff0c 更新过程中出现输入的界面都输入 y 命令 xff1a yum update 出现 Complete span class token operator span
  • DOCKER 部署应用

    DOCKER 部署应用 DOCKER 部署应用 DOCKER 部署应用安装 Docker部署 MySQL部署 Tomcat部署 Redis 下面操作没有特别说明 xff0c 都是在虚拟机CentOS7上完成 安装 Docker 第 1 步
  • Docker部署ElasticSearch

    Docker部署ElasticSearch 默认docker已安装且启动 通过 dockerhup 官网查询docker内提供的 ElasticSearch 镜像 官网 xff1a https registry hub docker com
  • 酒旅项目总结

    项目里程碑 项目里程碑下图是项目原计划的时间线 项目技术架构 下面介绍各个技术 xff1a DNS xff08 Domain Name Server xff0c 域名服务器 xff09 是进行域名 domain name 和与之相对应的IP
  • MySQL环境搭建

    MySQL环境搭建 1 MySQL的下载 MySQL的4大版本 MySQL Community Server 社区版本 xff0c 开源免费 xff0c 自由下载 xff0c 但不提供官方技术支持 xff0c 适用于 大多数普通用户 MyS
  • 通过 SMOTE 及其变体过采样处理不平衡数据

    在这篇文章中 xff0c 我将解释使用 SMOTE SVM SMOTE BorderlineSMOTE K Means SMOTE 和 SMOTE NC 进行过采样 上采样 我将通过一个实际示例进行解释 xff0c 在该示例中我们应用这些方
  • SNMP错误记录:No more variables left in this MIB view (It is past the end of the MIB tree)

    MIB和OID对应关系查看命令 xff1a snmptranslate Tz m all SNMP测试 本地测试 xff1a snmpwalk v 2c c public 64 123 localhost 1 3 6 1 2 1 25 3
  • 一个Docker面试题目

    编写Dockerfile脚本编译镜像 xff0c 运行容器后实现对现有 mysql 数据库做备份 环境信息 xff1a mysql数据库地址192 168 0 10 端口 6600 用户 testuser 密码 123456 需要备份的数据
  • Windows程序设置自启动

    Windows程序设置自启动 在Windows系统中 有几种方法可以设置一个程序在系统启动时自动启动 将程序添加到开机启动文件夹 Win 43 R打开运行框 输入shell startup打开开机启动文件夹 然后将你想自动启动的程序快捷方式
  • Windows Server 程序设置自启动(用户不登录)

    Windows Server 程序设置自启动 xff08 用户不登录 xff09 在Windows Server中 想要在系统启动时自动启动一个程序 但不依赖用户登录 可以使用以下几种方法 将程序添加为服务 这是Windows Server
  • linux时间同步脚本

    linux时间同步脚本 span class token function bash span span class token comment bin bash span span class token comment 时间同步服务器
  • 华三网络设备查看命令

    华三网络设备查看命令 华三网络设备的配置和管理可以通过设备的管理地址进行 常用的页面有 状态监控 用于查看设备运行状态 CPU利用率 内存利用率 温度等信息接口配置 用于配置接口属性 如速率模式 DUPLEX模式 description等I
  • rsync 远程删除文件

    rsync 远程删除文件 rsync是一个强大的远程数据同步工具 它不仅可以实现远程文件复制 也可以实现远程文件删除 要使用rsync实现远程删除文件 可以使用如下命令 span class token function bash span
  • 华为openEuler 22.03 LTS系统的欢迎讯息

    华为欧拉系统的欢迎讯息 华为EulerOS系统中的欢迎讯息是通过 etc profile文件来定义和设置的 该文件会在用户登录后读取并执行 EulerOS的 etc profile文件中定义了prompt函数来设置PS1提示符 并通过PRO
  • bash的进程与欢迎讯息自定义

    在bash shell中 可以通过多种方式自定义欢迎讯息和提示符 主要有 修改 etc profile文件 该文件在用户登录后执行 定义了PROMPT COMMAND和PS1提示符 可以修改其内容实现自定义欢迎讯息和提示符 例如 修改为 s
  • 使用crontab命令同步时间

    crontab命令可以用于在Linux系统中定期同步时间 常用的时间同步方法有 1 使用ntpdate同步时间 可以添加如下crontab任务 5 usr sbin ntpdate time nist gov http xn 5time r

随机推荐

  • GitHub+ Docker Hub 拉取国外镜像

    一 背景 我们在拉取国外镜像 xff0c 例如在搭建 Kubernetes 的时候需要使用到来自于 Google xff1a gcr io google containers kube apiserver amd64 这样的镜像 xff0c
  • 如何熟悉weblogic

    要熟悉WebLogic 可以从以下几个方面入手 理解WebLogic的基本架构 WebLogic是Oracle的中间件产品 用于开发和部署企业级Java EE应用程序 它的基本架构由管理服务器 托管服务器和节点管理器组成 理解每个组件的作用
  • docker overlay2 是存放什么的?

    docker overlay2是Docker中的存储驱动之一 用于管理镜像和容器层的数据 它使用最小存储空间来存储像层这样的临时数据 overlay2本质上是多层存储驱动 它将镜像和容器层都视为独立的匿名临时文件系统 然后通过联合挂载将这些
  • Google浏览器下载地址

    官网下载 https www google cn chrome 旧版本下载地址 https www chromedownloads net chrome64win https www slimjet com chrome google ch
  • docker网卡的IP地址修改

    Docker容器启动后 默认会在主机上分配一个网卡 该网卡对应一个网络命名空间 并在这个网络命名空间下随机分配一个IP地址 如果想修改Docker容器的IP地址 有以下几种方法 修改Docker宿主机的Docker网络 可以在Docker主
  • SNMP连接失败

    SNMP连接失败常见的原因有以下几个 版本不匹配 SNMP有SNMPv1 SNMPv2c SNMPv3等版本 客户端和服务器版本必须匹配 否则会连接失败 需要确认客户端和服务器所支持的SNMP版本 选择一个双方都兼容的版本进行连接 社区名不
  • windows安装GO语言环境

    GO语言版本 Windows 平台和 Mac 平台推荐下载可执行文件版 xff0c Linux 平台下载压缩文件版 版本 xff1a 1 16 8 出现上面这个界面就说明已经安装好了 查看GO版本 可以打开终端窗口 xff0c 输入go v
  • 3par命令集

    3PAR是惠普公司的存储产品 它提供了基于CLI的管理终端来管理存储系统 主要的3PAR CLI命令有 show 显示系统信息 showsys 显示系统概况信息shownode 显示节点信息showport 显示端口信息showdisks
  • 华为欧拉系统RPM强制卸载libffi-devel

    查看欧拉系统有没有安装这个包 yum list span class token operator span span class token function grep span libffi devel 准备离线下载时 xff0c 发现
  • 最全Arrays.sort函数举例

    Arrays sort 的作用是对括号中的数组进行排序 xff0c 时间复杂度O xff08 n logn xff09 xff0c 方法返回值为void 是在原来数组的空间基础上进行升序排序 xff0c 因此不需要定义一个数组接收它 xff
  • 【无标题】驱动设计思想P9- linux驱动(韦东山)

    linux驱动 xff08 韦东山 xff09 驱动设计思想P9 linux 驱动 61 驱动框架 43 硬件操作 61 驱动框架 43 单片机 面向对象 字符设备驱动程序抽象出file operation结构体对硬件部分抽象为led op
  • Ubuntu16.04 安装ROS 过程中遇到的问题

    操作系统 xff1a Ubuntu16 04 ROS版本 xff1a Kinetic 纯入门 xff0c 安装过程错误百出 xff0c 几乎是一步一个报错 xff0c 每执行一个命令就要各种查找解决方法 xff0c 终于用一个下午加晚上的时
  • Github学习心得(3):项目的修改

    书接上回Github创建版本库 xff0c 我们已经成功地创建了一个版本库 xff0c 并且上传了readme txt文件 在实际项目中 xff0c 我们总是要对代码进行修改 xff0c 那么就需要及时地更新Github版本库中的文件 以本
  • 解决Keil全局搜索时无法跳转的问题

    检查一下自己的工程文件路径中是否有英文括号 xff0c 如果有则删掉
  • 阿木实验室的普罗米修斯仿真平台搭建的难点和坑点

    普罗米修斯仿真实验平台搭建的难点解决 0 我为什么要辛苦搭环境 xff1f 前一段时间阿木实验室提供了一个搭好环境的镜像 xff0c 凭阿木币购买 xff0c 是真的好用 xff0c 阿木币嘛 xff0c 签一签道就会有 关于这个镜像其实还
  • Visual Studio Code无法监视此大工作空间中的文件更改的解决办法

    Visual Studio Code无法监视此大工作空间中的文件更改 xff08 错误ENOSPC xff09 当您看到此通知时 xff0c 表明VS Code文件监视程序用尽了句柄 xff0c 因为工作空间很大并且包含许多文件 在调整平台
  • Ubuntu增加交换分区即swap方法

    用交换文件的方式添加交换分区 xff0c 如下 sudo su 进入管理员模式 xff0c 会提示输入密码 cd usr mkdir swap cd swap dd if 61 dev zero of 61 swapfile bs 61 1
  • 为什么px4源码里找不到main函数?——从hello sky理解px4的编程规范

    如果你刚自学了c 43 43 xff0c 准备开始看px4的源码 xff0c 但翻来覆去找了半天没有找到一个标准的main 究其原因 xff0c 在nuttx系统里 xff0c 程序入口不是main xff0c 所以找不到任何main 如果
  • matlab提取外接盒、围盒、凸包和骨架

    宁收宁马的费呢 xff01 老子自己做的 xff0c 免费提供该大家 xff0c 卖资料的垃圾 xff0c 能收几个钱 拍一幅含多个人体目标的图像 xff0c 利用外接盒 围盒和凸包对每个人体目标区域进行表达 xff0c 并提取其骨架 ma
  • QLearning算法实现(python)

    文章目录 环境要求QLearning算法简介算法实现预设值Q表定义行为环境反馈环境更新Q学习主循环 环境要求 开发环境 xff1a python3 需要导入的包 xff1a numpy pandas time QLearning算法简介 Q