Python-DQN代码阅读-填充回放记忆(replay memory)

1.代码

python">def populate_replay_mem(sess, env, state_processor, replay_memory_init_size, policy, epsilon_start, epsilon_end, epsilon_decay_steps, VALID_ACTIONS, Transition):
    """
    填充回放记忆(replay memory)的函数

    参数:
        sess: TensorFlow 会话对象
        env: 环境对象
        state_processor: 状态处理器对象
        replay_memory_init_size: 回放记忆的初始大小
        policy: 策略函数,用于生成动作概率分布
        epsilon_start: 初始 epsilon 值
        epsilon_end: 最终 epsilon 值
        epsilon_decay_steps: epsilon 衰减的步数
        VALID_ACTIONS: 有效的动作列表
        Transition: 用于构建回放记忆的过渡对象类

    返回:
        replay_memory: 填充完毕的回放记忆列表
    """
    state = env.reset()  # 初始化环境状态
    state = state_processor.process(sess, state)  # 处理状态

    delta_epsilon = (epsilon_start - epsilon_end) / float(epsilon_decay_steps)  # 计算 epsilon 的衰减步长

    replay_memory = []  # 初始化回放记忆列表

    for i in range(replay_memory_init_size):
        epsilon = max(epsilon_start - float(i) * delta_epsilon, epsilon_end)  # 根据当前步数计算当前的 epsilon 值

        action_probs = policy(sess, state, epsilon)  # 生成动作概率分布
        action = np.random.choice(np.arange(len(action_probs)), p=action_probs)  # 根据动作概率分布选择动作

        env.render()  # 渲染环境

        next_state, reward, done, _ = env.step(VALID_ACTIONS[action])  # 执行选中的动作并观察下一个状态、奖励和终止状态

        next_state = state_processor.process(sess, next_state)  # 处理下一个状态
        next_state = np.append(state[:, :, 1:], np.expand_dims(next_state, 2), axis=2)  # 将下一个状态添加到当前状态中

        replay_memory.append(Transition(state, action, reward, next_state, done))  # 构建过渡对象并添加到回放记忆中

        if done:
            state = env.reset()  # 如果当前状态为终止状态,则重新初始化环境状态
            state = state_processor.process(sess, state)  # 处理状态
            state = np.stack([state] * 4, axis=2)  # 将状态复制四份并形成新的状态
        else:
            state = next_state  # 否则,更新当前状态为下一个状态

    return replay_memory  # 返回填充完毕的回放记忆列表

2.代码阅读

这段代码是用于填充回放记忆(replay memory)的函数,其中包含了以下步骤:

  1. 初始化环境状态:通过调用 env.reset() 方法来获取环境的初始状态,并通过 state_processor.process() 方法对状态进行处理。
  2. 初始化 epsilon:根据当前步数 i,使用线性插值的方式计算当前的 epsilon 值,以便在探索和利用之间进行平衡。
  3. 根据当前状态和 epsilon 值生成动作概率分布:通过调用输入的策略函数 policy,传入当前的会话对象 sess、当前状态 state 和 epsilon 值,获取动作概率分布 action_probs
  4. 根据动作概率分布选择动作:通过 np.random.choice() 方法从动作概率分布中选择一个动作,并记录选中的动作 action
  5. 执行选中的动作并观察下一个状态、奖励和终止状态:通过调用env.step() 方法执行选中的动作,并获取下一个状态 next_state、奖励 reward、终止状态 done
  6. 对下一个状态进行处理并添加到回放记忆中:通过调用 state_processor.process() 方法对下一个状态进行处理,将其添加到当前状态中并形成新的状态 next_state,然后将当前状态、动作、奖励、下一个状态和终止状态构成一个 Transition 对象,并添加到回放记忆 replay_memory 中。
  7. 更新当前状态:如果当前状态为终止状态,则通过调用 env.reset() 方法重新初始化环境状态;否则,将下一个状态赋值给当前状态 state
  8. 返回填充完毕的回放记忆:当回放记忆的大小达到预定的初始大小 replay_memory_init_size 时,函数将返回填充完毕的回放记忆 replay_memory

