关于后端:CS-285-DRL-Homework-1模仿学习的策略函数

39次阅读

共计 3812 个字符,预计需要花费 10 分钟才能阅读完成。

对于 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 多平台公布

正文完
 0