0


【强化学习】策略梯度算法中的损失函数

策略梯度算法推导

适合有一定强化学习算法基础的人看。

首先我们定义一条轨迹的奖励,有两种定义方法:
无折扣有限步奖励

     R
    
    
     (
    
    
     τ
    
    
     )
    
    
     =
    
    
     
      ∑
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      T
     
    
    
     
      r
     
     
      t
     
    
    
     .
    
   
   
    R(\tau) = \sum_{t=0}^T r_t.
   
  
 R(τ)=t=0∑T​rt​.

折扣无限步奖励

     R
    
    
     (
    
    
     τ
    
    
     )
    
    
     =
    
    
     
      ∑
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      ∞
     
    
    
     
      γ
     
     
      t
     
    
    
     
      r
     
     
      t
     
    
    
     .
    
   
   
    R(\tau) = \sum_{t=0}^{\infty} \gamma^t r_t.
   
  
 R(τ)=t=0∑∞​γtrt​.

以上两种轨迹奖励的求和方法第一种比较简单,第二种比较合适。而且一般对于第二种也是有限的,比如游戏必然会终结的。

智能体和环境交互的过程中,产生的轨迹有很多条,强化学习的目标是使得奖励的期望值最大:
假设在环境中智能体以策略

    π
   
  
  
   \pi
  
 
π和环境进行交互产生一条轨迹

 
  
   
    τ
   
  
  
   \tau
  
 
τ的概率:

 
  
   
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     π
    
    
     )
    
    
     =
    
    
     
      ρ
     
     
      0
     
    
    
     (
    
    
     
      s
     
     
      0
     
    
    
     )
    
    
     
      ∏
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      
       T
      
      
       −
      
      
       1
      
     
    
    
     P
    
    
     (
    
    
     
      s
     
     
      
       t
      
      
       +
      
      
       1
      
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     ,
    
    
     
      a
     
     
      t
     
    
    
     )
    
    
     π
    
    
     (
    
    
     
      a
     
     
      t
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     )
    
    
     .
    
   
   
    P(\tau|\pi) = \rho_0 (s_0) \prod_{t=0}^{T-1} P(s_{t+1} | s_t, a_t) \pi(a_t | s_t).
   
  
 P(τ∣π)=ρ0​(s0​)t=0∏T−1​P(st+1​∣st​,at​)π(at​∣st​).

其中

     ρ
    
    
     0
    
   
   
    (
   
   
    
     s
    
    
     0
    
   
   
    )
   
  
  
   \rho_0(s_0)
  
 
ρ0​(s0​)是初始状态出现的概率,

 
  
   
    P
   
   
    (
   
   
    
     s
    
    
     
      t
     
     
      +
     
     
      1
     
    
   
   
    ∣
   
   
    
     s
    
    
     t
    
   
   
    ,
   
   
    
     a
    
    
     t
    
   
   
    )
   
  
  
   P(s_{t+1}|s_t,a_t)
  
 
P(st+1​∣st​,at​)是状态转移的概率,

 
  
   
    π
   
   
    (
   
   
    
     a
    
    
     t
    
   
   
    ∣
   
   
    
     s
    
    
     t
    
   
   
    )
   
  
  
   \pi(a_t|s_t)
  
 
π(at​∣st​)是策略,也就是在状态

 
  
   
    
     s
    
    
     t
    
   
  
  
   s_t
  
 
st​下采取动作

 
  
   
    
     a
    
    
     t
    
   
  
  
   a_t
  
 
at​的概率。

那么目标就是最大化期望奖励:

     J
    
    
     (
    
    
     π
    
    
     )
    
    
     =
    
    
     
      ∫
     
     
      τ
     
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     π
    
    
     )
    
    
     R
    
    
     (
    
    
     τ
    
    
     )
    
    
     =
    
    
     
      
       E
      
     
     
      
       τ
      
      
       ∼
      
      
       π
      
     
    
    
     [
    
    
     
      R
     
     
      (
     
     
      τ
     
     
      )
     
    
    
     ]
    
    
     .
    
   
   
    J(\pi) = \int_{\tau} P(\tau|\pi) R(\tau) = \mathop{E}\limits_{\tau\sim\pi}[{R(\tau)}].
   
  
 J(π)=∫τ​P(τ∣π)R(τ)=τ∼πE​[R(τ)].

