首页 > 编程语言 >强化学习的REIINFORCE算法和交叉熵RL算法

强化学习的REIINFORCE算法和交叉熵RL算法

时间:2022-10-02 14:39:42浏览次数:65  
标签:step batch 算法 REIINFORCE act RL reward obs

注意:

本文并不讲REINFORCE算法,而是讲强化学习的交叉熵算法,关于REINFORCE算法可以参看:


 

 

 

==========================================

 

 

 

强化学习有多种分类方法,其中一类分法为:

  • 基于值函数的。该种类型的强化学习算法,比较有代表的基础算法有Q-learning算法、Sarsa算法等。
  • 基于策略梯度的。该种类型的强化学习算法,比较有代表的基础算法有REINFORCE、交叉熵RL算法等。

 

 

本文主要讲交叉熵RL算法。交叉熵RL不同于REINFORCE算法,损失函数中是不使用奖励值的。交叉熵RL在每次和环境交互采集一定数量的episodes数据后根据奖励值选择其中一定比例的episodes数据,然后根据这些选定数据中动作的选择和对应的概率来进行交叉熵损失计算。如果在选定的episodes数据中有某个step,该step中状态可选择的动作为a0,a1,a2,a3这四个动作,假设agent最终选择的动作为a2,计算损失函数时得到在该step下选择a2的概率为p2,那么计算时使用交叉熵函数则可以写为  -(0*logp0  + 0*logp1 + 1*logp2  +  0*logp3 ) = -logp2  。在对episodes数据进行选择时,我们可以根据最终奖励值的大小选择一定百分比的episodes,如选择最好的30%的episodes (在下面代码中百分位数设为70,就是选择最好的30%数据)。

 

需要注意的是交叉熵RL算法是十分基础的RL算法,缺点也很多,现在很少会有人使用,了解这个算法重要意义在于学习。在交叉熵RL算法可以使用对以往表现好的episodes数据进行保存,然后和新获得的数据一起进行再次训练,该种方式一般叫做保留精英操作。

 

 

给出CartPole环境下的一个交叉熵RL算法的代码:(Pytorch框架)

import gym
from collections import namedtuple
import numpy as np
from tensorboardX import SummaryWriter

import torch
import torch.nn as nn
import torch.optim as optim


HIDDEN_SIZE = 128
BATCH_SIZE = 16
PERCENTILE = 70


class Net(nn.Module):
def __init__(self, obs_size, hidden_size, n_actions):
super(Net, self).__init__()
self.net = nn.Sequential(
nn.Linear(obs_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, n_actions)
)

def forward(self, x):
return self.net(x)


Episode = namedtuple('Episode', field_names=['reward', 'steps'])
EpisodeStep = namedtuple('EpisodeStep', field_names=['observation', 'action'])


def iterate_batches(env, net, batch_size):
batch = []
episode_reward = 0.0
episode_steps = []
obs = env.reset()
sm = nn.Softmax(dim=1)
while True:
obs_v = torch.FloatTensor([obs])
act_probs_v = sm(net(obs_v))
act_probs = act_probs_v.data.numpy()[0]
action = np.random.choice(len(act_probs), p=act_probs)
next_obs, reward, is_done, _ = env.step(action)
episode_reward += reward
step = EpisodeStep(observation=obs, action=action)
episode_steps.append(step)
if is_done:
e = Episode(reward=episode_reward, steps=episode_steps)
batch.append(e)
episode_reward = 0.0
episode_steps = []
next_obs = env.reset()
if len(batch) == batch_size:
yield batch
batch = []
obs = next_obs


def filter_batch(batch, percentile):
rewards = list(map(lambda s: s.reward, batch))
reward_bound = np.percentile(rewards, percentile)
reward_mean = float(np.mean(rewards))

train_obs = []
train_act = []
for reward, steps in batch:
if reward < reward_bound:
continue
train_obs.extend(map(lambda step: step.observation, steps))
train_act.extend(map(lambda step: step.action, steps))