2.1 epsilon = max(epsilon_start - float(i) * delta_epsilon, epsilon_end)

python">epsilon = max(epsilon_start - float(i) * delta_epsilon, epsilon_end)

这行代码是用来计算当前步数下的 epsilon 值的。

epsilon 在强化学习中通常用于探索与利用之间的权衡,控制智能体在选择动作时的随机性程度。

具体解释如下:

  • epsilon_start:初始 epsilon 值,表示智能体在开始时对探索的偏好程度。
  • epsilon_end:最终 epsilon 值,表示智能体在训练过程中对探索的偏好程度。
  • delta_epsilon:epsilon 衰减步长,表示每一步 epsilon 需要减少的大小。
  • i:当前步数,表示当前训练的轮数。
  • float(i) * delta_epsilon:根据当前步数计算的 epsilon 的衰减值。
  • max(epsilon_start - float(i) * delta_epsilon, epsilon_end):取 epsilon_start 和 epsilon_end 中较大的值,确保 epsilon 的值不会小于 epsilon_end。随着训练步数的增加,epsilon 会逐渐减小,探索的随机性会逐渐降低。

这段代码的作用是根据训练步数 i 和设定的初始、最终 epsilon 值以及 epsilon 衰减步长,计算当前步数下的 epsilon 值,用于控制智能体在训练过程中的探索策略。随着训练的进行,epsilon 的值会逐渐减小,从而让智能体更加倾向于选择利用已有的经验来进行决策,而不是完全随机选择动作。

2.2 action_probs = policy(sess, state, epsilon)

python">action_probs = policy(sess, state, epsilon)

这行代码调用了 policy 函数,用于根据当前状态 state 和当前的 epsilon 值 epsilon 来计算动作的概率分布 action_probs

具体解释如下:

  • policy 函数是一个策略函数,接受当前状态 state 和当前的 epsilon 值 epsilon 作为输入,输出一个动作概率分布。
  • epsilon 值用于控制智能体在选择动作时的随机性程度,较大的 epsilon 值会导致较高的探索概率,而较小的 epsilon 值会导致较高的利用概率。
  • action_probs 是一个一维数组,表示每个可能动作的概率。数组的长度应与可选动作的数量相同。
  • action_probs 中的每个元素表示对应动作的选择概率,这些概率的和应为1。

这段代码的作用是根据当前状态 state 和当前的 epsilon 值,通过调用 policy 函数来计算动作的概率分布,从而用于后续的动作选择。具体的策略函数实现会根据具体的强化学习算法而定,例如 ε-greedy 策略、Softmax 策略等。

2.3 action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

python">action = np.random.choice(np.arange(len(action_probs)), p=action_probs)

这行代码使用 np.random.choice 函数根据动作概率分布 action_probs 来随机选择一个动作,并将选中的动作赋值给 action

具体解释如下:

  • np.random.choice 函数用于从给定的一维数组中进行随机采样,并返回一个随机选中的元素。
  • np.arange(len(action_probs)) 生成了一个从 0 到 len(action_probs)-1 的整数数组,用于作为随机采样的候选动作。
  • p=action_probs 参数指定了每个候选动作的选择概率,即动作概率分布。
  • action 是从候选动作中随机选中的动作,作为智能体当前时刻的动作选择。

这段代码的作用是根据动作概率分布 action_probs 来随机选择一个动作,并将选中的动作赋值给 action 变量,作为智能体在当前时刻的动作选择。选中的动作会用于后续的环境交互和经验存储。

2.4 env.render()

python">env.render()

这行代码调用了 env.render() 函数,用于在环境中渲染当前状态,以便可视化显示。