强化学习的核心问题是找到一个策略,使得目标函数值最大:

      π
     
     
      ∗
     
    
    
     =
    
    
     arg
    
    
     ⁡
    
    
     
      
       max
      
      
       ⁡
      
     
     
      π
     
    
    
     J
    
    
     (
    
    
     π
    
    
     )
    
   
   
    \pi^* = \arg \max_{\pi} J(\pi)
   
  
 π∗=argπmax​J(π)

目标函数的自变量是

    π
   
  
  
   \pi
  
 
π,如果我们用某种方法来表示策略,参数是

 
  
   
    θ
   
  
  
   \theta
  
 
θ,那么上面的式子就可以写成:

 
  
   
    
     J
    
    
     (
    
    
     
      π
     
     
      θ
     
    
    
     )
    
    
     =
    
    
     
      ∫
     
     
      τ
     
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     
      π
     
     
      θ
     
    
    
     )
    
    
     R
    
    
     (
    
    
     τ
    
    
     )
    
    
     =
    
    
     
      
       E
      
     
     
      
       τ
      
      
       ∼
      
      
       
        π
       
       
        θ
       
      
     
    
    
     [
    
    
     
      R
     
     
      (
     
     
      τ
     
     
      )
     
    
    
     ]
    
    
     .
    
   
   
    J(\pi_\theta) = \int_{\tau} P(\tau|\pi_\theta) R(\tau) = \mathop{E}\limits_{\tau\sim\pi_\theta}[{R(\tau)}].
   
  
 J(πθ​)=∫τ​P(τ∣πθ​)R(τ)=τ∼πθ​E​[R(τ)].

最终目标函数是和参数

    θ
   
  
  
   \theta
  
 
θ有关的,我们只需要更新参数

 
  
   
    θ
   
  
  
   \theta
  
 
θ就能影响策略

 
  
   
    π
   
   
    (
   
   
    a
   
   
    ∣
   
   
    s
   
   
    )
   
  
  
   \pi(a|s)
  
 
π(a∣s)的分布,进而影响

 
  
   
    J
   
   
    (
   
   
    
     π
    
    
     θ
    
   
   
    )
   
  
  
   J(\pi_\theta)
  
 
J(πθ​).

接下来我们求目标函数的梯度
1.轨迹

    τ
   
  
  
   \tau
  
 
τ出现的概率

 
  
   
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     =
    
    
     
      ρ
     
     
      0
     
    
    
     (
    
    
     
      s
     
     
      0
     
    
    
     )
    
    
     
      ∏
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      T
     
    
    
     P
    
    
     (
    
    
     
      s
     
     
      
       t
      
      
       +
      
      
       1
      
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     ,
    
    
     
      a
     
     
      t
     
    
    
     )
    
    
     
      π
     
     
      θ
     
    
    
     (
    
    
     
      a
     
     
      t
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     )
    
    
     .
    
   
   
    P(\tau|\theta) = \rho_0 (s_0) \prod_{t=0}^{T} P(s_{t+1}|s_t, a_t) \pi_{\theta}(a_t |s_t).
   
  
 P(τ∣θ)=ρ0​(s0​)t=0∏T​P(st+1​∣st​,at​)πθ​(at​∣st​).

2.对轨迹的概率

    P
   
   
    (
   
   
    τ
   
   
    ∣
   
   
    θ
   
   
    )
   
  
  
   P(\tau|\theta)
  
 
P(τ∣θ)求关于

 
  
   
    θ
   
  
  
   \theta
  
 
θ的导数

