首页 > 其他分享 >5. ε-greedy 探索

5. ε-greedy 探索

时间:2024-11-16 18:49:53浏览次数:3  
标签:探索 动作 decay epsilon random greedy

在 DDPG(Deep Deterministic Policy Gradient)中加入 ε-greedy 探索 也是一种增加智能体探索性的策略,尽管 ε-greedy 策略通常更适用于离散动作空间。然而,在 DDPG 的连续动作空间中,也可以通过 ε-greedy 策略实现探索。以下是如何将 ε-greedy 应用于 DDPG 的方法及其原因。

ε-greedy

1. 什么是 ε-greedy 探索策略?

ε − g r e e d y ε-greedy ε−greedy 策略是一种简单而有效的探索方法,定义如下:

  • 在每个时间步中,以 ε 的概率进行随机探索,即选择一个随机动作;
  • 以 (1 - ε) 的概率选择当前策略网络输出的最优动作,即 Actor 网络的确定性输出。

在离散动作空间中,ε-greedy 的随机探索通常是从离散动作集中随机选择一个动作。而在连续动作空间中,我们可以稍作修改,使 ε-greedy 策略与 DDPG 的确定性策略结合。

2. 在 DDPG 中实现 ε-greedy 探索

在 DDPG 中,可以通过以下方式引入 ε-greedy 策略:

1 ) 随机选择一个动作

  • 以 ε 的概率选择一个完全随机的动作,从动作空间中均匀采样。

2 ) 选择当前策略输出的最优动作

  • 以 (1 - ε) 的概率选择 Actor 网络输出的确定性动作(最优动作)。

在连续动作空间中,具体实现如下:

import numpy as np

def select_action(state, actor, action_dim, epsilon):
    # 以 epsilon 的概率进行随机探索
    if np.random.rand() < epsilon:
        # 随机生成一个动作
        action = np.random.uniform(low=-1.0, high=1.0, size=action_dim)
    else:
        # 否则选择当前策略的最优动作
        action = actor(state).detach().cpu().numpy()
    return action

3. ε 的值及其调整

  • 初始值设置:在训练开始时,可以将 ε 设置得较高(如 0.1 至 0.3),这样可以让智能体在初期进行更多的探索。
  • 逐步减少 ε:随着训练的进行,逐渐减小 ε 的值,使得智能体逐渐从探索过渡到利用。
    epsilon = max(epsilon_min, epsilon * decay_rate)
    

4. 为什么在 DDPG 中加入 ε-greedy 探索?

在 DDPG 中使用 ε-greedy 探索有以下几点优势:

1 ) 探索与利用平衡

  • 通过 ε-greedy 策略,智能体在训练初期能够进行更多随机探索,逐渐减少探索以便更专注于最优策略。
  • 这种机制有助于在确定性策略中增加随机性,以避免过度依赖当前策略网络输出。

2 ) 简单且有效

  • 相比于加入连续噪声(如高斯噪声或 Ornstein-Uhlenbeck 噪声),ε-greedy 策略的实现更加直接且便于调节。
  • 这种方法尤其适合对噪声分布不敏感的任务,能够以更简单的方式实现探索。

3 ) 适合在特定场景下使用

  • 对于需要更强的探索性或环境具有较多随机性时,ε-greedy 可以确保一定的随机探索,有助于跳出局部最优解。

5. ε-greedy 与噪声探索的对比

在 DDPG 中,加入 ε-greedy 探索和噪声探索各有优势,具体区别如下:

特性ε-greedy 探索噪声探索(如 Ornstein-Uhlenbeck 噪声)
适用性更适合需要随机选择动作的任务更适合需要连续平滑动作的任务
探索方式ε 概率选择随机动作,(1 - ε) 概率选择最优动作每个时间步中均在确定性动作上加入噪声
复杂性实现简单、调节直观实现稍复杂,可能需调整噪声参数
效果增强探索性,适合具有较多随机性环境的任务平滑且时间相关的探索,适合物理系统或需要平滑动作的任务

6.实践中的应用

在 DDPG 中,通常会优先使用噪声(如高斯噪声或 Ornstein-Uhlenbeck 噪声)进行探索。然而,在某些任务中,ε-greedy 探索也可以提供有效的探索方式,尤其是在探索多样性、随机性方面有较高要求的任务中。

    def allocate(self, prev_action, users, curren_episode, current_step):

        self.prev_qualities = prev_action
        self.users = users
        self.curren_episode = curren_episode
        self.curren_step = current_step
        # input state
        state_vector = self.get_state_vector(self.prev_qualities, self.users)

        # 增加noise探索
        epsilon = np.interp(x=self.curren_episode * self.num_step + self.curren_step,
                            xp=[0, self.epsilon_decay],
                            fp=[self.epsilon_start, self.epsilon_end])
        random_sample = random.random()
        if random_sample <= epsilon:
            # 探索:选择一个随机离散动作
            actions = np.random.choice(range(1, self.max_quality_level + 1), size=self.action_dim)
        else:
            # 利用:使用 Actor 网络选择动作
            actions = self.ddpg_agent.select_action(state_vector)

        return actions