具体解释如下:

  • env.render() 是一个用于在环境中渲染当前状态的方法,它可以将环境状态以图像或其他形式展示出来,便于观察智能体在环境中的行为。
  • 渲染函数通常在调试、测试或演示时使用,可以帮助开发者和用户更直观地了解智能体的行为和环境的状态。
  • 注意,在实际训练过程中,由于渲染操作可能会消耗较多的计算资源,通常会在训练时禁用渲染以提高训练效率,仅在需要可视化时才会启用渲染。

2.5 next_state, reward, done, _ = env.step(VALID_ACTIONS[action])

python">next_state, reward, done, _ = env.step(VALID_ACTIONS[action])

这行代码调用了 env.step() 函数,用于执行智能体选择的动作并更新环境状态。

具体解释如下:

  • env.step(action) 是一个用于执行智能体选择的动作并更新环境状态的方法,它接受智能体选择的动作作为输入,并返回下一步的状态、奖励、是否完成、以及其他相关信息。
  • VALID_ACTIONS[action] 是从动作概率中选择的动作索引,它通过 np.random.choice() 函数生成。
  • next_state 是执行动作后的下一步状态,表示智能体在环境中执行了选择的动作后得到的新状态。
  • reward 是执行动作后获得的奖励,表示智能体在执行动作后根据环境的反馈获得的奖励值。
  • done 是一个布尔值,表示智能体是否在当前步骤完成了任务或者达到了终止条件。
  • _ 是一个占位符,通常用于存储其他不需要使用的信息,例如调试信息等。在这里,它表示返回的其他相关信息,但在后续的代码中并没有被使用。

VALID_ACTIONS[action] 是从预定义的动作空间 VALID_ACTIONS 中根据随机选择的动作索引 action 取得对应的具体动作

具体解释如下:

  • VALID_ACTIONS 是一个包含所有可用动作的列表或数组。每个动作在这个列表中都有一个对应的索引。
  • action 是一个整数,表示在动作空间中随机选择的动作的索引。
  • VALID_ACTIONS[action] 通过索引 action 取得在 VALID_ACTIONS 列表中对应的具体动作,用于传递给环境的 step() 函数执行。

2.6 next_state = state_processor.process(sess, next_state)

python">next_state = state_processor.process(sess, next_state)

这行代码调用了 state_processor.process() 方法,用于处理环境返回的下一步状态。

具体解释如下:

  • state_processor 是一个用于处理状态的对象,可能包含了对状态进行预处理或者特征提取的逻辑。
  • sess 是 TensorFlow 会话,用于执行 TensorFlow 计算图中的操作。
  • next_state 是从环境中获得的下一步状态,通过 env.step() 函数返回。
  • state_processor.process(sess, next_state) 是对下一步状态进行处理的方法,它接受 TensorFlow 会话和下一步状态作为输入,并返回处理后的状态。
  • 处理后的状态会被赋值给 next_state 变量,供后续使用。

2.7 next_state = np.append(state[:, :, 1:], np.expand_dims(next_state, 2), axis=2)

python">next_state = np.append(state[:, :, 1:], np.expand_dims(next_state, 2), axis=2)

这行代码通过 np.append() 函数将下一步状态 next_state 和当前状态 state 中的最近的 3 个状态(即 state[:,:,1:])在第三维度(axis=2)上进行拼接。

具体解释如下:

  • state 是当前状态,是一个形状为 (height, width, num_frames) 的三维数组,其中 heightwidth 是状态图像的高度和宽度,num_frames 是保存的连续帧数。
  • next_state 是下一步状态,与 state 的形状相同。
  • state[:,:,1:] 表示将 state 中的第一个维度和第二个维度保持不变,从第三个维度开始(即 state[:,:,1:]),取所有的值,这样就得到了 state 中的最近的 3 个状态,即除去最旧的状态。
  • np.expand_dims(next_state, 2) 表示将 next_state 在第三维度上扩展一个维度,从形状为 (height, width) 变为 (height, width, 1),这样就能与 state[:,:,1:] 在第三个维度上保持一致。
  • np.append(state[:,:,1:], np.expand_dims(next_state, 2), axis=2)state[:,:,1:]np.expand_dims(next_state, 2) 在第三维度上进行拼接,得到形状为 (height, width, num_frames) 的新状态 next_state
  • 最后,将拼接后的新状态赋值给 next_state 变量,供后续使用。

