【机器学习】强化学习(八)-深度确定性策略梯度(DDPG)算法及LunarLanderContinuous-v2环境训练示例...

5e4fe522fcb5bd9891161bc96a41c458.gif

训练效果

DDPG算法是一种基于演员-评论家(Actor-Critic)框架的深度强化学习(Deep Reinforcement Learning)算法,它可以处理连续动作空间的问题。DDPG算法描述如下:

GPT-4 Turbo

d376491b0bbfa56a3350d257bb3191d4.png

Copilot GPT-4

3b503d311012a1fa1e6792270b0e80f2.png

20aea199a9da20db69c58ed0eda0c2b9.png

DDPG算法伪代码:

950f90d84d511146c2ad785671509af3.png

深度确定性策略梯度(DDPG)算法,用于训练一个智能体解决OpenAI Gym中的LunarLanderContinuous-v2环境示例代码

a3ff3c6a98a19117f4c0bad117210bc5.png

import argparse  # 用于解析命令行参数
from collections import deque  # 提供了一个双端队列
import itertools   # 用于对迭代对象执行多种操作
import random  # 提供随机数相关的函数
import time  # 提供时间相关的函数
import torch.optim as optim  # 提供了模型优化器
import gymnasium as gym  # 强化学习环境的库
import numpy as np  # 数学库,用于数组和矩阵等数学运算
import torch.nn.functional as F  # PyTorch的函数接口
import torch  # 神经网络库
import torch.nn as nn  # 用于构建神经网络
from torch.utils.tensorboard import SummaryWriter  # 用于可视化的工具




# 定义一个高斯噪声类,用于给动作添加一些随机性,增加探索性
class GaussianNoise:
    def __init__(self, dim, mu=None, std=None):
        # 初始化高斯噪声的均值和标准差,如果没有给定,就默认为零向量和0.1的常数向量
        self.mu = mu if mu else np.zeros(dim)
        self.std = std if std else np.ones(dim) * .1


    def sample(self):
        # 从高斯分布中采样一个噪声
        return np.random.normal(self.mu, self.std)




# 定义一个回放缓冲区类,用于存储和采样转移
class ReplayMemory:
    __slots__ = ['buffer']


    def __init__(self, capacity):
        # 初始化回放缓冲区的容量,使用一个双端队列来实现
        self.buffer = deque(maxlen=capacity)


    def __len__(self):
        # 返回回放缓冲区的长度
        return len(self.buffer)


    def append(self, *transition):
        # 将一个转移(状态,动作,奖励,下一个状态,是否结束)添加到回放缓冲区中
        # 使用tuple和map函数来将转移转换为元组的形式
        self.buffer.append(tuple(map(tuple, transition)))


    def sample(self, batch_size, device):
        '''sample a batch of transition tensors'''
        # 从回放缓冲区中随机采样一批转移,返回一个生成器,每个元素是一个张量
        # 使用random.sample函数来随机采样
        # 使用torch.tensor函数来将转移转换为张量,并指定数据类型为浮点数和设备为device
        # 使用zip和*操作符来将转移按照元素分组
        transitions = random.sample(self.buffer, batch_size)
        return (torch.tensor(x, dtype=torch.float, device=device)
                for x in zip(*transitions))




# 定义一个演员网络类,用于输出一个确定性的动作
# ActorNet动作空间是2的原因是因为它需要适应环境的动作空间。
# 在LunarLanderContinuous-v2环境中,智能体需要控制着陆器的两个引擎,
# 一个是主引擎,一个是方向引擎。主引擎的推力范围是0到1,方向引擎的
# 推力范围是-1到1。因此,智能体的动作空间是一个2维的向量,每个维度
# 的取值范围是-1到1。为了让ActorNet能够输出这样的动作,它的动作空间
# 也需要设置为2,即输出层的神经元个数为2,同时使用Tanh激活函数,
# 使得输出在-1到1之间。
class ActorNet(nn.Module):
    def __init__(self, state_dim=8, action_dim=2, hidden_dim=(400, 300)):
        # 调用父类的初始化方法
        super().__init__()
        # 解包隐藏层的维度
        h1, h2 = hidden_dim
        # 定义演员网络的头部,使用一个全连接层和一个ReLU激活函数
        self.actor_head = nn.Sequential(
            nn.Linear(state_dim, h1),
            nn.ReLU(),
        )
        # 定义演员网络的主体,使用一个全连接层和一个ReLU激活函数
        self.actor = nn.Sequential(
            nn.Linear(h1, h2),
            nn.ReLU(),
        )
        # 定义演员网络的输出,使用一个全连接层和一个Tanh激活函数,使得输出在-1到1之间
        self.actor_output = nn.Sequential(
            nn.Linear(h2, action_dim),
            nn.Tanh(),
        )


    def forward(self, x):
        # 定义演员网络的前向传播,输入一个状态,输出一个动作
        # 先通过演员网络的头部
        x = self.actor_head(x)
        # 再通过演员网络的主体
        x = self.actor(x)
        # 最后通过演员网络的输出
        x = self.actor_output(x)
        # 返回输出的动作
        return x




# 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值