这里用到了一个技巧后面会用到

      ∇
     
     
      θ
     
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     =
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     
      ∇
     
     
      θ
     
    
    
     log
    
    
     ⁡
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     .
    
   
   
    \nabla_{\theta} P(\tau | \theta) = P(\tau | \theta) \nabla_{\theta} \log P(\tau | \theta).
   
  
 ∇θ​P(τ∣θ)=P(τ∣θ)∇θ​logP(τ∣θ).


 
  
   
    log
   
   
    ⁡
   
   
    P
   
   
    (
   
   
    τ
   
   
    ∣
   
   
    θ
   
   
    )
   
  
  
   \log P(\tau|\theta)
  
 
logP(τ∣θ)可以展开为

 
  
   
    
     log
    
    
     ⁡
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     =
    
    
     log
    
    
     ⁡
    
    
     
      ρ
     
     
      0
     
    
    
     (
    
    
     
      s
     
     
      0
     
    
    
     )
    
    
     +
    
    
     
      ∑
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      T
     
    
    
     (
    
    
     log
    
    
     ⁡
    
    
     P
    
    
     (
    
    
     
      s
     
     
      
       t
      
      
       +
      
      
       1
      
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     ,
    
    
     
      a
     
     
      t
     
    
    
     )
    
    
     +
    
    
     log
    
    
     ⁡
    
    
     
      π
     
     
      θ
     
    
    
     (
    
    
     
      a
     
     
      t
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     )
    
    
     )
    
    
     .
    
   
   
    \log P(\tau|\theta) = \log \rho_0 (s_0) + \sum_{t=0}^{T} \bigg( \log P(s_{t+1}|s_t, a_t) + \log \pi_{\theta}(a_t |s_t)\bigg).
   
  
 logP(τ∣θ)=logρ0​(s0​)+t=0∑T​(logP(st+1​∣st​,at​)+logπθ​(at​∣st​)).

第一项和第二项都和参数无关,只有最后一项和参数有关:

      ∇
     
     
      θ
     
    
    
     l
    
    
     o
    
    
     g
    
    
     P
    
    
     (
    
    
     τ
    
    
     ∣
    
    
     θ
    
    
     )
    
    
     =
    
    
     
      ∑
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      T
     
    
    
     
      
       ∇
      
      
       θ
      
     
     
      l
     
     
      o
     
     
      g
     
     
      
       
        π
       
       
        θ
       
      
      
       (
      
      
       
        a
       
       
        t
       
      
      
       ∣
      
      
       
        s
       
       
        t
       
      
      
       )
      
     
    
   
   
     \nabla_{\theta}logP(\tau|\theta)=\sum_{t=0}^{T}{\nabla_{\theta}log{\pi_\theta(a_t|s_t)}} 
   
  
 ∇θ​logP(τ∣θ)=t=0∑T​∇θ​logπθ​(at​∣st​)

