Q-Learning 简介:初学者教程(1)

一、说明

强化学习强调无模型学习算法,因此出现Q-Learning,Q-Learning算法酷似“有限状态自动机”模型,只是增加了奖励机制和Agent机制,而Agent与粒子群算法、蒙特卡洛算法是有关的。本文介绍这个算法框架。

二、QL框架

Q 学习标题

        强化学习 (RL) 是机器学习生态系统的一部分,其中代理通过与环境交互来学习,以获得实现目标的最佳策略。它与监督式机器学习算法完全不同,在监督式机器学习算法中,我们需要提取和处理这些数据。强化学习不需要数据。相反,它从环境和奖励系统中学习以做出更好的决策。

        例如,在马里奥视频游戏中,如果角色采取随机动作(例如向左移动),则根据该动作,它可能会获得奖励。采取行动后,代理(马里奥)处于新状态,该过程重复进行,直到游戏角色到达关卡终点或死亡。 

        此情节将重复多次,直到马里奥学会通过最大化奖励来驾驭环境。 

强化学习

        我们可以将强化学习分为五个简单的步骤:

  1. 代理在环境中处于状态零。
  2. 它将根据特定的策略采取行动。
  3. 它将根据该行动获得奖励或惩罚。
  4. 通过学习先前的动作并优化策略。 
  5. 该过程将重复,直到找到最佳策略。       

 

三、什么是 Q-Learning?

Q 学习是一种无模型、基于价值的离策略算法,它将根据代理的当前状态找到最佳的一系列操作。“Q”代表质量。质量表示该操作在最大化未来奖励方面有多大价值。  

基于模型的算法使用转换和奖励函数来估计最优策略并创建模型。相比之下,无模型算法则通过没有转换和奖励函数的经验来学习其行为的后果。 

基于价值的方法训练价值函数,以了解哪种状态更有价值并采取行动。另一方面,基于策略的方法直接训练策略,以了解在给定状态下应采取哪种行动。

离策略中,算法评估并更新与采取行动所用策略不同的策略。相反,在策略算法评估并改进采取行动所用相同策略。  

Q 学习中的关键术语

在我们了解 Q-learning 的工作原理之前,我们需要学习一些有用的术语来理解 Q-learning 的基础知识。 

  • 状态:代理在环境中的当前位置。 
  • 动作(a):代理在特定状态下采取的步骤。 
  • 奖励:对于每一个动作,代理都会得到奖励和惩罚。 
  • 情节:阶段的结束,此时代理无法采取新的行动。当代理已实现目标或失败时,就会发生这种情况。 
  • Q(S t+1 , a):在特定状态下执行操作的预期最佳 Q 值。 
  • Q(S t , A t ):是 Q(S t+1 , a) 的当前估计。
  • Q-Table:代理维护状态和动作集的 Q 表。
  • 时间差分(TD) :利用当前状态和动作以及之前的状态和动作 来估计Q(S t+1 , a)的预期值。

四、Q-Learning 如何工作?

        我们将以结冰的湖泊为例,详细了解 Q 学习的工作原理。在这个环境中,代理必须从起点穿过结冰的湖泊到达目标,而不能掉进洞里。最好的策略是走最短的路径到达目标。 

Q 学习可视化

4.1 Q-表

        代理将使用 Q 表根据环境中每个状态的预期奖励采取最佳行动。简而言之,Q 表是一组动作和状态的数据结构,我们使用 Q 学习算法来更新表中的值。 

4.2 Q 函数

        Q 函数使用贝尔曼方程,以状态(s)和动作(a)作为输入。该方程简化了状态值和状态动作值的计算。 

贝尔曼方程

五、Q 学习算法

Q 学习过程

5.1 初始化 Q 表

        我们首先初始化 Q 表。我们将根据动作数量构建列,根据状态数量构建行。

        在我们的示例中,角色可以上下左右移动。我们有四种可能的动作和四种状态(开始、空闲、错误路径和结束)。您还可以考虑掉入洞中的错误路径。我们将使用 0 值初始化 Q-Table。 

