使用paddle2的DQN跑Mountain

2023-10-30 00:20
文章标签 使用 dqn mountain paddle2

本文主要是介绍使用paddle2的DQN跑Mountain,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.Agent

Agent就是一个接口,sample就是实现了一个随机探索,本质还是用的self.alg.predict()函数
然后Agent.learn(self, obs, act, reward, next_obs, terminal)就是将从环境拿到的obs, act, reward, next_obs, terminal转化为tensor形式,然后送给算法中的learn,即self.alg.learn(obs, act, reward, next_obs, terminal)

import parl
import paddle
import numpy as npclass Agent(parl.Agent):def __init__(self, algorithm, act_dim, e_greed=0.1, e_greed_decrement=0):super(Agent, self).__init__(algorithm)assert isinstance(act_dim, int)self.act_dim = act_dimself.global_step = 0self.update_target_steps = 200self.e_greed = e_greedself.e_greed_decrement = e_greed_decrementdef sample(self, obs):"""Sample an action `for exploration` when given an observationArgs:obs(np.float32): shape of (obs_dim,)Returns:act(int): action"""sample = np.random.random()if sample < self.e_greed:act = np.random.randint(self.act_dim)else:if np.random.random() < 0.01:act = np.random.randint(self.act_dim)else:act = self.predict(obs)self.e_greed = max(0.01, self.e_greed - self.e_greed_decrement)return act  ##返回动作def predict(self, obs):"""Predict an action when given an observationArgs:obs(np.float32): shape of (obs_dim,)Returns:act(int): action"""obs = paddle.to_tensor(obs, dtype='float32')	##将环境obs转换为tensor形式pred_q = self.alg.predict(obs)     ##调用了算法中的predict函数act = pred_q.argmax().numpy()[0]	##找最大值,返回第一个数据即actreturn actdef learn(self, obs, act, reward, next_obs, terminal):"""Update model with an episode dataArgs:obs(np.float32): shape of (batch_size, obs_dim)act(np.int32): shape of (batch_size)reward(np.float32): shape of (batch_size)next_obs(np.float32): shape of (batch_size, obs_dim)terminal(np.float32): shape of (batch_size)Returns:loss(float)"""if self.global_step % self.update_target_steps == 0:self.alg.sync_target()self.global_step += 1##扩展维度1变为【1】act = np.expand_dims(act, axis=-1)reward = np.expand_dims(reward, axis=-1)terminal = np.expand_dims(terminal, axis=-1)##将arrary转换为tensor形式obs = paddle.to_tensor(obs, dtype='float32')act = paddle.to_tensor(act, dtype='int32')reward = paddle.to_tensor(reward, dtype='float32')next_obs = paddle.to_tensor(next_obs, dtype='float32')terminal = paddle.to_tensor(terminal, dtype='float32')##调用算法中的learn,因为self.alg引用算法中的learn了loss = self.alg.learn(obs, act, reward, next_obs, terminal)return loss.numpy()[0]

2.Model

model就是定义网络的结构,nn.Linear(输入维度,输出维度)。前向网络就是输入进入全连接层,然后relu激活函数;再经过第二层全连接层,然后relu激活函数,最后再全连接层输出。输出维度为act_dim。

import paddle
import paddle.nn as nn
import paddle.nn.functional as F
import parlclass Model(parl.Model):""" Linear network to solve Cartpole problem.Args:obs_dim (int): Dimension of observation space.act_dim (int): Dimension of action space."""def __init__(self, obs_dim, act_dim):super(Model, self).__init__()hid1_size = 128hid2_size = 128self.fc1 = nn.Linear(obs_dim, hid1_size)self.fc2 = nn.Linear(hid1_size, hid2_size)self.fc3 = nn.Linear(hid2_size, act_dim)def forward(self, obs):h1 = F.relu(self.fc1(obs))h2 = F.relu(self.fc2(h1))Q = self.fc3(h2)return Q

3.Train

import gym
import numpy as np
from parl.utils import logger, ReplayMemoryfrom Model import Model
from Agent import Agent
from parl.algorithms import DQNLEARN_FREQ = 5  # 训练频率,不需要每一个step都learn,攒一些新增经验后再learn,提高效率
MEMORY_SIZE = 20000  # replay memory的大小,越大越占用内存
MEMORY_WARMUP_SIZE = 200  # replay_memory 里需要预存一些经验数据,再从里面sample一个batch的经验让agent去learn
BATCH_SIZE = 32  # 每次给agent learn的数据数量,从replay memory随机里sample一批数据出来
LEARNING_RATE = 0.001  # 学习率
GAMMA = 0.99  # reward 的衰减因子,一般取 0.90.999 不等# train an episode
def run_train_episode(agent, env, rpm):total_reward = 0obs = env.reset()step = 0while True:step += 1action = agent.sample(obs)——训练的时候用sampl函数next_obs, reward, done, _ = env.step(action)#这里体现了Q-learningrpm.append(obs, action, reward, next_obs, done)——存储到经验池# train model——进行学习if (len(rpm) > MEMORY_WARMUP_SIZE) and (step % LEARN_FREQ == 0):# s,a,r,s',done(batch_obs, batch_action, batch_reward, batch_next_obs,batch_done) = rpm.sample_batch(BATCH_SIZE)train_loss = agent.learn(batch_obs, batch_action, batch_reward,batch_next_obs, batch_done)total_reward += rewardobs = next_obsif done:breakreturn total_reward# evaluate 5 episodes
def run_evaluate_episodes(agent, env, eval_episodes=5, render=False):eval_reward = []for i in range(eval_episodes):obs = env.reset()episode_reward = 0while True:action = agent.predict(obs)——用训练的模型与环境交互obs, reward, done, _ = env.step(action)episode_reward += reward##记录一轮的游戏得分if render:env.render()if done:breakeval_reward.append(episode_reward)##组装为数组,再进行求平均return np.mean(eval_reward)def main():env = gym.make('MountainCar-v0')obs_dim = env.observation_space.shape[0]act_dim = env.action_space.nlogger.info('obs_dim {}, act_dim {}'.format(obs_dim, act_dim))# set action_shape = 0 while in discrete control environmentrpm = ReplayMemory(MEMORY_SIZE, obs_dim, 0)# build an agentmodel = Model(obs_dim=obs_dim, act_dim=act_dim)alg = DQN(model, gamma=GAMMA, lr=LEARNING_RATE)agent = Agent(alg, act_dim=act_dim, e_greed=0.1, e_greed_decrement=1e-6)
##加载模型save_path = './model.ckpt'agent.restore(save_path)# warmup memorywhile len(rpm) < MEMORY_WARMUP_SIZE:run_train_episode(agent, env, rpm)##总训练次数max_episode = 2000# start trainingepisode = 0while episode < max_episode:# train part一轮训练50for i in range(50):total_reward = run_train_episode(agent, env, rpm)episode += 1# test parteval_reward = run_evaluate_episodes(agent, env, render=True)logger.info('episode:{}    e_greed:{}   Test reward:{}'.format(episode, agent.e_greed, eval_reward))# save the parameters to ./model.ckptsave_path = './model.ckpt'agent.save(save_path)if __name__ == '__main__':main()

4.结果

在这里插入图片描述

这篇关于使用paddle2的DQN跑Mountain的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/304365

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W