所以

          ∇
         
         
          θ
         
        
        
         J
        
        
         (
        
        
         
          π
         
         
          θ
         
        
        
         )
        
       
      
     
     
      
       
        
        
         =
        
        
         
          ∇
         
         
          θ
         
        
        
         
          
           E
          
         
         
          
           τ
          
          
           ∼
          
          
           
            π
           
           
            θ
           
          
         
        
        
         [
        
        
         
          R
         
         
          (
         
         
          τ
         
         
          )
         
        
        
         ]
        
       
      
     
     
      
       
      
     
    
    
     
      
       
      
     
     
      
       
        
        
         =
        
        
         
          ∇
         
         
          θ
         
        
        
         
          ∫
         
         
          τ
         
        
        
         P
        
        
         (
        
        
         τ
        
        
         ∣
        
        
         θ
        
        
         )
        
        
         R
        
        
         (
        
        
         τ
        
        
         )
        
       
      
     
     
      
       
        展开期望
       
      
     
    
    
     
      
       
      
     
     
      
       
        
        
         =
        
        
         
          ∫
         
         
          τ
         
        
        
         
          ∇
         
         
          θ
         
        
        
         P
        
        
         (
        
        
         τ
        
        
         ∣
        
        
         θ
        
        
         )
        
        
         R
        
        
         (
        
        
         τ
        
        
         )
        
       
      
     
     
      
       
        把梯度放到里面
       
      
     
    
    
     
      
       
      
     
     
      
       
        
        
         =
        
        
         
          ∫
         
         
          τ
         
        
        
         P
        
        
         (
        
        
         τ
        
        
         ∣
        
        
         θ
        
        
         )
        
        
         
          ∇
         
         
          θ
         
        
        
         log
        
        
         ⁡
        
        
         P
        
        
         (
        
        
         τ
        
        
         ∣
        
        
         θ
        
        
         )
        
        
         R
        
        
         (
        
        
         τ
        
        
         )
        
       
      
     
     
      
       
        log技巧
       
      
     
    
    
     
      
       
      
     
     
      
       
        
        
         =
        
        
         
          
           E
          
         
         
          
           τ
          
          
           ∼
          
          
           
            π
           
           
            θ
           
          
         
        
        
         
          
           ∇
          
          
           θ
          
         
         
          log
         
         
          ⁡
         
         
          P
         
         
          (
         
         
          τ
         
         
          ∣
         
         
          θ
         
         
          )
         
         
          R
         
         
          (
         
         
          τ
         
         
          )
         
        
       
      
     
     
      
       
        又重新变成期望的格式
       
      
     
    
    
     
      
       
        
         ∴
        
        
         
          ∇
         
         
          θ
         
        
        
         J
        
        
         (
        
        
         
          π
         
         
          θ
         
        
        
         )
        
       
      
     
     
      
       
        
        
         =
        
        
         
          
           E
          
         
         
          
           τ
          
          
           ∼
          
          
           
            π
           
           
            θ
           
          
         
        
        
         
          
           ∑
          
          
           
            t
           
           
            =
           
           
            0
           
          
          
           T
          
         
         
          
           ∇
          
          
           θ
          
         
         
          log
         
         
          ⁡
         
         
          
           π
          
          
           θ
          
         
         
          (
         
         
          
           a
          
          
           t
          
         
         
          ∣
         
         
          
           s
          
          
           t
          
         
         
          )
         
         
          R
         
         
          (
         
         
          τ
         
         
          )
         
        
       
      
     
     
      
       
        目标函数的梯度
       
      
     
    
   
   
     \begin{align*} \nabla_{\theta} J(\pi_{\theta}) &= \nabla_{\theta} \mathop{E}\limits_{\tau \sim \pi_{\theta}}[{R(\tau)}] & \\ &= \nabla_{\theta} \int_{\tau} P(\tau|\theta) R(\tau) & \text{展开期望} \\ &= \int_{\tau} \nabla_{\theta} P(\tau|\theta) R(\tau) & \text{把梯度放到里面} \\ &= \int_{\tau} P(\tau|\theta) \nabla_{\theta} \log P(\tau|\theta) R(\tau) & \text{log技巧} \\ &= \mathop{E}\limits_{\tau \sim \pi_{\theta}}{\nabla_{\theta} \log P(\tau|\theta) R(\tau)} & \text{又重新变成期望的格式} \\ \therefore \nabla_{\theta} J(\pi_{\theta}) &= \mathop{E}\limits_{\tau \sim \pi_{\theta}}{\sum_{t=0}^{T} \nabla_{\theta} \log \pi_{\theta}(a_t |s_t) R(\tau)} & \text{目标函数的梯度} \end{align*} 
   
  
 ∇θ​J(πθ​)∴∇θ​J(πθ​)​=∇θ​τ∼πθ​E​[R(τ)]=∇θ​∫τ​P(τ∣θ)R(τ)=∫τ​∇θ​P(τ∣θ)R(τ)=∫τ​P(τ∣θ)∇θ​logP(τ∣θ)R(τ)=τ∼πθ​E​∇θ​logP(τ∣θ)R(τ)=τ∼πθ​E​t=0∑T​∇θ​logπθ​(at​∣st​)R(τ)​展开期望把梯度放到里面log技巧又重新变成期望的格式目标函数的梯度​

