强化学习库tianshou——DQN使用

本文介绍了清华大学学生开源的强化学习库tianshou,并分享了使用该库实现DQN强化学习的经验。作者对比了tianshou与其他库,强调了tianshou在文档和性能上的优势。在实践中,作者采用面向对象的方式组织代码,详细阐述了策略类(policy)和DQN策略的实现,特别提到了种子设置的重要性以确保复现性。虽然tianshou速度快,但功能不全,作者考虑转向支持多智能体的ray库。
摘要由CSDN通过智能技术生成

强化学习库tianshou——DQN使用

tianshou是清华大学学生开源编写的强化学习库。本人因为一些比赛的原因,有使用到强化学习,但是因为过于紧张与没有尝试快速复现强化学习的代码,并没有获得很好的成绩,故尝试用库进行快速复现。

之前也尝试了parl等库,感觉parl在文档等方面似乎并不如tianshou,性能上作为菜鸟不好评价。tianshou的官方文档也有很久没有更新了,上面有些代码不能运行,用了最新版tianshou的github上的代码案例进行学习,相关注释已经记录。

import os
import gym
import torch
import pickle
import pprint
import argparse
import numpy as np
from torch.utils.tensorboard import SummaryWriter

from tianshou.policy import DQNPolicy
from tianshou.env import DummyVectorEnv
from tianshou.utils.net.common import Net
from tianshou.trainer import offpolicy_trainer
from tianshou.data import Collector, ReplayBuffer, PrioritizedReplayBuffer


