当前位置: 首页 > news >正文

强化学习之REINFORECE策略梯度算法——已CartPole环境为例

整体代码如下:

import gym
import numpy as np
import torch
import matplotlib.pyplot as plt
from tqdm import tqdm
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
def moving_average(a, window_size):cumulative_sum = np.cumsum(np.insert(a, 0, 0)) middle = (cumulative_sum[window_size:] - cumulative_sum[:-window_size]) / window_sizer = np.arange(1, window_size-1, 2)begin = np.cumsum(a[:window_size-1])[::2] / rend = (np.cumsum(a[:-window_size:-1])[::2] / r)[::-1]return np.concatenate((begin, middle, end))
class PolicyNetwork(torch.nn.Module):def __init__(self,statedim,hiddendim,actiondim):super(PolicyNetwork,self).__init__()self.cf1=torch.nn.Linear(statedim,hiddendim)self.cf2=torch.nn.Linear(hiddendim,actiondim)def forward(self,x):x=torch.nn.functional.relu(self.cf1(x))return torch.nn.functional.softmax(self.cf2(x),dim=1)
class REINFORCE:def __init__(self,statedim,hiddendim,actiondim,learningrate,gamma,device):self.policynet=PolicyNetwork(statedim,hiddendim,actiondim).to(device)self.gamma=gammaself.device=deviceself.optimizer=torch.optim.Adam(self.policynet.parameters(),lr=learningrate)def takeaction(self,state):state=torch.tensor([state],dtype=torch.float).to(self.device)probs=self.policynet(state)actiondist=torch.distributions.Categorical(probs)#torch.distributions.Categorical:这是 PyTorch 中用于表示类别分布的类,可以使用 actiondist.sample() 方法从这个分布中随机采样一个类别action=actiondist.sample()return action.item()def update(self,transitiondist):statelist=transitiondist['states']rewardlist=transitiondist['rewards']actionlist=transitiondist['actions']G=0self.optimizer.zero_grad()for i in reversed(range(len(rewardlist))):#从最后一步计算起reward=rewardlist[i]state=statelist[i]action=actionlist[i]state=torch.tensor([state],dtype=torch.float).to(self.device)action=torch.tensor([action]).view(-1,1).to(self.device)logprob=torch.log(self.policynet(state).gather(1,action)) #.gather(1, action) 方法从策略网络的输出中提取对应于特定动作 action 的概率值。这里的 1 表示沿着维度 1(通常对应于动作维度)进行索引。G=self.gamma*G+rewardloss=-logprob*G#每一步的损失函数loss.backward()#反向传播计算梯度self.optimizer.step()#更新参数,梯度下降learningrate=4e-3
episodesnum=1000
hiddendim=128
gamma=0.99
pbarnum=10
printreturnnum=10
device=torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
env=gym.make('CartPole-v1')
env.reset(seed=880)
torch.manual_seed(880)
statedim=env.observation_space.shape[0]
actiondim=env.action_space.n
agent=REINFORCE(statedim=statedim,hiddendim=hiddendim,actiondim=actiondim,learningrate=learningrate,gamma=gamma,device=device)
returnlist=[]
for  k in range(pbarnum):with tqdm(total=int(episodesnum/pbarnum),desc='Iteration %d'%k)as pbar:for episode in range(int(episodesnum/pbarnum)):g=0transitiondist={'states':[],'actions':[],'nextstates':[],'rewards':[]}state,_=env.reset(seed=880)done=Falsewhile not done:action=agent.takeaction(state)nextstate,reward,done,truncated,_=env.step(action)done=done or truncatedtransitiondist['states'].append(state)transitiondist['actions'].append(action)transitiondist['nextstates'].append(nextstate)transitiondist['rewards'].append(reward)state=nextstateg=g+rewardreturnlist.append(g)agent.update(transitiondist)if (episode+1)%(printreturnnum)==0:pbar.set_postfix({'Episode':'%d'%(episodesnum//pbarnum+episode+1),'Return':'%.3f'%np.mean(returnlist[-printreturnnum:])})pbar.update(1)episodelist=list(range(len(returnlist)))
plt.plot(episodelist,returnlist)
plt.xlabel('Episodes')
plt.ylabel('Returns')
plt.title('REINFORCE on {}'.format(env.spec.name))     
plt.show()
mvreturn=moving_average(returnlist,9)
plt.plot(episodelist,mvreturn)
plt.xlabel('Episodes')
plt.ylabel('Returns')
plt.title('REINFORCE on {}'.format(env.spec.name))
plt.show()  

效果:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 高级web安全技术(第一篇)
  • 【ARM】v8架构programmer guide(4)_ARMv8的寄存器
  • Oracle(47)如何创建和使用集合?
  • Leetcode面试经典150题-236.二叉树的最低公共祖先
  • 保研考研机试攻略:第二章——入门经典(2)
  • LVS(Linux virual server)
  • 排序算法——插入排序
  • “华为杯”第十六届中国研究生数学建模竞赛-C题:视觉情报信息分析
  • rust pin_project的使用
  • 算法经典题目:Insert Interval
  • 深入了解HTML链接:从基础到进阶——WEB开发系列06
  • C# 不使用 `async` 和 `await` 的常见场景
  • STC-ISP升级MCU
  • HCIE学习笔记:IPV6 地址、ICMP V6、NDP 、DAD (更新补充中)
  • 【路由器】RT-AC88U华硕配置DNS
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • FastReport在线报表设计器工作原理
  • HTTP请求重发
  • miaov-React 最佳入门
  • node和express搭建代理服务器(源码)
  • spring-boot List转Page
  • Vue 2.3、2.4 知识点小结
  • 第十八天-企业应用架构模式-基本模式
  • 通过几道题目学习二叉搜索树
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 06-01 点餐小程序前台界面搭建
  • Nginx实现动静分离
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • # 数据结构
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (24)(24.1) FPV和仿真的机载OSD(三)
  • (7) cmake 编译C++程序(二)
  • (70min)字节暑假实习二面(已挂)
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (二十六)Java 数据结构
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (转)jQuery 基础
  • ***测试-HTTP方法
  • .chm格式文件如何阅读
  • .NET 服务 ServiceController
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net下简单快捷的数值高低位切换
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • .sh 的运行
  • /etc/shadow字段详解
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @ohos.systemParameterEnhance系统参数接口调用:控制设备硬件(执行shell命令方式)
  • @RequestBody与@RequestParam:Spring MVC中的参数接收差异解析
  • [000-002-01].数据库调优相关学习
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [C++] Windows中字符串函数的种类
  • [CISCN2019 华北赛区 Day1 Web5]CyberPunk --不会编程的崽