这个难度有些大,有两个policy,一个负责更新策略,另一个负责提供数据,实际这两个policy是一个东西,用policy1跑出一组数据给新的policy2训练,然后policy2跑数据给新的policy3训练,,,,直到policy(N-1)跑数据给新的policyN训练,过程感觉和DQN比较像,但是模型是actor critic 架构,on-policy转换成off-policy,使用剪切策略来限制策略的更新幅度,off-policy的好处是策略更新快,PPO的优化目标是最大化策略的期望回报,同时避免策略更新过大

import gym
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import pygame
import sys
from collections import deque # 定义策略网络
class PolicyNetwork(nn.Module):
def __init__(self):
super(PolicyNetwork, self).__init__()
self.fc = nn.Sequential(
nn.Linear(4, 2),
nn.Tanh(),
nn.Linear(2, 2), # CartPole的动作空间为2
nn.Softmax(dim=-1)
) def forward(self, x):
return self.fc(x) # 定义值网络
class ValueNetwork(nn.Module):
def __init__(self):
super(ValueNetwork, self).__init__()
self.fc = nn.Sequential(
nn.Linear(4, 2),
nn.Tanh(),
nn.Linear(2, 1)
) def forward(self, x):
return self.fc(x) # 经验回放缓冲区
class RolloutBuffer:
def __init__(self):
self.states = []
self.actions = []
self.rewards = []
self.dones = []
self.log_probs = [] def store(self, state, action, reward, done, log_prob):
self.states.append(state)
self.actions.append(action)
self.rewards.append(reward)
self.dones.append(done)
self.log_probs.append(log_prob) def clear(self):
self.states = []
self.actions = []
self.rewards = []
self.dones = []
self.log_probs = [] def get_batch(self):
return (
torch.tensor(self.states, dtype=torch.float),
torch.tensor(self.actions, dtype=torch.long),
torch.tensor(self.rewards, dtype=torch.float),
torch.tensor(self.dones, dtype=torch.bool),
torch.tensor(self.log_probs, dtype=torch.float)
) # PPO更新函数
def ppo_update(policy_net, value_net, optimizer_policy, optimizer_value, buffer, epochs=10, gamma=0.99, clip_param=0.2):
states, actions, rewards, dones, old_log_probs = buffer.get_batch()
returns = []
advantages = []
G = 0
adv = 0
dones = dones.to(torch.int)
# print(dones)
for reward, done, value in zip(reversed(rewards), reversed(dones), reversed(value_net(states))):
if done:
G = 0
adv = 0
G = reward + gamma * G #蒙特卡洛回溯G值
delta = reward + gamma * value.item() * (1 - done) - value.item() #TD差分
# adv = delta + gamma * 0.95 * adv * (1 - done) #
adv = delta + adv*(1-done)
returns.insert(0, G)
advantages.insert(0, adv) returns = torch.tensor(returns, dtype=torch.float) #价值
advantages = torch.tensor(advantages, dtype=torch.float)
advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8) #add baseline for _ in range(epochs):
action_probs = policy_net(states)
dist = torch.distributions.Categorical(action_probs)
new_log_probs = dist.log_prob(actions)
ratio = (new_log_probs - old_log_probs).exp()
surr1 = ratio * advantages
surr2 = torch.clamp(ratio, 1.0 - clip_param, 1.0 + clip_param) * advantages
actor_loss = -torch.min(surr1, surr2).mean() optimizer_policy.zero_grad()
actor_loss.backward()
optimizer_policy.step() value_loss = (returns - value_net(states)).pow(2).mean() optimizer_value.zero_grad()
value_loss.backward()
optimizer_value.step() # 初始化环境和模型
env = gym.make('CartPole-v1')
policy_net = PolicyNetwork()
value_net = ValueNetwork()
optimizer_policy = optim.Adam(policy_net.parameters(), lr=3e-4)
optimizer_value = optim.Adam(value_net.parameters(), lr=1e-3)
buffer = RolloutBuffer() # Pygame初始化
pygame.init()
screen = pygame.display.set_mode((600, 400))
clock = pygame.time.Clock() draw_on = False
# 训练循环
state = env.reset()
for episode in range(10000): # 训练轮次
done = False
state = state[0]
step= 0
while not done:
step+=1
state_tensor = torch.FloatTensor(state).unsqueeze(0)
action_probs = policy_net(state_tensor)
dist = torch.distributions.Categorical(action_probs)
action = dist.sample()
log_prob = dist.log_prob(action) next_state, reward, done, _ ,_ = env.step(action.item())
buffer.store(state, action.item(), reward, done, log_prob) state = next_state # 实时显示
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit() if draw_on:
# 清屏并重新绘制
screen.fill((0, 0, 0))
cart_x = int(state[0] * 100 + 300) # 位置转换为屏幕坐标
pygame.draw.rect(screen, (0, 128, 255), (cart_x, 300, 50, 30))
pygame.draw.line(screen, (255, 0, 0), (cart_x + 25, 300), (cart_x + 25 - int(50 * np.sin(state[2])), 300 - int(50 * np.cos(state[2]))), 5)
pygame.display.flip()
clock.tick(600) if step >10000:
draw_on = True
ppo_update(policy_net, value_net, optimizer_policy, optimizer_value, buffer)
buffer.clear()
state = env.reset()
print(f'Episode {episode} completed {step}.') # 结束训练
env.close()
pygame.quit()

运行效果