def get_args():
    '''
    max_epoch:最大允许的训练轮数,有可能没训练完这么多轮就会停止(因为满足了 stop_fn 的条件)

    step_per_epoch:每个epoch要更新多少次策略网络

    collect_per_step:每次更新前要收集多少帧与环境的交互数据。上面的代码参数意思是,每收集10帧进行一次网络更新

    episode_per_test:每次测试的时候花几个rollout进行测试

    batch_size:每次策略计算的时候批量处理多少数据

    train_fn:在每个epoch训练之前被调用的函数,输入的是当前第几轮epoch和当前用于训练的env一共step了多少次。上面的代码意味着,在每次训练前将epsilon设置成0.1

    test_fn:在每个epoch测试之前被调用的函数,输入的是当前第几轮epoch和当前用于训练的env一共step了多少次。上面的代码意味着,在每次测试前将epsilon设置成0.05

    stop_fn:停止条件,输入是当前平均总奖励回报(the average undiscounted returns),返回是否要停止训练

    writer:天授支持 TensorBoard,可以像下面这样初始化:

    :return:
    '''
    parser = argparse.ArgumentParser()
    parser.add_argument('--task', type=str, default='CartPole-v0')  # 环境名
    parser.add_argument('--seed', type=int, default=1626)  # 随机种子
    parser.add_argument('--eps-test', type=float, default=0.05)  # 贪婪策略的比例
    parser.add_argument('--eps-train', type=float, default=0.1)  # 贪婪策略的比例
    parser.add_argument('--buffer-size', type=int, default=20000)  # 回放池大小
    parser.add_argument('--lr', type=float, default=1e-3)  # 学习率
    parser.add_argument('--gamma', type=float, default=0.9)  # 衰减率
    parser.add_argument('--n-step', type=int, default=3)  # 要向前看的步数
    parser.add_argument('--target-update-freq', type=int, default=320)  # 目标网络的更新频率,每隔freq次更新一次,0为不使用目标网络
    parser.add_argument('--epoch', type=int, default=10)  # 世代
    parser.add_argument('--step-per-epoch', type=int, default=1000)  # 每个世代策略网络更新的次数
    parser.add_argument('--collect-per-step', type=int, default=10)  # 网络更新之前收集的帧数
    parser.add_argument('--batch-size', type=int, default=64)  # 神经网络批训练大小
    parser.add_argument('--hidden-sizes', type=int,
                        nargs='*', default=[128, 128, 128, 128])  # 隐藏层尺寸
    parser.add_argument('--training-num', type=int, default=8)  # 学习环境数量
    parser.add_argument('--test-num', type=int, default=100)  # 测试环境数量
    parser.add_argument('--logdir', type
  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您可以按照以下步骤使用tianshou进行SACPolicy的训练,并且输出训练模型pth,并利用writer.add_graph输出网络结构。 1. 安装tianshou 您可以使用以下命令安装最新版本的tianshou: ``` pip install tianshou ``` 2. 构建环境 您需要构建一个gym环境,然后将其传递给tianshou的环境包装器。以下是一个示例环境: ```python import gym import numpy as np class MyEnv(gym.Env): def __init__(self): self.action_space = gym.spaces.Box(low=-1, high=1, shape=(1,)) self.observation_space = gym.spaces.Box(low=-1, high=1, shape=(1,)) self.state = np.zeros((1,)) def reset(self): self.state = np.zeros((1,)) return self.state def step(self, action): action = np.clip(action, -1, 1) reward = -np.abs(action) self.state += action done = False return self.state, reward, done, {} ``` 在这个环境中,我们使用一个连续的动作空间和一个连续的观测空间,每个步骤的奖励为动作的绝对值的负数。 3. 定义模型 使用tianshou的智能体API,我们可以定义我们的SACPolicy模型: ```python import torch import torch.nn.functional as F from tianshou.policy import SACPolicy class MyModel(torch.nn.Module): def __init__(self, obs_shape, action_shape): super().__init__() self.obs_dim = obs_shape[0] self.act_dim = action_shape[0] self.fc1 = torch.nn.Linear(self.obs_dim, 64) self.fc2 = torch.nn.Linear(64, 64) self.mu_head = torch.nn.Linear(64, self.act_dim) self.sigma_head = torch.nn.Linear(64, self.act_dim) self.value_head = torch.nn.Linear(64, 1) def forward(self, obs, state=None, info={}): x = F.relu(self.fc1(obs)) x = F.relu(self.fc2(x)) mu = self.mu_head(x) sigma = F.softplus(self.sigma_head(x)) value = self.value_head(x) dist = torch.distributions.Normal(mu, sigma) return dist, value ``` 在这个模型中,我们使用两个完全连接的层来处理观察,并将输出分别传递到一个均值头和一个标准差头中。我们还添加了一个价值头来估计每个状态的价值。最后,我们将均值和标准差组合成一个正态分布,以便我们可以从中采样动作。 4. 训练模型 使用tianshou的训练API,我们可以定义我们的训练循环: ```python import torch.optim as optim from tianshou.trainer import offpolicy_trainer from tianshou.data import Collector, ReplayBuffer from torch.utils.tensorboard import SummaryWriter env = MyEnv() train_envs = gym.make('MyEnv-v0') test_envs = gym.make('MyEnv-v0') # 建立replay buffer buffer = ReplayBuffer(size=10000, buffer_num=1) # 建立collector train_collector = Collector(policy, train_envs, buffer) test_collector = Collector(policy, test_envs) # 建立optimizer optimizer = optim.Adam(policy.parameters(), lr=3e-4) # 定义训练循环 result = offpolicy_trainer( policy, train_collector, test_collector, optimizer, max_epoch=100, step_per_epoch=1000, collect_per_step=1, episode_per_test=10, batch_size=64, train_fn=None, test_fn=None, stop_fn=None, writer=writer, verbose=True) ``` 在这个循环中,我们首先创建一个回放缓冲区和一个collector,然后使用Adam优化器来优化我们的模型参数。我们使用offpolicy_trainer方法来训练我们的模型,其中我们设置了一些超参数,如最大epoch数、每个epoch的步数、每个步骤的收集数等。 5. 输出模型 训练完成后,我们可以将模型保存为一个.pth文件: ```python torch.save(policy.state_dict(), 'model.pth') ``` 6. 输出网络结构 最后,我们可以使用以下代码将网络结构写入TensorBoard: ```python writer.add_graph(policy, torch.zeros((1, 1))) ``` 在这个例子中,我们使用一个大小为1的观察空间,以便我们可以将模型传递给writer.add_graph方法。这将在TensorBoard中显示我们的网络结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值