对于 CS 285 深度强化学习 Homework 1 的笔记很少,百度到 前年 一些同学的笔记,感觉有点不太对。。

这里写一些集体了解,敬供各位批评。

策略(Policy)函数的实现

间断动作空间 & 高斯策略实现

首先明确,这里的 “间断动作空间” ( $\pi(a|s)$ ) 就是单峰的高斯分布。即 动作向量的每个重量间断、独立且别离遵从不同参数的高斯分布。

因而首先如果是高斯函数 ( $\pi_{\mu,\sigma}(a|s)$ ) , 则 待预计的 未知参数为 冀望和标准差。动作值冀望随观测值不同而变动。因而反映在 Pytorch 的实现上就是如下可梯度优化的张量。

  • nn.Parameter 是一个 Tensor 的包装类。可了解为一个可参加反向流传的非凡张量。这个类能够帮忙实现某一部分参数与网络输出无关。
  • 策略冀望 $\mu$ 是与 observation 相干的参数。因而是承接观测输出的 MLP
class MLPPolicy(BasePolicy, nn.Module, metaclass=abc.ABCMeta):    def __init__(self, **kwargs):        super().__init__(**kwargs)        # init vars        if self.discrete:            pass        else:            self.logits_na = None            self.mean_net = ptu.build_mlp(                input_size=self.ob_dim, output_size=self.ac_dim,                n_layers=self.n_layers, size=self.size,            )            self.log_std = nn.Parameter(                torch.zeros(self.ac_dim, dtype=torch.float32, device=ptu.device)            )

离散动作空间 & 离散策略函数

Gym 框架(包含 Gymnasium)中离散动作空间用 Discrete 示意。

它只能示意 一个 维度的无限离散取值(多选一),而 MultiDiscrete 是示意多维的离散值(别离多选一)

因而在 CS285 Homework 1 代码中,self.logits_na 是一个动作维度 不同取值的 概率对数(log-likelihood)

class MLPPolicy(BasePolicy, nn.Module, metaclass=abc.ABCMeta):    def __init__(self, **kwargs):        super().__init__(**kwargs)        # init vars        if self.discrete:            self.logits_na = ptu.build_mlp(                input_size=self.ob_dim,                output_size=self.ac_dim,                n_layers=self.n_layers,                size=self.size,            )            self.mean_net = None            self.log_std = None        else:            pass

最初应用 torch.distributions.Distribution (的不同子类)定义散布。在 Pytorch 中散布自身是能够传递梯度的。

  • 应用 torch.distributions.Normal 定义一个正态分布(留神:是正态分布,而不是正态分布采样值)。
  • distributions.Categorical 定义离散散布。Categorical 自身能够定义多维离散散布
class MLPPolicy(BasePolicy, nn.Module, metaclass=abc.ABCMeta):    # This function defines the forward pass of the network.    # You can return anything you want, but you should be able to differentiate    # through it. For example, you can return a torch.FloatTensor. You can also    # return more flexible objects, such as a    # `torch.distributions.Distribution` object. It's up to you!    def forward(self, observation: torch.FloatTensor) -> Any:        if self.discrete:            return distributions.Categorical(self.logits_na(observation))        else:            mu = self.mean_net(observation)            std = self.log_std.exp().expand_as(mu)            return distributions.Normal(mu, std)

最终通过 sample() 办法对 Distribution 对象采样。留神这个采样值是没有梯度的。

def get_action(self, obs: np.ndarray) -> np.ndarray:    if len(obs.shape) > 1:        observation = obs    else:        observation = obs[None]    observation = ptu.from_numpy(observation)    distr = self.forward(observation)    return ptu.to_numpy(distr.sample())

上述的实现办法能够参考 PPO 的实现办法。(但优化原理上是不同的)

策略概率函数的优化

Stochastic Policy 的优化实现

如下剖析属于集体了解。

上述 离散、间断 只是策略函数的一个分类。还能够是 Deterministic 或 Stochastic(见 Lecture 4:Tradeoff)

  • Stochastic:策略函数是一个概率函数 $\pi(a_t|s_t)$ 。同一个 state 可能有不同的 action
  • Deterministic:state 与 action 是齐全的函数映射。比方 Policy 网络的输入就是 动作值,或 Q-Learning 中查表确定动作。

又因为, 这里实现的的是模拟学习,是 learned policy 与 experts' policy 的 拟合 (与其余的 RL 算法不同)。因而实质上是一种 参数估计 。(概率论 DNA 动了(大雾))

  • 矩预计:须要对散布采样。learned policy 采样均值能够近似 一阶矩 $E(A)$,而 expert policy 采样均值是 $\bar{A}$ ,那么 两个 policy 采样并作 MSE Loss 即可。然而 Distribution.sample() 没有梯度信息
  • 所以这里的办法理论是 极大似然预计:极大化如下 对数似然函数。其中 $a_i$ 是 $\pi_{expert}(a|s_i)$ 的采样
    $$\log L(\mu,\sigma)=\log(\prod_{i=1}^n\pi_{\mu,\sigma}(a_i|s_i))=\sum_{i=1}^{n}\log(\pi_{\mu,\sigma}(a_i|s_i))$$

具体如下:

class MLPPolicySL(MLPPolicy):    def __init__(self, ac_dim, ob_dim, n_layers, size, **kwargs):        super().__init__(ac_dim, ob_dim, n_layers, size, **kwargs)        self.loss = nn.MSELoss()    def update(            self, observations, actions,            adv_n=None, acs_labels_na=None, qvals=None    ):        # TODO: update the policy and return the loss        self.optimizer.zero_grad()        observations = ptu.from_numpy(observations)        actions = ptu.from_numpy(actions)        action_distribution = self.forward(observations)        loss = -action_distribution.log_prob(actions).mean()        loss.backward()        self.optimizer.step()                return {            # You can add extra logging information here, but keep this line            'Training Loss': ptu.to_numpy(loss),        }

Deterministic 和 Stochastic 不仅局限于 强化学习。

同样也是集体剖析。

  • Deterministic:有些模型自身就是 输出和输入的函数,是输出空间和输入空间的相对映射。
  • Stochastic:有些模型的输入 示意的是 概率分布。比方某些分类问题,网络输入示意的是每一类的概率,最终预测值选最大值的标号。

上述的 分类问题情景 罕用的损失函数就是 穿插熵 $H(p, q)$:

$$H(p, q)=\mathrm{E}_{p}[-\log q]=H(p)+D_{\mathrm{KL}}(p | q)$$

它是指标散布 p 的熵,加上 p 与模型散布 q 的 KL散度。Stochastic 模型就是 概率分布之间 的趋近。而 Deterministic 模型 则是 值与值之间 的拟合,所以相应的指标函数就是输入预测值和真值的 误差

本文由mdnice多平台公布