在强化学习的领域中,主要存在基于价值和基于策略的两种学习方法。基于价值的方法,如 Q - learning,侧重于学习状态 - 动作对的价值函数,通过选择价值最大的动作来执行。而基于策略的方法则直接对策略进行优化,也就是直接学习从状态到动作的映射。REINFORCE 算法作为一种经典的基于策略的算法,在强化学习的发展历程中有着重要的地位。接下来,我们将深入探讨 REINFORCE 算法的原理、实现和应用。
在基于策略的学习中,策略通常用一个参数化的函数 $\pi{\theta}(a|s)$ 来表示,其中 $\theta$ 是策略的参数,$s$ 是状态,$a$ 是动作。这个函数表示在状态 $s$ 下选择动作 $a$ 的概率。例如,在一个简单的机器人导航任务中,状态 $s$ 可以是机器人当前的位置和朝向,动作 $a$ 可以是向前移动、向左转、向右转等,$\pi{\theta}(a|s)$ 就表示在当前状态下选择每个动作的概率。
策略梯度算法的目标是最大化累积奖励的期望。累积奖励通常用折扣后的未来奖励之和来表示,即 $Rt=\sum{k = 0}^{\infty}\gamma^{k}r{t + k}$,其中 $r{t + k}$ 是时刻 $t + k$ 的奖励,$\gamma$ 是折扣因子($0\leqslant\gamma\leqslant1$)。策略梯度算法通过调整策略的参数 $\theta$ 来最大化 $J(\theta)=E{\tau\sim\pi{\theta}}[R(\tau)]$,其中 $\tau$ 表示一个轨迹(状态 - 动作序列),$R(\tau)$ 是该轨迹的累积奖励。
REINFORCE 算法的核心思想是通过采样轨迹来估计策略梯度,然后使用梯度上升的方法来更新策略的参数。具体来说,REINFORCE 算法使用蒙特卡罗方法来估计累积奖励,即通过与环境进行交互得到一个完整的轨迹 $\tau=(s_0,a_0,r_0,s_1,a_1,r_1,\cdots)$,然后计算该轨迹的累积奖励 $R(\tau)$。
根据策略梯度定理,策略梯度可以表示为:
$\nabla{\theta}J(\theta)=E{\tau\sim\pi{\theta}}[\sum{t = 0}^{T}\nabla{\theta}\log\pi{\theta}(at|s_t)R(\tau)]$
其中,$\nabla{\theta}\log\pi_{\theta}(a_t|s_t)$ 是对数策略的梯度,$R(\tau)$ 是整个轨迹的累积奖励。
以下是一个简单的使用 PyTorch 实现 REINFORCE 算法的例子,以 OpenAI Gym 中的 CartPole 环境为例:
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import gym
# 定义策略网络
class PolicyNetwork(nn.Module):
def __init__(self, input_dim, output_dim):
super(PolicyNetwork, self).__init__()
self.fc1 = nn.Linear(input_dim, 128)
self.fc2 = nn.Linear(128, output_dim)
self.relu = nn.ReLU()
self.softmax = nn.Softmax(dim = 0)
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.softmax(self.fc2(x))
return x
# 初始化环境和策略网络
env = gym.make('CartPole-v1')
input_dim = env.observation_space.shape[0]
output_dim = env.action_space.n
policy_network = PolicyNetwork(input_dim, output_dim)
optimizer = optim.Adam(policy_network.parameters(), lr = 0.01)
gamma = 0.99
# REINFORCE 算法
for episode in range(500):
state = env.reset()
log_probs = []
rewards = []
done = False
while not done:
state = torch.FloatTensor(state)
action_probs = policy_network(state)
action = torch.multinomial(action_probs, 1).item()
log_prob = torch.log(action_probs[action])
log_probs.append(log_prob)
next_state, reward, done, _ = env.step(action)
rewards.append(reward)
state = next_state
# 计算累积奖励
R = 0
returns = []
for r in reversed(rewards):
R = r + gamma * R
returns.insert(0, R)
returns = torch.FloatTensor(returns)
# 计算损失
loss = []
for log_prob, R in zip(log_probs, returns):
loss.append(-log_prob * R)
loss = torch.stack(loss).sum()
# 更新参数
optimizer.zero_grad()
loss.backward()
optimizer.step()
if episode % 10 == 0:
print(f'Episode {episode}: Total reward = {sum(rewards)}')
env.close()
方面 | 详情 |
---|---|
核心思想 | 通过采样轨迹估计策略梯度,用梯度上升更新策略参数 |
优点 | 直接优化策略,适用于连续动作空间 |
缺点 | 高方差,样本效率低 |
应用场景 | 理论研究、连续动作空间问题初步探索 |
REINFORCE 算法作为一种经典的基于策略的强化学习算法,为后续的策略梯度算法发展奠定了基础。虽然它存在一些缺点,但通过改进和扩展,如引入基线、使用优势函数等,可以有效地降低方差,提高样本效率。在实际应用中,REINFORCE 算法可以用于一些简单的任务和理论研究,帮助我们更好地理解基于策略的学习方法。