最后的表达式就是我们所需要的目标函数的梯度,后面的

    R
   
   
    (
   
   
    τ
   
   
    )
   
  
  
   R(\tau)
  
 
R(τ)部分还可以写成其他的形式,这里不做讨论,例如写成Rewart-to-go的形式:

 
  
   
    
     
      ∇
     
     
      θ
     
    
    
     J
    
    
     (
    
    
     
      π
     
     
      θ
     
    
    
     )
    
    
     =
    
    
     
      
       E
      
     
     
      
       τ
      
      
       ∼
      
      
       
        π
       
       
        θ
       
      
     
    
    
     
      
       ∑
      
      
       
        t
       
       
        =
       
       
        0
       
      
      
       T
      
     
     
      
       ∇
      
      
       θ
      
     
     
      log
     
     
      ⁡
     
     
      
       π
      
      
       θ
      
     
     
      (
     
     
      
       a
      
      
       t
      
     
     
      ∣
     
     
      
       s
      
      
       t
      
     
     
      )
     
     
      
       ∑
      
      
       
        
         t
        
        
         ′
        
       
       
        =
       
       
        t
       
      
      
       T
      
     
     
      R
     
     
      (
     
     
      
       s
      
      
       
        t
       
       
        ′
       
      
     
     
      ,
     
     
      
       a
      
      
       
        t
       
       
        ′
       
      
     
     
      ,
     
     
      
       s
      
      
       
        
         t
        
        
         ′
        
       
       
        +
       
       
        1
       
      
     
     
      )
     
    
    
     .
    
   
   
    \nabla_{\theta} J(\pi_{\theta}) = \mathop{E}\limits_{\tau \sim \pi_{\theta}}{\sum_{t=0}^{T} \nabla_{\theta} \log \pi_{\theta}(a_t |s_t) \sum_{t'=t}^T R(s_{t'}, a_{t'}, s_{t'+1})}.
   
  
 ∇θ​J(πθ​)=τ∼πθ​E​t=0∑T​∇θ​logπθ​(at​∣st​)t′=t∑T​R(st′​,at′​,st′+1​).

还可以减去一个baseline来减小方差

      ∇
     
     
      θ
     
    
    
     J
    
    
     (
    
    
     
      π
     
     
      θ
     
    
    
     )
    
    
     =
    
    
     
      
       E
      
     
     
      
       τ
      
      
       ∼
      
      
       
        π
       
       
        θ
       
      
     
    
    
     
      
       ∑
      
      
       
        t
       
       
        =
       
       
        0
       
      
      
       T
      
     
     
      
       ∇
      
      
       θ
      
     
     
      log
     
     
      ⁡
     
     
      
       π
      
      
       θ
      
     
     
      (
     
     
      
       a
      
      
       t
      
     
     
      ∣
     
     
      
       s
      
      
       t
      
     
     
      )
     
     
      
       (
      
      
       
        ∑
       
       
        
         
          t
         
         
          ′
         
        
        
         =
        
        
         t
        
       
       
        T
       
      
      
       R
      
      
       (
      
      
       
        s
       
       
        
         t
        
        
         ′
        
       
      
      
       ,
      
      
       
        a
       
       
        
         t
        
        
         ′
        
       
      
      
       ,
      
      
       
        s
       
       
        
         
          t
         
         
          ′
         
        
        
         +
        
        
         1
        
       
      
      
       )
      
      
       −
      
      
       b
      
      
       (
      
      
       
        s
       
       
        t
       
      
      
       )
      
      
       )
      
     
    
    
     .
    
   
   
    \nabla_{\theta} J(\pi_{\theta}) = \mathop{E}\limits_{\tau \sim \pi_{\theta}}{\sum_{t=0}^{T} \nabla_{\theta} \log \pi_{\theta}(a_t |s_t) \left(\sum_{t'=t}^T R(s_{t'}, a_{t'}, s_{t'+1}) - b(s_t)\right)}.
   
  
 ∇θ​J(πθ​)=τ∼πθ​E​t=0∑T​∇θ​logπθ​(at​∣st​)(t′=t∑T​R(st′​,at′​,st′+1​)−b(st​)).

