On-policy Control with Approximation
回合半梯度控制
将半梯度预测方法推广到动作价值上,这种情况下是动作-价值函数 q ^ ≈ q π \hat{q} \approx q_\pi q^≈qπ 的近似,其表示为带有权重向量 w \mathbf{w} w 的参数化函数形式
现在我们考虑形式 S t , A t ↦ U t S_t , A_t \mapsto U_t St,At↦Ut 的样例
更新的目标 U t U_t Ut 可以是 q π ( S t , A t ) q_\pi (S_t, A_t) qπ(St,At) 的任何近似,包括通常的备份值,像完整蒙特卡洛回报 G t G_t Gt 或任何 n-步 Sarsa 回报
动作-价值预测的一般梯度下降更新是:
w t + 1 ≐ w t + α [ U t − q ^ ( S t , A t , w t ) ] ∇ q ^ ( S t , A t , w t ) \mathbf{w}_{t+1} \doteq \mathbf{w}_t + \alpha [U_t - \hat{q}(S_t, A_t, \mathbf{w}_t)] \nabla \hat{q} (S_t, A_t, \mathbf{w}_t) wt+1≐wt+α[Ut−q^(St,At,wt)]∇q^(St,At,wt)
比如,一步 Sarsa 方法的更新是:
w t + 1 ≐ w t + α [ R t + 1 + γ q ^ ( S t + 1 , A t + 1 , w t ) − q ^ ( S t , A t , w t ) ] ∇ q ^ ( S t , A t , w t ) \mathbf{w}_{t+1} \doteq \mathbf{w}_t + \alpha [R_{t+1} + \gamma \hat{q}(S_{t+1}, A_{t+1}, \mathbf{w}_t) - \hat{q}(S_t, A_t, \mathbf{w}_t)] \nabla \hat{q} (S_t, A_t, \mathbf{w}_t) wt+1≐wt+α[Rt+1+γq^(St+1,At+1,wt)−q^(St,At,wt)]∇q^(St,At,wt)
我们叫这种方法为回合半梯度一步 Sarsa
对于常量策略,这个方法以与 TD(0) 相同方式收敛,并带有同类型的误差边界
为了形成控制方法,我们需要将这种动作-价值预测方法和策略提升与动作选择技术相结合
如果动作集合是离散的并且不太大,那么我们可以使用前面已经介绍的技术
对在下一个状态 S t + 1 S_{t+1} St+1 可用的每一个可能动作 a a a,我们可以计算 q ^ ( S t + 1 , a , w t ) \hat{q}(S_{t+1}, a, \mathbf{w}_t) q^(St+1,a,wt),然后找到贪婪动作 A t + 1 = arg max a q ^ ( S t + 1 , a , w t ) A_{t+1} = \argmax_a \hat{q}(S_{t+1}, a, \mathbf{w}_t) At+1=aargmaxq^(St+1,a,wt)
接着,通过将估计策略更改为贪婪策略的软近似来完成策略提升
动作也根据相同的策略来选择
下面是伪代码:
案例:陡坡汽车任务
考虑如下图所示的汽车爬坡问题:
注意重力要强于汽车的引擎,即使是全油门时,汽车也不能在斜坡上加速
唯一的解决方案是首先远离目标,驱车驶向左边的斜坡,然后通过全油门建立足够的惯性以便到达目标点
在所有时间步的奖励都是 -1,除了汽车冲过山顶目标,结束了这一回合
有三种可能的动作:全油门前进(+1),全油门倒车(-1),零油门(0)
其位置 x t x_t xt,速度 x ˙ t \dot{x}_t x˙t 由以下公式更新:
其中 b o u n d bound bound 操作强制 − 1.2 ⩽ x t + 1 ⩽ 0.5 -1.2 \leqslant x_{t+1} \leqslant 0.5 −1.2⩽xt+1⩽0.5 和 − 0.07 ⩽ x ˙ t + 1 ⩽ 0.07 -0.07 \leqslant \dot{x}_{t+1} \leqslant 0.07 −0.07⩽x˙t+1⩽0.07
此外,当 x t + 1 x_{t+1} xt+1 到达左边界时, x ˙ t + 1 \dot{x}_{t+1} x˙t+1 重置为零
当其到达右边界时,到达目标,回合结束
每个回合开始于随机位置 x t ∈ [ − 0.6 , − 0.4 ) x_t \in [-0.6, -0.4) xt∈[−0.6,−0.4) 和零初速度
程序:
mlpack 有相同的环境,我们直接拿来用:
/**
* Implementation of Mountain Car task.
*/
class MountainCar
{
public:
/**
* Implementation of state of Mountain Car. Each state is a
* (velocity, position) vector.
*/
class State
{
public:
/**
* Construct a state instance.
*/
State(): data(dimension, arma::fill::zeros)
{
/* Nothing to do here. */ }
/**
* Construct a state based on the given data.
*
* @param data Data for the velocity and position.
*/
State(const arma::colvec& data): data(data)
{
/* Nothing to do here. */ }
//! Modify the internal representation of the state.
arma::colvec& Data() {
return data; }
//! Get the velocity.
double Velocity() const {
return data[0]; }
//! Modify the velocity.
double& Velocity() {
return data[0]; }
//! Get the position.
double Position() const {
return data[1]; }
//! Modify the position.
double& Position() {
return data[1]; }
//! Encode the state to a column vector.
const arma::colvec& Encode() const {
return data; }
//! Dimension of the encoded state.
static constexpr size_t dimension = 2;
private:
//! Locally-stored velocity and position vector.
arma::colvec data;
};
/**
* Implementation of action of Mountain Car.
*/
class Action
{
public:
enum actions
{
backward,
stop,
forward
};
// To store the action.
Action::actions action;
// Track the size of the action space.
static const size_t size = 3;
};
/**
* Construct a Mountain Car instance using the given constant.
*
* @param maxSteps The number of steps after which the episode
* terminates. If the value is 0, there is no limit.
* @param positionMin Minimum legal position.
* @param positionMax Maximum legal position.
* @param positionGoal Final target position.
* @param velocityMin Minimum legal velocity.
* @param velocityMax Maximum legal ve