Q-表 1

5.2 选择一个动作

        第二步很简单。一开始,代理会选择采取随机动作(向下或向右),第二次运行时,它将使用更新的 Q 表来选择动作。 

5.3 执行操作

        选择一个动作并执行该动作将重复多次,直到训练循环停止。使用 Q 表选择第一个动作和状态。在我们的例子中,Q 表的所有值都是零。 

        然后,代理将向下移动并使用贝尔曼方程更新 Q 表。每次移动时,我们都会更新 Q 表中的值,并使用它来确定最佳行动方案。 

        最初,代理处于探索模式,并选择随机动作来探索环境。Epsilon 贪婪策略是一种平衡探索和利用的简单方法。epsilon 代表在探索机会较小的情况下选择探索和利用的概率。 

        开始时,epsilon 率较高,这意味着代理处于探索模式。在探索环境时,epsilon 会降低,代理会开始利用环境。在探索过程中,随着每次迭代,代理对估计 Q 值的信心会越来越强

Q 表 2

        在冰冻湖泊示例中,代理不知道环境,因此需要采取随机动作(向下移动)才能启动。如上图所示,Q 表使用贝尔曼方程进行更新。

5.4 衡量回报

        采取行动后,我们将衡量结果和回报。 

  • 达成目标的奖励为+1
  • 走错路(掉进洞里)的奖励是0
  • 在冰冻湖上空闲或移动的奖励也是 0。 

5.5 更新 Q 表

        我们将使用方程更新函数 Q(S t , A t )。它使用前一集的估计 Q 值、学习率和时间差异误差。时间差异误差是使用即时奖励、折扣后的最大预期未来奖励和前一个估计 Q 值计算的。 

该过程重复多次,直到 Q 表更新并且 Q 值函数最大化。 

Q 学习方程

        一开始,代理会探索环境以更新 Q 表。当 Q 表准备就绪时,代理将开始利用并开始做出更好的决策。 

        在湖面结冰的情况下,代理将学习采取最短路径到达目标并避免跳入洞中。

六、Q-Learning Python 教程 

        我们将使用 Gym 环境、Pygame 和 Numpy 从头开始​​构建 Q 学习模型。Python 教程是Thomas Simonini 的Notebook的修改版本。它包括初始化环境和 Q 表、定义贪婪策略、设置超参数、创建和运行训练循环和评估以及可视化结果。   

        如果您在创建和运行训练循环时遇到问题,您可以使用输出   检查代码源。

6.1 配置

设置虚拟显示

我们首先安装所有依赖项以生成回放视频(Gif)。我们需要一个虚拟屏幕(pyvirtualdisplay)来渲染环境并记录帧。 

注意:通过使用“%%capture”,我们抑制了 Jupyter 单元的输出。 

%%capture
!pip install pyglet==1.5.1
!apt install python-opengl
!apt install ffmpeg
!apt install xvfb
!pip3 install pyvirtualdisplay# Virtual display
from pyvirtualdisplay import Displayvirtual_display = Display(visible=0, size=(1400, 900))
virtual_display.start()
依赖项安装

我们现在将安装依赖项来帮助我们创建、运行和评估训练循环。 

  • gym:用于初始化FrozenLake-v1环境。
  • pygame:用于FrozenLake-v1 UI。
  • numPy:用于创建和处理 Q 表。
%%capture
!pip install gym==0.24
!pip install pygame
!pip install numpy!pip install imageio imageio_ffmpeg
导入包

我们现在将导入所需的库。 

  • Imageio 用于创建动画。 
  • tqdm 用于进度条。 
import numpy as np
import gym
import random
import imageio
from tqdm.notebook import trange
冰冻湖健身房环境 

我们将使用冰冻湖健身库创建一个防滑的 4x4 环境。 

  • 有两个网格版本:“4x4”和“8x8”。
  • 如果“is_slippery=True”,则由于冰冻湖的滑溜性质,代理可能不会朝预定的方向移动。 

初始化环境之后,我们来进行环境分析。 