这个式子是正确的,因为后面的baseline不会影响梯度的值,可以证明第二项的期望为0.

回到话题,我们已经求出了目标函数的梯度:

      ∇
     
     
      θ
     
    
    
     J
    
    
     (
    
    
     
      π
     
     
      θ
     
    
    
     )
    
    
     =
    
    
     
      
       E
      
     
     
      
       τ
      
      
       ∼
      
      
       
        π
       
       
        θ
       
      
     
    
    
     
      
       ∑
      
      
       
        t
       
       
        =
       
       
        0
       
      
      
       T
      
     
     
      
       ∇
      
      
       θ
      
     
     
      log
     
     
      ⁡
     
     
      
       π
      
      
       θ
      
     
     
      (
     
     
      
       a
      
      
       t
      
     
     
      ∣
     
     
      
       s
      
      
       t
      
     
     
      )
     
     
      R
     
     
      (
     
     
      τ
     
     
      )
     
    
   
   
    \nabla_{\theta} J(\pi_{\theta}) = \mathop{E}\limits_{\tau \sim \pi_{\theta}}{\sum_{t=0}^{T} \nabla_{\theta} \log \pi_{\theta}(a_t |s_t) R(\tau)} 
   
  
 ∇θ​J(πθ​)=τ∼πθ​E​t=0∑T​∇θ​logπθ​(at​∣st​)R(τ)

最外层的期望可以通过蒙特卡洛采样的方法来实现,即采样多条轨迹然后求平均值:

      g
     
     
      ^
     
    
    
     =
    
    
     
      1
     
     
      
       ∣
      
      
       D
      
      
       ∣
      
     
    
    
     
      ∑
     
     
      
       τ
      
      
       ∈
      
      
       D
      
     
    
    
     
      ∑
     
     
      
       t
      
      
       =
      
      
       0
      
     
     
      T
     
    
    
     
      ∇
     
     
      θ
     
    
    
     log
    
    
     ⁡
    
    
     
      π
     
     
      θ
     
    
    
     (
    
    
     
      a
     
     
      t
     
    
    
     ∣
    
    
     
      s
     
     
      t
     
    
    
     )
    
    
     R
    
    
     (
    
    
     τ
    
    
     )
    
    
     ,
    
   
   
    \hat{g} = \frac{1}{|\mathcal{D}|} \sum_{\tau \in \mathcal{D}} \sum_{t=0}^{T} \nabla_{\theta} \log \pi_{\theta}(a_t |s_t) R(\tau),
   
  
 g^​=∣D∣1​τ∈D∑​t=0∑T​∇θ​logπθ​(at​∣st​)R(τ),
     D
    
   
   
    \mathcal{D}
   
  
 D是采集的轨迹的集合:
 
  
   
    
     D
    
    
     =
    
    
     {
    
    
     
      τ
     
     
      1
     
    
    
     ,
    
    
     
      τ
     
     
      2
     
    
    
     ,
    
    
     .
    
    
     .
    
    
     .
    
    
     ,
    
    
     
      τ
     
     
      
       ∣
      
      
       D
      
      
       ∣
      
     
    
    
     }
    
   
   
    \mathcal{D} =\{\tau_1,\tau_2,...,\tau_{|\mathcal{D}|}\}
   
  
 D={τ1​,τ2​,...,τ∣D∣​}

但是问题是,放到神经网络中,参数该如何更新呢?

策略梯度算法的损失函数

神经网络的结构

如果我们用神经网络来表示策略

     π
    
    
     θ
    
   
  
  
   \pi_\theta
  
 
πθ​,神经网络的输入就是状态

 
  
   
    
     s
    
    
     t
    
   
  
  
   s_t
  
 
st​,输出是每一个动作的概率

 
  
   
    
     π
    
    
     θ
    
   
   
    (
   
   
    
     a
    
    
     t
    
   
   
    ∣
   
   
    
     s
    
    
     t
    
   
   
    )
   
  
  
   \pi_\theta(a_t|s_t)
  
 