这段代码实现了基于 ε-greedy 策略的探索与利用机制。它通过插值计算逐步减少的 ε 值来控制探索的概率,使得在训练早期更偏向探索,后期则逐渐更偏向利用 Actor 网络输出的最优动作。以下是每一行的解释:

6.1 代码详细解释

for step_i in range(NUM_STEP):
  • 这段代码运行一个循环 NUM_STEP 次(假设是一个训练过程中需要执行的步数),每次循环都代表一个时间步。
  • step_i 表示当前时间步的索引。
epsilon = np.interp(x=episode_i * NUM_STEP + step_i, xp=[0, epsilon_decay], fp=[epsilon_start, epsilon_end])
  • 这一行使用 np.interp 函数对 epsilon 进行线性插值,使 epsilonepsilon_start(初始探索概率)逐步减小到 epsilon_end(最终探索概率)。
  • np.interp 的参数含义:
    • x=episode_i * NUM_STEP + step_i:表示当前训练的步数。episode_i 是当前的回合数,乘以 NUM_STEP 后表示所有时间步的数量,再加上当前步 step_i
    • xp=[0, epsilon_decay]:定义了插值的两个参考点,即从步数 0epsilon_decay 之间,epsilon 会逐渐变化。
    • fp=[epsilon_start, epsilon_end]:指定插值的起始值和结束值,即 epsilonepsilon_start 逐渐减小到 epsilon_end
  • 这种插值方法让 epsilon 随着步数逐渐减小,初期探索概率较高,训练后期则逐渐减少探索概率。
random_sample = random.random()
  • 生成一个 0 到 1 之间的随机浮点数 random_sample,用于决定当前时间步是执行探索还是利用。
  • random.random() 返回一个均匀分布的随机数,介于 [0, 1) 之间。
if random_sample <= epsilon:
    # 探索:选择一个随机动作
    action = np.random.uniform(-2, 2, size=ACTION_DIM)
  • 如果 random_sample 小于等于当前的 epsilon 值,表示以 epsilon 概率进行探索,即选择一个随机动作。
  • np.random.uniform(-2, 2, size=ACTION_DIM):在动作空间中随机生成一个动作,范围为 [-2, 2],动作的维度是 ACTION_DIM
  • 这种探索方式允许智能体尝试不同的动作,从而在训练初期积累更多多样性的经验。
else:
    # 利用:使用 Actor 网络选择动作
    action = agent.select_action(state)
  • 如果 random_sample 大于 epsilon 值,表示以 1 − ϵ 1 - \epsilon 1−ϵ 的概率执行利用,即使用 Actor 网络来选择动作。
  • agent.select_action(state):调用 agentselect_action 方法,用 Actor 网络基于当前状态 state 输出确定性动作。

6.2 代码总结

  • 这段代码实现了 ε-greedy 探索策略,在每个时间步中以 ϵ \epsilon ϵ 的概率执行探索(选择随机动作),以 1 − ϵ 1 - \epsilon 1−ϵ 的概率执行利用(选择最优动作)。
  • epsilon 通过插值逐渐减小,使得智能体在训练早期更偏向探索,后期则逐渐更偏向利用 Actor 网络的输出,从而逐步收敛到更稳定的策略。

6.3 参数解释

参数 xp=[0, epsilon_decay] 是用来定义 epsilon 的衰减过程的步数范围。它指定了 epsilon 从初始值逐渐衰减到终止值的步数区间。

np.interp 函数中:

  • xp 表示插值过程的参考点的步数范围。在 [0, epsilon_decay] 之间,epsilon 从初始值 epsilon_start 逐渐减小到终值 epsilon_end
  • epsilon_decay 通常是一个整数,表示经过多少步后,epsilon 应该从 epsilon_start 减小到 epsilon_end

6.4 如何设定 epsilon_decay

1 ) 任务复杂度

  • 对于较复杂的任务,可能需要更长时间的探索。因此,epsilon_decay 可以设定得较大,让智能体更长时间保持较高的探索概率,从而积累足够的经验。
  • 对于简单的任务,epsilon_decay 可以设定得小一些,让智能体快速过渡到利用阶段。

2 ) 环境动态性

  • 如果环境较为动态,可能需要较长时间的探索。此时,可以增加 epsilon_decay 值。
  • 如果环境稳定,可以更快地衰减 epsilon,因此可以设置较小的 epsilon_decay 值。