env = gym.make("FrozenLake-v1",map_name="4x4",is_slippery=False)print("Observation Space", env.observation_space)
print("Sample observation", env.observation_space.sample()) # display a random observation
环境中有 16 个独特的空间,以随机位置显示。 
Observation Space Discrete(16)
Sample observation 15
让我们发现动作的数量并显示随机动作。 

行动空间

  • 0:向左移动
  • 1:向下移动
  • 2:向右移动
  • 3:向上移动

奖励函数

  • 达成目标:+1
  • 掉坑:0
  • 停留在冰冻湖面:0
print("Action Space Shape", env.action_space.n) 
print("Action Space Sample", env.action_space.sample())
Action Space Shape 4
Action Space Sample 1

6.2 创建并初始化Q表

Q 表的列表示动作,行表示状态。我们可以使用 OpenAI Gym 来查找动作空间和状态空间。然后我们将使用此信息来创建 Q 表。 

state_space = env.observation_space.n
print("There are ", state_space, " possible states")
action_space = env.action_space.n
print("There are ", action_space, " possible actions")
There are 16 possible states There are 4 possible actions

为了初始化 Q 表,我们将创建一个包含 state_space 和 action 空间的 Numpy 数组。我们将创建一个 16 X 4 数组。 

def initialize_q_table(state_space, action_space):Qtable = np.zeros((state_space, action_space))return Qtable 
Qtable_frozenlake = initialize_q_table(state_space, action_space)

6.3 贪婪策略

在上一节中,我们了解了处理探索和利用权衡的 epsilon 贪婪策略。以 1 - ε 的概率,我们进行利用;以 ε 的概率,我们进行探索。 

在 epsilon_greedy_policy 中我们将:

  1. 生成0到1之间的随机数。
  2. 如果随机数大于 epsilon,我们将进行利用。这意味着代理将在给定状态下采取具有最高值的操作。
  3. 否则,我们将进行探索(采取随机行动)。 
def epsilon_greedy_policy(Qtable, state, epsilon):random_int = random.uniform(0,1)if random_int > epsilon:action = np.argmax(Qtable[state])else:action = env.action_space.sample()return action
定义贪婪策略

我们现在知道 Q 学习是一种离策略算法,这意味着采取行动和更新函数的策略是不同的。 

在这个例子中,Epsilon Greedy 策略是代理策略,而 Greedy 策略是更新策略。 

贪婪策略也将是训练代理时的最终策略。它用于从 Q 表中选择最高的状态和动作值。

def greedy_policy(Qtable, state):action = np.argmax(Qtable[state])return action
模型超参数

这些超参数用于训练循环,对其进行微调将会给你带来更好的结果。 

代理需要探索足够的状态空间才能学习良好的值近似值;我们需要逐步衰减 epsilon。如果衰减率很高,代理可能会卡住,因为它没有探索足够的状态空间。

  • 共有 10,000 个训练片段和 100 个评估片段
  • 学习率为0.7。
  • 我们使用“FrozenLake-v1”作为环境,每集最多有 99 步
  • 伽马(折扣率)为 0.95。
  • eval_seed:环境的评估种子。
  • 开始时探索的epsilon 概率为 1.0,最小概率为 0.05。
  • 埃普西隆概率的指数衰减率为0.0005。
# Training parameters
n_training_episodes = 10000
learning_rate = 0.7        # Evaluation parameters
n_eval_episodes = 100      # Environment parameters
env_id = "FrozenLake-v1"   
max_steps = 99             
gamma = 0.95               
eval_seed = []             # Exploration parameters
max_epsilon = 1.0           
min_epsilon = 0.05           
decay_rate = 0.0005           

6.4 模型训练 

