概括来说,RL要解决的问题是:让agent学习在一个环境中的如何行为动作(act), 从而获得最大的奖励值总和(total reward)。
这个奖励值一般与agent定义的任务目标关联。
agent需要的主要学习内容:第一是行为策略(action policy), 第二是规划(planning)。
其中,行为策略的学习目标是最优策略, 也就是使用这样的策略,可以让agent在特定环境中的行为获得最大的奖励值,从而实现其任务目标。
行为(action)可以简单分为:
DDPG是针对连续行为的策略学习方法。
在RL领域,DDPG主要从:PG -> DPG -> DDPG 发展而来。
R.Sutton 在2000年提出的Policy Gradient 方法,是RL中,学习连续的行为控制策略的经典方法,其提出的解决方案是:
通过一个概率分布函数 , 来表示每一步的最优策略, 在每一步根据该概率分布进行action采样,获得当前的最佳action取值;即:
生成action的过程,本质上是一个随机过程;最后学习到的策略,也是一个随机策略(stochastic policy).
Deepmind的D.Silver等在2014年提出DPG: Deterministic Policy Gradient, 即确定性的行为策略,每一步的行为通过函数μ 直接获得确定的值:
这个函数μ即最优行为策略,不再是一个需要采样的随机策略。
为何需要确定性的策略?简单来说,PG方法有以下缺陷:
Deepmind在2016年提出DDPG,全称是:Deep Deterministic Policy Gradient,是将深度学习神经网络融合进DPG的策略学习方法。
相对于DPG的核心改进是: 采用卷积神经网络作为策略函数μ 和Q 函数的模拟,即策略网络和Q网络;然后使用深度学习的方法来训练上述神经网络。
Q函数的实现和训练方法,采用了Deepmind 2015年发表的DQN方法 ,即 Alpha Go使用的Q函数方法。
import gym
import paddle
import paddle.nn as nn
from itertools import count
from paddle.distribution import Normal
import numpy as np
from collections import deque
import random
import paddle.nn.functional as F
# 定义评论家网络结构
# DDPG这种方法与Q学习紧密相关,可以看作是连续动作空间的深度Q学习。
class Critic(nn.Layer):
def __init__(self):
super(Critic, self).__init__()
self.fc1 = nn.Linear(3, 256)
self.fc2 = nn.Linear(256 + 1, 128)
self.fc3 = nn.Linear(128, 1)
self.relu = nn.ReLU()
def forward(self, x, a):
x = self.relu(self.fc1(x))
x = paddle.concat((x, a), axis=1)
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
# 定义演员网络结构
# 为了使DDPG策略更好地进行探索,在训练时对其行为增加了干扰。 原始DDPG论文的作者建议使用时间相关的 OU噪声 ,
# 但最近的结果表明,不相关的均值零高斯噪声效果很好。 由于后者更简单,因此是首选。
class Actor(nn.Layer):
def __init__(self, is_train=True):
super(Actor, self).__init__()
self.fc1 = nn.Linear(3, 256)
self.fc2 = nn.Linear(256, 128)
self.fc3 = nn.Linear(128, 1)
self.relu = nn.ReLU()
self.tanh = nn.Tanh()
self.noisy = Normal(0, 0.2)
self.is_train = is_train
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.tanh(self.fc3(x))
return x
def select_action(self, epsilon, state):
state = paddle.to_tensor(state,dtype="float32").unsqueeze(0)
with paddle.no_grad():
action = self.forward(state).squeeze() + self.is_train * epsilon * self.noisy.sample([1]).squeeze(0)
return 2 * paddle.clip(action, -1, 1).numpy()
# 重播缓冲区:这是智能体以前的经验, 为了使算法具有稳定的行为,重播缓冲区应该足够大以包含广泛的体验。
# 如果仅使用最新数据,则可能会过分拟合,如果使用过多的经验,则可能会减慢模型的学习速度。 这可能需要一些调整才能正确。
class Memory(object):
def __init__(self, memory_size: int) -> None:
self.memory_size = memory_size
self.buffer = deque(maxlen=self.memory_size)
def add(self, experience) -> None:
self.buffer.append(experience)
def size(self):
return len(self.buffer)
def sample(self, batch_size: int, continuous: bool = True):
if batch_size > len(self.buffer):
batch_size = len(self.buffer)
if continuous:
rand = random.randint(0, len(self.buffer) - batch_size)
return [self.buffer[i] for i in range(rand, rand + batch_size)]
else:
indexes = np.random.choice(np.arange(len(self.buffer)), size=batch_size, replace=False)
return [self.buffer[i] for i in indexes]
def clear(self):
self.buffer.clear()
# 定义软更新的函数
def soft_update(target, source, tau):
for target_param, param in zip(target.parameters(), source.parameters()):
target_param.set_value(target_param * (1.0 - tau) + param * tau)
# 定义环境、实例化模型
env = gym.make('Pendulum-v1')
actor = Actor()
critic = Critic()
actor_target = Actor()
critic_target = Critic()
# 定义优化器
critic_optim = paddle.optimizer.Adam(parameters=critic.parameters(), learning_rate=3e-5)
actor_optim = paddle.optimizer.Adam(parameters=actor.parameters(), learning_rate=1e-5)
# 定义超参数
explore = 50000
epsilon = 1
gamma = 0.99
tau = 0.001
memory_replay = Memory(50000)
begin_train = False
batch_size = 32
learn_steps = 0
#writer = LogWriter('logs')
# 训练循环
for epoch in count():
state = env.reset()
episode_reward = 0
for time_step in range(200):
action = actor.select_action(epsilon, state)
next_state, reward, done, _ = env.step([action])
episode_reward += reward
reward = (reward + 8.1) / 8.1
memory_replay.add((state, next_state, action, reward))
if memory_replay.size() > 1280:
learn_steps += 1
if not begin_train:
print('train begin!')
begin_train = True
experiences = memory_replay.sample(batch_size, False)
batch_state, batch_next_state, batch_action, batch_reward = zip(*experiences)
batch_state = paddle.to_tensor(batch_state, dtype="float32")
batch_next_state = paddle.to_tensor(batch_next_state, dtype="float32")
batch_action = paddle.to_tensor(batch_action, dtype="float32").unsqueeze(1)
batch_reward = paddle.to_tensor(batch_reward, dtype="float32").unsqueeze(1)
# 均方误差 y - Q(s, a) , y是目标网络所看到的预期收益, 而 Q(s, a)是Critic网络预测的操作值。
# y是一个移动的目标,评论者模型试图实现的目标;这个目标通过缓慢的更新目标模型来保持稳定。
with paddle.no_grad():
Q_next = critic_target(batch_next_state, actor_target(batch_next_state))
Q_target = batch_reward + gamma * Q_next
critic_loss = F.mse_loss(critic(batch_state, batch_action), Q_target)
critic_optim.clear_grad()
critic_loss.backward()
critic_optim.step()
#writer.add_scalar('critic loss', critic_loss.numpy(), learn_steps)
# 使用Critic网络给定值的平均值来评价Actor网络采取的行动。 我们力求使这一数值最大化。
# 因此,我们更新了Actor网络,对于一个给定状态,它产生的动作尽量让Critic网络给出高的评分。
critic.eval()
actor_loss = - critic(batch_state, actor(batch_state))
# print(actor_loss.shape)
actor_loss = actor_loss.mean()
actor_optim.clear_grad()
actor_loss.backward()
actor_optim.step()
critic.train()
#writer.add_scalar('actor loss', actor_loss.numpy(), learn_steps)
soft_update(actor_target, actor, tau)
soft_update(critic_target, critic, tau)
env.render()
if epsilon > 0:
epsilon -= 1 / explore
state = next_state
#writer.add_scalar('episode reward', episode_reward, epoch)
if epoch % 10 == 0:
print('Epoch:{}, episode reward is {}'.format(epoch, episode_reward))
if epoch % 200 == 0:
paddle.save(actor.state_dict(), 'model/ddpg-actor' + str(epoch) + '.para')
paddle.save(critic.state_dict(), 'model/ddpg-critic' + str(epoch) + '.para')
print('model saved!')
文章浏览阅读341次。spring-cloud-hystrix之spring-cloud-1.3.4(Dalston.SR3)-boot(1.5.6) 学习笔记概述hystrix可单独使用,也可与feign搭配使用,详见HystrixTargeter参考 https://fangjian0423.github.io/2017/02/19/springcloud-hystrix/http://blog.csdn.n_springcloud dalston.sr3怎么引用
文章浏览阅读991次。前言:在程序员的日常开发工作中,会遇到这样的情况,我们需要用自己本地的工作笔记本连接到大的服务器进行开发,因为大服务器的硬件性能强悍,有很多软件环境。我们在自己的笔记本进行开发需要用到这些软硬件环境,尤其在深度学习项目开发过程中,需要非常好的显卡,而显卡资源一般都部署在大服务器上。下面讲具体步骤:ssh和vscode的安装不再赘述,网上有很多教程。1,打开vscode编辑器,进入"扩展:商店":在搜索框里搜索Remote-SSH,下载好这个插件。2,点击左下角绿色部分"打开远程窗口",出现下图内容_ubuntu 通过 ssh 连接到远程服务器方便编辑代码的工具
文章浏览阅读3.2k次,点赞4次,收藏13次。概述GPU(Graphics Processing Unit) 图形处理单元,又称图形处理器,是我们所周知的显卡的核心部件,是显卡的“心脏”。按照字面意..._前台应用加速核心
文章浏览阅读4.3k次,点赞5次,收藏18次。本文详细介绍如何将串口通信将数据进行本次存储,主要介绍常用的csv、txt格式文件,由多年实战经验总结,绝对干货!_读取并保存串口发送来的数据
文章浏览阅读229次。对象锁:同步方法锁住的是对象A.一个对象+有多个synchronized方法:某一时刻内,只要有一个线程去调用其中一个synchronized 方法,其他的线程都要等待。B.一个对象中+synchronized方法+非synchronized方法:某个线程访问同步方法不影响其他线程访问非同步方法C.多个对象+多个同步方法:访问不同的对象的同步方法不会相互影响全局锁:静态同步方法锁的是当前的..._如果为put方法加synchronized锁,锁住的是什么?是一个put还是所有put方法?
文章浏览阅读2.5k次。最近有用户反馈在mac下通过airmail、outlook这样的邮件客户端查看系统发出邮件的标题显示为乱码,但是windows下正常。通过邮件客户端保存为eml,用sublime text 2打开,可以发现展示为以下效果:Date: Wed, 01 Jul 2015 19:54:57 +0800From: To: "=?GBK?B?zt6+zA==?=" Subject: [MTLÑз¢Ö§³Å..._outlook 2013 转发邮件 乱码
文章浏览阅读619次。python自定义复杂排序的使用(含案例)_python 自定义复合排序
文章浏览阅读2.8k次,点赞86次,收藏44次。在这一小节中,重点要理解的就是组件的编程思想。组件表示页面中的部分功能(包含自己的逻辑与样式),可以组合多个组件实现完整的页面功能。问题是,如何确定页面中哪些内容划分到一个组件中呢?你可以将组件当作一种函数或者是对象来考虑(函数的功能是单一的),根据[单一功能原则]来判定组件的范围。也就是说,一个组件原则上只能负责一个功能。如果它需要负责更多的功能,这时候就应该考虑将它拆分成更小的组件。定义:组件是可复用的Vue实例,准确讲它是的实例,继承自Vue分类:有状态组件(有data属性),
文章浏览阅读7.1k次。Springer期刊 latex投稿经验分享_投期刊要求latex
文章浏览阅读192次。1制造业数字化工艺目标1) 通过PLM项目的实施能够理顺企...
文章浏览阅读3.7k次,点赞5次,收藏17次。文件包含漏洞详解_ctf 文件包含
文章浏览阅读970次。文章目录java占位符具体使用搭配转换符的标志java占位符拼接字符串显示十分麻烦,因此java中存在大量占位符用来规范输出诸如:String.format("0.5(-%d)+", i),类似c语言的printf方法,比“0.5(-”+…更加简洁易懂String类的format()方法具体使用format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。format(Locale locale, String fo_%x java