πθ​(at​∣st​),

 
  
   
    θ
   
  
  
   \theta
  
 
θ是神经网络中的参数.

这里考虑的是离散动作的情况,如果是连续动作,输出是高斯分布的参数。如果是多维连续动作,那么输出是多维高斯分布的参数。

要想输出是概率,那么最后一层之后我们需要接一个

    s
   
   
    o
   
   
    f
   
   
    t
   
   
    m
   
   
    a
   
   
    x
   
  
  
   softmax
  
 
softmax函数,这样才能保证每一个输出值大于0,且和为1.

 
  
   
    
     s
    
    
     o
    
    
     f
    
    
     t
    
    
     m
    
    
     a
    
    
     x
    
    
     (
    
    
     
      x
     
     
      i
     
    
    
     )
    
    
     =
    
    
     
      
       e
      
      
       
        x
       
       
        i
       
      
     
     
      
       
        ∑
       
       
        
         j
        
        
         =
        
        
         1
        
       
       
        N
       
      
      
       
        e
       
       
        
         x
        
        
         j
        
       
      
     
    
   
   
     softmax(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{N}{e^{x_j}}} 
   
  
 softmax(xi​)=∑j=1N​exj​exi​​

Note:神经网络的参数

     θ
    
   
   
    \theta
   
  
 θ影响的是策略
 
  
   
    
     
      π
     
     
      θ
     
    
   
   
    \pi_\theta
   
  
 πθ​的分布,策略的分布,影响的是智能体在环境中的交互产生的轨迹的分布,轨迹的分布影响的是最终智能体得到的累计回报。

我们希望产生回报大的轨迹出现的概率高,产生回报小的轨迹出现的概率低。如果能够构造一个好的动作评判指标,来判断一个动作的好和不好,那么就可以通过改变动作出现的概率来优化策略。
我们构造损失函数如下:

     L
    
    
     (
    
    
     θ
    
    
     )
    
    
     =
    
    
     −
    
    
     
      ∑
     
     
      
       τ
      
      
       ∼
      
      
       
        π
       
       
        θ
       
      
     
    
    
     
      l
     
     
      o
     
     
      g
     
     
      
       π
      
      
       θ
      
     
     
      (
     
     
      a
     
     
      ∣
     
     
      s
     
     
      )
     
     
      R
     
     
      (
     
     
      τ
     
     
      )
     
    
   
   
     L(\theta) = -\sum_{\tau \sim \pi_\theta}{log\pi_\theta(a|s)R(\tau)} 
   
  
 L(θ)=−τ∼πθ​∑​logπθ​(a∣s)R(τ)

那么在深度学习框架中实现参数更新只需要如下的伪代码:

loss = L(theta)
loss.backward()#梯度反向传播
loss.step()#参数theta更新

上述代码会对loss求梯度,然后通过梯度下降来更新参数。

回顾一下交叉熵:

     H
    
    
     (
    
    
     p
    
    
     ,
    
    
     q
    
    
     )
    
    
     =
    
    
     −
    
    
     
      ∑
     
     
      x
     
    
    
     
      p
     
     
      (
     
     
      x
     
     
      )
     
     
      l
     
     
      o
     
     
      g
     
     
      q
     
     
      (
     
     
      x
     
     
      )
     
    
   
   
     H(p,q) = -\sum_{x}{\mathcal{p}(x)log \mathcal{q}(x)} 
   
  
 H(p,q)=−x∑​p(x)logq(x)

其中p和q是两个概率分布,交叉熵刻画的是两个概率分布之间的距离,两个概率的分布越接近,交叉熵越小
回到我们的话题,我们希望当轨迹累计回报

    R
   
   
    (
   
   
    τ
   
   
    )
   
  
  
   R(\tau)
  
 
R(τ) 越大的时候,对应的动作出现的概率也越大 

 
  
   
    l
   
   
    o
   
   
    g
   
   
    
     π
    
    
     θ
    
   
   
    (
   
   
    
     a
    
    
     t
    
   
   
    ∣
   
   
    
     s
    
    
     t
    
   
   
    )
   
  
  
   log\pi_\theta(a_t|s_t)
  
 