PPO近端策略优化玩cartpole游戏的更多相关文章

  1. TensorFlow利用A3C算法训练智能体玩CartPole游戏

    本教程讲解如何使用深度强化学习训练一个可以在 CartPole 游戏中获胜的模型.研究人员使用 tf.keras.OpenAI 训练了一个使用「异步优势动作评价」(Asynchronous Advan ...

  2. DRL 教程 | 如何保持运动小车上的旗杆屹立不倒?TensorFlow利用A3C算法训练智能体玩CartPole游戏

    本教程讲解如何使用深度强化学习训练一个可以在 CartPole 游戏中获胜的模型.研究人员使用 tf.keras.OpenAI 训练了一个使用「异步优势动作评价」(Asynchronous Advan ...

  3. 适合码农工作时玩的游戏:Scrum

    适合码农工作时玩的游戏:Scrum 昨天遇到一个来自微软的面试者,在面试的最后,我简单介绍了一下我们团队使用一周一次的 Scrum 来做项目管理.他回答说:” 我在微软也用 Scrum,不过我们一周两 ...

  4. 玩QQ游戏,见到好几个图像是美女的QQ,就不始玩

    玩QQ游戏,见到好几个图像是美女的QQ,光占坑就是不开始玩 加了一个,发现是传播不良网站的QQ 聊天还是自动的 估计是利用webqq写的程序,也就那几句话来回重复,让你去注册网站什么 可以加这个Q去体 ...

  5. 使用PS3手柄在PC玩Unity3D游戏

    PS3手柄玩Unity游戏 今天把公司的PS3手柄接到PC上,想用手柄试一下玩赛车的感觉,老感觉用键盘按键玩的不爽. 把PS3的手柄接到PC上之后,系统提示正在安装驱动--,百度找资料,如何在PC上使 ...

  6. 伯克利、OpenAI等提出基于模型的元策略优化强化学习

    基于模型的强化学习方法数据效率高,前景可观.本文提出了一种基于模型的元策略强化学习方法,实践证明,该方法比以前基于模型的方法更能够应对模型缺陷,还能取得与无模型方法相近的性能. 引言 强化学习领域近期 ...

  7. 用python玩推理游戏还能掌握基础知识点,有趣又充实,你不试试吗?

    可能更多的人依然还在苦苦的学python各种知识点,但其实同样很多人,玩着游戏就把python学会了.     用python玩推理游戏,是这份python教程中的12个游戏的其中之一. 有关这份Py ...

  8. Linux系统中有趣的命令(可以玩小游戏)

    Linux系统中有趣的命令(可以玩小游戏) 前言 最近,我在看一些关于Linux系统的内容,这里面的内容是真的越学越枯燥,果然学习的过程还是不容易的.记得前几个月初学Linux时,有时候就会碰到小彩蛋 ...

  9. Bert不完全手册3. Bert训练策略优化!RoBERTa & SpanBERT

    之前看过一条评论说Bert提出了很好的双向语言模型的预训练以及下游迁移的框架,但是它提出的各种训练方式槽点较多,或多或少都有优化的空间.这一章就训练方案的改良,我们来聊聊RoBERTa和SpanBER ...

  10. 策略梯度训练cartpole小游戏

    我原来已经安装了anaconda,在此基础上进入cmd进行pip install tensorflow和pip install gym就可以了. 在win10的pycharm做的. policy_gr ...

随机推荐

  1. #根号分治,前缀和,双指针#CF1446D2 Frequency Problem (Hard Version)

    题目 给定一个长度为 \(n\) 的序列,问是否存在一个最长的区间使得至少存在两个众数. 分析 实际上 Easy Version 是用来启发大于根号的做法的. 众数可以说有一个性质吧,答案区间中的其中 ...

  2. 基于HANA重构业务的总结

    本文于2019年7月29日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 依据领导的规划,本月启动了一项业务迁移工作,作为特别行动,部门安 ...

  3. 探索基于WebRTC的有感录屏技术开发流程

    第一章:技术原理 WebRTC(Web Real-Time Communication)是一种开放源代码项目,旨在通过浏览器之间的点对点通信实现实时音视频通信.WebRTC利用JavaScript A ...

  4. 深入理解 C# 编程:枚举、文件处理、异常处理和数字相加

    C# 枚举 枚举是一个特殊的"类",表示一组常量(不可更改/只读变量). 要创建枚举,请使用 enum 关键字(而不是 class 或 interface),并用逗号分隔枚举项: ...

  5. 从零开始学Spring Boot系列-SpringApplication

    SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式.在很多情况下, 你只需委托给 SpringApplication.run这个静态方法 : @Spring ...

  6. How to install Django-Install Python Django | Django 安装指南【官方版】

    How to install Django¶ This document will get you up and running with Django. Install Python--Linux ...

  7. sass 基本常识

    一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.我的目标是,有了这篇文章,日常的一 ...

  8. C/C++常考习题

    1.什么是虚函数?什么是纯虚函数? 虚函数:允许被其子类重新定义的成员函数. 虚函数的声明:virtual returntype func(parameter);引入虚函数的目的是为了动态绑定: 纯虚 ...

  9. 简单介绍 Vue 3.0 项目创建

    一.前期转杯 确保电脑上已安装 node.js. 可通过命令 npm --version进行查询,如果展示了版本号,则说明已安装,若提示 npm 不是有内部或外部命令,也不是可运行的程序,则说明未安装 ...

  10. Faiss 向量库编译安装

    Faiss 是 Facebook 开源的一套高效相似性搜索以及向量聚类的开发库,支持各类相似性搜索的算法,Faiss 项目本身是使用 C++ 编写的,但是提供 Python 的绑定,可以直接使用 nu ...