3 ) 训练时长

  • 假设训练的总步数为 total_steps,可以设置 epsilon_decay 使探索持续到总步数的 10%-20%,即 epsilon_decay ≈ total_steps * 0.10.2
  • 例如,若总步数为 100000,可以将 epsilon_decay 设为 1000020000,这样前 10000-20000 步中 epsilon 会逐渐减小。

6.5 示例

假设我们有如下参数:

  • total_steps = 100000(总训练步数)
  • 希望在前 10% 的步数中衰减 epsilon,那么:
    epsilon_decay = int(total_steps * 0.1)  # 10% 的步数
    xp = [0, epsilon_decay]  # 衰减范围
    

这样,epsilon 会在前 10000 步内从 epsilon_start 逐渐衰减到 epsilon_end

标签:探索,动作,decay,epsilon,random,greedy
From: https://blog.csdn.net/u014217137/article/details/143793398

相关文章

  • Python基础:探索迭代器(Iterator)的奥秘
    引言在当今的科技时代,Python作为一种功能强大且广泛应用的编程语言,在数据处理、人工智能、网络爬虫等诸多领域发挥着不可替代的作用。迭代器作为Python中的一个重要概念,对于高效处理数据、优化算法等有着极大的意义。它能够以一种简洁而有效的方式遍历数据结构,无论是大型数......
  • 探索线性插值以外的插值方法
    引言        插值方法广泛应用于数据处理和科学计算中,不同插值方法适合不同的数据类型和应用场景。在上一篇博客中,我们讨论了线性插值,它通过在两个已知数据点之间绘制一条直线来估计中间值。然而,对于非线性数据或复杂的函数关系,线性插值的准确性可能不足。本篇博客将......
  • 探索大型语言模型(LLMs)能否在不泄露私人信息的情况下联合其他大型语言模型共同解决问题
    概述谷歌的GeminiUltra(2023年)和OpenAI的GPT-4(2023年)等大规模语言模型在许多任务中都表现出了令人印象深刻的性能。然而,这些模型不仅推理成本高昂,而且运行于数据中心,而数据中心并非本地环境,无法获得私人数据。另一方面,可以在私人环境中运行的模型,如GeminiNano,可以......
  • 探索 USB 上网模组,Air780ER 当仁不让
    今天探索的是USB上网模组,我推荐的是Air780ER模组,本文从用户实际使用的角度,解答大家对Air780ER最关心的一些问题,内容不深入探究技术细节,更多从选型、应用等非技术维度展开。一、Air780ER核心信息描述适用场景:Air780ER是推出的一款专门面向USB上网场景的4G-Cat.1模组,支持RNDIS/P......
  • 深入探索LangChain的高级功能
    在当今的AI开发领域,LangChain以其独特的模块化设计和强大的功能集,成为大语言模型开发者的重要工具。本文将深入探讨LangChain的高级功能,展示其在复杂应用场景中的应用潜力。###LangChain的架构优势LangChain的设计理念是通过模块化和可扩展性,简化大语言模型的集成与管理。其核......
  • 【Linux探索学习】第十三弹——进程状态:深入理解操作系统进程状态与Linux操作系统中的
    Linux笔记:https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482前言:在上篇我们已经讲解了进程的基本内容,也了解了进程在操作系统的重要作用,今天我们正式开始进程的另一个知识点的讲解:进程状态,即一个进程不可能一直处在运行或终止状态中,它......
  • 跨企业、跨区域的 FMEA 数据共享和协作模式的探索
    【大家好,我是唐Sun,唐Sun的唐,唐Sun的Sun。】在当今全球化和高度互联的商业环境中,跨企业、跨区域的FMEA(失效模式及后果分析)数据共享和协作模式具有重要意义。首先,建立统一的数据标准和格式是实现有效共享的基础。不同企业和区域可能采用各自独特的FMEA记录方式和术语,这会导......
  • 【C++】list 类深度解析:探索双向链表的奇妙世界
    ......
  • 深入探索 C++11 第一弹:现代 C++ 编程的基石与革新
    1、C++的发展历史C++11是C++的第⼆个主要版本,并且是从C++98起的最重要更新。C++11对C++语言的发展具有深远的影响,它使C++语言更加现代化、高效、灵活和易于使用,为开发者提供了更强大的工具和更好的编程体验,推动了C++在各个领域的广泛应用和持续发展。话不多说,下......
  • 探索线性插值:从原理到应用
    目录引言1.线性插值的基本概念2.线性插值的数学公式3.线性插值的示意图4.线性插值的应用场景  (1)图形处理  (2)数据填补  (3)动画制作5.使用Python实现线性插值  代码说明6.线性插值的优缺点7.线性插值的拓展方法8.总结引言  ......