2.8 replay_memory.append(Transition(state, action, reward, next_state, done))

python">replay_memory.append(Transition(state, action, reward, next_state, done))

这行代码将当前状态 state、执行的动作 action、获得的奖励 reward、下一步状态 next_state、以及是否终止 done 作为一个 Transition 对象添加到回放记忆 replay_memory 列表中。

具体解释如下:

  • Transition 是一个自定义的类或命名元组,用于存储状态转移的信息。它可以包含当前状态、动作、奖励、下一步状态以及终止状态等信息。
  • Transition() 是一个用于创建经验回放缓冲区中的经验转换对象的构造函数。它通常在强化    学习中用于保存在环境中执行的经验。
  • Transition(state, action, reward, next_state, done) 创建一个 Transition 对象,使用当前状态 state、执行的动作 action、获得的奖励 reward、下一步状态 next_state,以及是否终止 done 作为参数进行初始化。
  • replay_memory.append(Transition(state, action, reward, next_state, done)) 将初始化后的 Transition 对象添加到回放记忆 replay_memory 列表中,用于后续的经验回放训练过程。


http://www.niftyadmin.cn/n/219925.html

相关文章

开发一个ChatGPT都需要什么?

开发像 ChatGPT 这样的聊天机器人一般需要以下组件:1. 大型语言模型:像 ChatGPT 这样的聊天机器人的骨干是一个大型语言模型,这个模型已经在大量文本数据上进行了训练。该模型应该能够生成类似人类真实语言的文本并根据上下文回答问题。语言模…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的拉普拉斯算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的拉普拉斯算法增强(C#)Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合OpenCV使用图像增强算法1.引用合适的类文件2.BGAPI SDK在图像回调…

自己动手写CPU——第二篇

1 ori指令说明 ori是进行逻辑 或 运算的指令,其指令格式如下所示 从以上的指令格式,我们可以直到,这是一个I类型指令,ori指令的指令码是 6‘b001101,所以当处理器发现正在处理的指令的高6bit 是 001101 的时候&#x…

结构体联合体sizeof内存求值 - 对齐数

讲解下struct和union的内存求值和对齐 以题目讲解 结构体联合体sizeof内存求值 - 对齐数不同位数下类型字节大小内存对齐规则struct 内存对齐求值嵌套struct内存对齐求值union的内存大小求值union大小计算准则struct嵌套union内存对齐求值不同位数下类型字节大小 一定要搞清楚…

精通线程池,看这一篇就够了

一:什么是线程池 当我们运用多线程技术处理任务时,需要不断通过new的方式创建线程,这样频繁创建和销毁线程,会造成cpu消耗过多。那么有没有什么办法避免频繁创建线程呢? 当然有,和我们以前学习过多连接池技术类似&…

java-ssh连接会报Algorithm negotiation fail 算法协商失败的解决方案

openssh8.1版本 or 7.4版本 jsch0.53or0.2.7版本 调用ssh连接是报Algorithm negotiation fail; 解决方案&#xff1a; maven中增加依赖&#xff0c;弥补算法缺失 <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</art…

06_GBDT+LR论文翻译

0.摘要 在线广告允许广告客户仅针对可衡量的用户响应进行出价和付费&#xff0c;例如广告点击。因此&#xff0c;点击预测系统是大多数在线广告系统的核心。伴随每日活跃用户超过7.5亿&#xff0c;活跃广告客户超过100万的情况&#xff0c;预测Facebook广告点击是一项具有挑战…

7.1 基本运放电路(1)

集成运放的应用首先表现在它能构成各种运算电路上&#xff0c;并因此而得名。在运算电路中&#xff0c;以输入电压作为自变量&#xff0c;以输出电压作为函数&#xff1b;当输入电压变化时&#xff0c;输出电压将按一定的数学规律变化&#xff0c;即输出电压反映输入电压某种运…