logπθ​(at​∣st​). 反之亦然。 换句话说,我们希望

 
  
   
    R
   
   
    (
   
   
    τ
   
   
    )
   
  
  
   R(\tau)
  
 
R(τ)和

 
  
   
    l
   
   
    o
   
   
    g
   
   
    
     π
    
    
     θ
    
   
   
    (
   
   
    
     a
    
    
     t
    
   
   
    ∣
   
   
    
     s
    
    
     t
    
   
   
    )
   
  
  
   log\pi_\theta(a_t|s_t)
  
 
logπθ​(at​∣st​)的分布越接近越好,用交叉熵损失函数是再合适不过了!

这里还可以继续深入理解: 使用交叉熵损失函数将两者绑定在了一起,其中

     R
    
    
     (
    
    
     τ
    
    
     )
    
   
   
    R(\tau)
   
  
 R(τ)在确定环境中给定策略下是确定的,无法改变的。智能体在和环境交互的过程中,发现轨迹
 
  
   
    
     
      τ
     
     
      i
     
    
   
   
    \tau_i
   
  
 τi​的奖励大一些,于是就通过交叉熵损失函数将对应的动作出现的概率也增大了一些(通过更新参数实现)。于是,智能体再次探索环境的时候,走那些奖励大一些的轨迹的概率更大一些(这就是利用已经学会的知识)。

策略梯度算法的简单实现

声明:以下代码为大概思路,不是完整的代码。完整代码可以参考 【强化学习】spinningup最简单的策略梯度(VPG)代码详细注释——基于pytorch实现
或者这篇:动手强化学习(九):策略梯度算法 代码通俗易懂,适合新手。

定义神经网络
classPolicyNet(torch.nn.Module):def__init__(self, state_dim, hidden_dim, action_dim):super(PolicyNet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim)defforward(self, x):
        x = F.relu(self.fc1(x))return F.softmax(self.fc2(x), dim=1)

神经网络就两层,第一层的输出接一个激活函数,第二层的输出接一个softmax函数,目的是得到输入状态为

     s
    
    
     t
    
   
  
  
   s_t
  
 
st​时,输出动作的概率。
选取动作

神经网络的输出是动作的概率分布,根据这个分布选取当前智能体执行的动作是什么:

deftake_action(self, state):# 根据动作概率分布随机采样
        state = torch.tensor([state], dtype=torch.float).to(self.device)# 输入状态得到动作的概率分布
        probs = self.policy_net(state)# 离散型的动作分布
        action_dist = torch.distributions.Categorical(probs)# 随机采样(概率大的动作采样出现的次数更多)
        action = action_dist.sample()# 返回动作(这里的动作是index,从0开始)return action.item()
采样

接下来就是智能体和环境进行交互采样,得到一个批次的数据。

损失函数

定义损失函数

defcompute_loss(obs, act, weights):# 注意:这里传入的是批次数据(多条轨迹),所以最后求平均值,为平均loss,或者
        logp = get_policy(obs).log_prob(act)# 计算 logp(a|s)return-(logp * weights).mean()# 交叉熵损失函数
参数更新

有了损失函数之后,定义优化器,更新参数:

optimizer = Adam(logits_net.parameters(), lr=lr)# 采样之后,计算梯度,更新网络参数
optimizer.zero_grad()# 这里是计算梯度
batch_loss = compute_loss(obs=torch.as_tensor(batch_obs, dtype=torch.float32),
                                  act=torch.as_tensor(batch_acts, dtype=torch.int32),
                                  weights=torch.as_tensor(batch_weights, dtype=torch.float32)# 梯度反向传播
batch_loss.backward()
optimizer.step()

本文转载自: https://blog.csdn.net/Cser_zhu/article/details/126780417
版权归原作者 sumilkk 所有, 如有侵权,请联系我们删除。

“【强化学习】策略梯度算法中的损失函数”的评论:

还没有评论