在训练循环中,我们将:

  1. 为训练片段创建一个循环。
  2. 我们首先要减少 epsilon。因为在每一集中,我们需要的探索越来越少,而利用越来越多。 
  3. 重置环境。
  4. 创建一个嵌套循环以获取最大步数。
  5. 使用 epsilon 贪婪策略选择动作。 
  6. 采取行动(A t)并观察预期奖励(R t+1)和状态(S t+1)。
  7. 采取行动(a)并观察结果状态(s')和奖励(r)。
  8. 使用公式更新 Q 函数。 
  9. 如果“done = True”,则完成情节并打破循环。
  10. 最后,将当前状态更改为新状态。 
  11. 完成所有训练阶段后,该函数将返回更新的 Q 表。 
def train(n_training_episodes, min_epsilon, max_epsilon, decay_rate, env, max_steps, Qtable):for episode in trange(n_training_episodes):epsilon = min_epsilon + (max_epsilon - min_epsilon)*np.exp(-decay_rate*episode)# Reset the environmentstate = env.reset()step = 0done = False# repeatfor step in range(max_steps):action = epsilon_greedy_policy(Qtable, state, epsilon)new_state, reward, done, info = env.step(action)Qtable[state][action] = Qtable[state][action] + learning_rate * (reward + gamma * np.max(Qtable[new_state]) - Qtable[state][action])# If done, finish the episodeif done:break# Our state is the new statestate = new_statereturn Qtable

我们花了3秒完成10,000次训练。 

Qtable_frozenlake = train(n_training_episodes, min_epsilon, max_epsilon, decay_rate, env, max_steps, Qtable_frozenlake)

训练结果

我们可以看到,训练过的 Q 表具有值,代理现在将使用这些值来导航环境并实现目标。  


Qtable_frozenlake
array([[0.73509189, 0.77378094, 0.77378094, 0.73509189],[0.73509189, 0.        , 0.81450625, 0.77378094],[0.77378094, 0.857375  , 0.77378094, 0.81450625],[0.81450625, 0.        , 0.77378094, 0.77378094],[0.77378094, 0.81450625, 0.        , 0.73509189],[0.        , 0.        , 0.        , 0.        ],[0.        , 0.9025    , 0.        , 0.81450625],[0.        , 0.        , 0.        , 0.        ],[0.81450625, 0.        , 0.857375  , 0.77378094],[0.81450625, 0.9025    , 0.9025    , 0.        ],[0.857375  , 0.95      , 0.        , 0.857375  ],[0.        , 0.        , 0.        , 0.        ],[0.        , 0.        , 0.        , 0.        ],[0.        , 0.9025    , 0.95      , 0.857375  ],[0.9025    , 0.95      , 1.        , 0.9025    ],[0.        , 0.        , 0.        , 0.        ]])
评估

Evaluation_agent 运行“n_eval_episodes”事件并返回奖励的平均值和标准差。 

  1. 在循环中,我们首先检查是否存在评估种子。如果没有,那么我们将重置没有种子的环境。 
  2. 嵌套循环将运行至max_steps。
  3. 代理将使用 Q-Table 采取在给定状态下具有最大预期未来奖励的行动。 
  4. 计算獎勵。
  5. 改变状态。
  6. 如果完成(代理掉入洞中或者目标已实现),则打破循环。
  7. 附加结果。
  8. 最后,我们将使用这些结果来计算平均值和标准差。 
def evaluate_agent(env, max_steps, n_eval_episodes, Q, seed):episode_rewards = []for episode in range(n_eval_episodes):if seed:state = env.reset(seed=seed[episode])else:state = env.reset()step = 0done = Falsetotal_rewards_ep = 0for step in range(max_steps):# Take the action (index) that have the maximum rewardaction = np.argmax(Q[state][:])new_state, reward, done, info = env.step(action)total_rewards_ep += rewardif done:breakstate = new_stateepisode_rewards.append(total_rewards_ep)mean_reward = np.mean(episode_rewards)std_reward = np.std(episode_rewards)return mean_reward, std_reward

如你所见,我们获得了满分,标准差为零。这意味着我们的代理在所有 100 集中都达到了目标。 

# Evaluate our Agent
mean_reward, std_reward = evaluate_agent(env, max_steps, n_eval_episodes, Qtable_frozenlake, eval_seed)
print(f"Mean_reward={mean_reward:.2f} +/- {std_reward:.2f}")
Mean_reward=1.00 +/- 0.00

6.5 可视化结果

到目前为止,我们一直在玩数字,为了进行演示,我们需要创建一个代理从一开始直到达到目标的动画 Gif。 

  1. 我们将首先通过使用 0-500 的随机整数重置环境来创建状态。 
  2. 使用 rdb_array 创建图像数组来渲染环境。 
  3. 然后将“img”附加到“images”数组。 
  4. 在循环中,我们将使用 Q-Table 采取步骤并为每个步骤渲染图像。 
  5. 最后,我们将使用这个数组和 imageio 来创建每秒一帧的 Gif。 
def record_video(env, Qtable, out_directory, fps=1):images = [] done = Falsestate = env.reset(seed=random.randint(0,500))img = env.render(mode='rgb_array')images.append(img)while not done:# Take the action (index) that have the maximum expected future reward given that stateaction = np.argmax(Qtable[state][:])state, reward, done, info = env.step(action) # We directly put next_state = state for recording logicimg = env.render(mode='rgb_array')images.append(img)imageio.mimsave(out_directory, [np.array(img) for i, img in enumerate(images)], fps=fps)
如果您在 Jupyter 笔记本中,则可以使用“IPython.display”图像函数显示 Gif。 
video_path="/content/replay.gif"
video_fps=1
record_video(env, Qtable_frozenlake, video_path, video_fps)from IPython.display import Image
Image('./replay.gif')
您现在可以与同事和同学分享这些结果或将其发布在社交媒体上。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言—深入理解指针(5)

1. sizeof 和 strlen 的对比 1.1 sizeof 在学习操作符的时候,我们学习了 sizeof,sizeof 是计算变量所占内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。 sizeof 只…

西瓜播放器xgplayer设置自动播放踩坑

上图是官网(西瓜视频播放器官方中文文档)的介绍,相信大家都是按照官网配置去做的,但是并没有什么用,插件很好用,但是属性不全,真的很悔恨,找遍 api 都没有找到自动播放的属性&#x…

MongoDB-4.2.1 之安装和使用

安装 下载安装包 我自己电脑是 Windows7 的老古董,所以就下载老版本的 MongoDB。 mongodb: https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2012plus-4.2.1.zip 解压安装包到指定路径 我解压到的 C 盘 C:\mongodb-4.2.1 添加环境变量 创建数据库和…

【免费Web系列】JavaWeb实战项目案例六

这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 员工信息-删除&修改 前面我们已经实现了员工信息的条件分页查询以及新增操作。 关于员工管理的功能,还有两个需要实现: 删除员工 修改员工 除了员工管理的功能之外&#x…

基于springboot+vue的家乡特色推荐系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

【Linux】Linux工具——gcc/g++

1.使用vim更改信用名单——sudo 我们这里来补充sudo的相关知识——添加信任白名单用户 使用sudo就必须将使用sudo的那个账号添加到信用名单里,而且啊,只有超级管理员才可以添加 信用名单在/etc/sudoers里 我们发现它的权限只是可读啊,所以…

分享:重庆耶非凡科技有限公司人力资源项目靠不靠谱?

在当今快速变化的商业环境中,人力资源项目作为企业发展的重要支撑,其专业性和可靠性成为企业选择合作伙伴时的重要考量因素。重庆耶非凡科技有限公司作为一家在行业内颇具影响力的科技企业,其人力资源项目——人力RPO(招聘流程外包)项目&…

dm8 什么时候视图中统计的内存会超过OS

v$bufferpool和v$mem_pool视图记录着DMSERVER各组件的内存占用量。理论上跟OS看到的保持一致。但实际大多数场景下,OS中看到的数据远大于视图中的统计。这里面可能有内存泄漏的原因。不过也有的时候视图中的统计数据超过OS。下面就是这种情况: 上图中红线…

Java_Mybatis

Mybatis是一款优秀的持久层框架,用户简化JDBC(使用Java语言操作关系型数据库的一套API)开发 使用Mybatis查询所有用户数据: 代码演示: UserMapper: Mapper //被调用时会通过动态代理自动创建实体类,并放入IOC容器中…

用cloudflared 把家里电脑网站可以让任何人试用

一针见血说技术,通俗易懂去实现自己的想法 一、背景 搭建一个网站,或者有个自己开发的算法,需要供应少量的人免费服务,也可以用于向合伙人演示。需要一个云服务,要么购买。还得啰嗦学习一些网站的开通知识&#xff0…

单号日入50+,全自动挂机赚钱

大家好!今天我为大家精心挑选了一个极具潜力的副业项目——“游戏工作室自由之刃2:单号日入50,全自动挂机赚钱”。 传奇游戏,无疑是许多人心中那段青春时光的珍贵回忆。 即便是其手游版本,也依旧保持着极高的热度和人…

【教程】20个高级 Python 函数,让你编程更高效

在Python的编程世界中,函数是我们编写代码的重要工具之一。除了常见的内置函数外,Python还提供了许多强大而有趣的高级函数,它们可以帮助我们简化代码、提升效率,甚至在某些情况下让编程变得更加有趣。让我们一起来探索这些高级函数的奇妙之处吧! 1.enumerate() – 枚举函…

Chrome DevTools

Console 面板 此章节请打开 justwe7.github.io/devtools/console/console.html 一起食用 一方面用来记录页面在执行过程中的信息(一般通过各种 console 语句来实现),另一方面用来当做 shell 窗口来执行脚本以及与页面文档、DevTools 等进行交…

【C++进阶】深入STL之string:模拟实现走进C++字符串的世界

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C “ 登神长阶 ” 🤡往期回顾🤡:C模板入门 🌹🌹期待您的关注 🌹🌹 ❀STL之string 📒1. string…

VRRP

文章目录 VRRP基本原理技术背景VRRP作用VRRP概述VRRP名词解释VRRP路由器VRRP组虚拟路由器虚拟IP地址、MAC地址Master、Backup路由器 VRRP状态机Master/ Backup 路由器Master路由器:Backup路由器: VRRP的工作过程 VRRP基础配置![image.png](https://img-blog.csdnimg.cn/img_con…

05C零碎语法

C零碎语法 目录 文章目录 C零碎语法1.函数指针2.回调函数3.数据拷贝3.1静态内存分配![请添加图片描述](https://img-blog.csdnimg.cn/direct/54d44e32bb7944f0866d4ca1e2667ce8.png)### 4.1动态内存分配 字符串6.sizeof()和strlen()的区别7.strcpy()/strncpy()函数7.1**strcp…

中继器、集线器、网桥、交换机、路由器和网关

目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.2 交换机 三、路由器、网关3.1 路由器3.2 网关 总结 前言 理解这些设备的关键是他们运行在不同的层次上。之所以存在不同层的问题,是因为不同的设备使用不同的信息来决定如何交换。在典…

【Hive SQL 每日一题】统计指定范围内的有效下单用户

文章目录 测试数据需求说明需求实现 前言:本题制作参考牛客网进阶题目 —— SQL128 未完成试卷数大于1的有效用户 测试数据 -- 创建用户表 DROP TABLE IF EXISTS users; CREATE TABLE users (user_id INT,name STRING,age INT,gender STRING,register_date STRING…

外卖点餐系统 springboot+vue+element-ui

免费获取方式↓↓↓ 项目介绍038: http://localhost:8080/ 账号:weiguanke 123 系统登陆后展示 用户可视界面 – 登录页面 – 首页: – 店铺查找页面: 店铺查找 – 店铺页面 店铺管理者可视页面 – 店铺页面 店铺管理员…

XCP协议系列介绍02-基于ASAP2 Tool-Set生成A2l介绍

本文框架 1. 前言2. ASAP2 Tool-Set系统介绍2.1 ASAP2 Creator介绍2.2 ASAP2 Updater介绍2.3 ASAP2 Merger介绍2.4 ASAP2 Comparer及Checker介绍2.5 ASAP2 Modifier介绍2.6 ASAP2 Studio介绍 3. 项目实操说明3.1 项目实操建议3.2 工具下载地址及使用 1. 前言 在XCP观测及标定整…