train_obs_v = torch.FloatTensor(train_obs)
train_act_v = torch.LongTensor(train_act)
return train_obs_v, train_act_v, reward_bound, reward_mean


if __name__ == "__main__":
env = gym.make("CartPole-v0")
# env = gym.wrappers.Monitor(env, directory="mon", force=True)
obs_size = env.observation_space.shape[0]
n_actions = env.action_space.n

net = Net(obs_size, HIDDEN_SIZE, n_actions)
objective = nn.CrossEntropyLoss()
optimizer = optim.Adam(params=net.parameters(), lr=0.01)
writer = SummaryWriter(comment="-cartpole")

for iter_no, batch in enumerate(iterate_batches(
env, net, BATCH_SIZE)):
obs_v, acts_v, reward_b, reward_m = \
filter_batch(batch, PERCENTILE)
optimizer.zero_grad()
action_scores_v = net(obs_v)
loss_v = objective(action_scores_v, acts_v)
loss_v.backward()
optimizer.step()
print("%d: loss=%.3f, reward_mean=%.1f, rw_bound=%.1f" % (
iter_no, loss_v.item(), reward_m, reward_b))
writer.add_scalar("loss", loss_v.item(), iter_no)
writer.add_scalar("reward_bound", reward_b, iter_no)
writer.add_scalar("reward_mean", reward_m, iter_no)
if reward_m > 199:
print("Solved!")
break
writer.close()

 

 

 

 

============================================

 

 

强化学习的REIINFORCE算法和交叉熵算法作为比较基础的算法经常作为baseline被提及,关于REIINFORCE算法可以参看:


 

 

 

============================================

 

标签:step,batch,算法,REIINFORCE,act,RL,reward,obs
From: https://blog.51cto.com/u_15642578/5729298

相关文章

  • BF(暴力求解算法)
    BF(暴力求解算法)即是暴力(BruteForce)算法,是普通的模式匹配算法,BF算法的思想就是将目标串T的第一个字符和主串的S的第一个字符进行匹配,若相等,则则继续匹配T串和S串的第二......
  • C++实现双向RRT算法
    C++实现双向RRT算法背景介绍RRT(Rapidly-exploringRandomTrees)是StevenM.LaValle和JamesJ.KuffnerJr.提出的一种通过所及构建空间搜索树实现对非凸高维空间快速搜......
  • 字符串匹配基础(上):如何借助哈希算法实现高效字符串匹配?
    链接:https://time.geekbang.org/column/article/71187目录字符串匹配算法BF算法RK算法字符串匹配算法BF算法、RK算法、BM算法、KMP算法BF算法和RK算法:单模......
  • KMP算法
    KMP算法首先kmp算法有两个字符串,一个目标串s[],一个模板串p[]我们需要对模板串进行预处理,创建一个数组ne[i]表示以p[i]为结尾的字符串和前缀相等字符串的最长长度,就是前缀......
  • 对于关键路径算法中最迟发生时间取最小值的理解
    问题产生:错误理解:当前事件的最迟发生时间vl(i)的产生跟与之直接关联的后继事件j和中间活动<i,j>有关,如果要使当前事件发生的时间“最晚”,应当取集合{j}中产生的最大......
  • 基础算法五大板块
    基础动态规划基础的DP题目,模板题等。基础图论基础的最短路,最小生成树,拓扑排序等算法基础数学基础数论基础字符串基础算法骗分必备......
  • python关于算法题的输入
    关于Python算法题的输入处理最近在准备蓝桥杯,打算报Python组,所以开始尝试用Python刷算法题。【python&ACM输入输出的处理:sys.stdin.readline().strip().split())】上......
  • 高级算法/数据结构
    AhoCorasick自动机用于多模式字符串匹配。可持久化线段树利用前缀和思想求区间第k小等不易直接求出的值。后缀数组Manacher求最长回文串。......
  • 【WSN定位】基于改进chan算法和talor算法实现多基站目标定位附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 【无人机】基于A星算法和B次样条实现危险模型实现无人机三维航迹规划附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......