当前位置: 首页 > news >正文

app和网站哪个难做wordpress 选项卡插件

app和网站哪个难做,wordpress 选项卡插件,下载微信公众号,企业网站建设公司电话西安本笔记有大量参考蘑菇书EasyRL https://datawhalechina.github.io/easy-rl/#/ 包括其配图和部分文本。 1. 基本概念 1.1 基本流程 强化学习是一种学习框架#xff0c;其中智能体#xff08;Agent#xff09; 通过与 环境#xff08;Environment#xff09; 的交互#… 本笔记有大量参考蘑菇书EasyRL https://datawhalechina.github.io/easy-rl/#/ 包括其配图和部分文本。 1. 基本概念 1.1 基本流程 强化学习是一种学习框架其中智能体Agent 通过与 环境Environment 的交互在每一步从环境中接收状态State和奖励Reward并通过选择行动Action来学习最优策略Policy以最大化其累计奖励。 换句话说强化学习是让智能体找到一种行为策略使得它在长期内获得的奖励总和通常是期望值最大化。 图中的每个元素代表以下含义 Agent智能体这是我们的学习者它会根据当前的状态State做出一个动作Action。Environment环境这是智能体所处的外部世界它会根据智能体的动作给出相应的反馈 Reward奖励智能体执行动作后环境会给出一个数值表示的奖励。正奖励表示动作的好坏负奖励表示动作的坏处。Next State下一个状态执行动作后环境的状态会发生变化进入下一个状态。 State状态环境在某个时刻的具体情况比如游戏中的分数、机器人的位置等。Action动作智能体可以采取的各种行为比如向左走、开火等。 1.2 马尔可夫过程 **马尔科夫性质**一个随机过程的下一个状态只取决于当前状态而与过去的状态无关。即 p ( X t 1 x t 1 ∣ X 0 : t x 0 : t ) p ( X t 1 x t 1 ∣ X t x t ) p(X_{t 1}x_{t 1}|X_{0:t}x_{0:t}) p(X_{t 1}x_{t 1}|X_{t}x_{t}) p(Xt1​xt1​∣X0:t​x0:t​)p(Xt1​xt1​∣Xt​xt​) 马尔可夫性质也可以描述为给定当前状态时将来的状态与过去状态是条件独立的。如果某一个过程满足马尔可夫性质那么未来的转移与过去的是独立的它只取决于现在。马尔可夫性质是所有马尔可夫过程的基础。 也就是说满足以下关系其中 h t { s 1 , s 2 , s 3 , … , s t } h_t \{ s_1, s_2, s_3, \ldots, s_t \} ht​{s1​,s2​,s3​,…,st​} h t h_t ht​包含了之前所有状态 p ( s t 1 ∣ s t ) p ( s t 1 ∣ h t ) p(s_{t 1} | s_{t}) p(s_{t 1} | h_{t}) p(st1​∣st​)p(st1​∣ht​) 从当前 s t s_t st​转移到 s t 1 s_{t1} st1​它是直接就等于它之前所有的状态转移到 s t 1 s_{t1} st1​​。 **马尔可夫链**离散时间的马尔可夫过程。其状态是有限的例如 可以用状态转移矩阵来描述状态转移过程 P [ p ( s 1 ∣ s 1 ) p ( s 2 ∣ s 1 ) ⋯ p ( s N ∣ s 1 ) p ( s 1 ∣ s 2 ) p ( s 2 ∣ s 2 ) ⋯ p ( s N ∣ s 2 ) ⋮ ⋮ ⋱ ⋮ p ( s 1 ∣ s N ) p ( s 2 ∣ s N ) ⋯ p ( s N ∣ s N ) ] P \begin{bmatrix} p(s_1|s_1) p(s_2|s_1) \cdots p(s_N|s_1) \\ p(s_1|s_2) p(s_2|s_2) \cdots p(s_N|s_2) \\ \vdots \vdots \ddots \vdots \\ p(s_1|s_N) p(s_2|s_N) \cdots p(s_N|s_N) \end{bmatrix} P ​p(s1​∣s1​)p(s1​∣s2​)⋮p(s1​∣sN​)​p(s2​∣s1​)p(s2​∣s2​)⋮p(s2​∣sN​)​⋯⋯⋱⋯​p(sN​∣s1​)p(sN​∣s2​)⋮p(sN​∣sN​)​ ​ 状态转移矩阵类似于条件概率conditional probability它表示当我们知道当前我们在状态 s t s_t st​​ 时到达下面所有状态的概率。所以它的每一行描述的是从一个节点到达所有其他节点的概率。 1.3 马尔可夫奖励过程 马尔可夫链加上奖励函数。在马尔可夫奖励过程中状态转移矩阵和状态都与马尔可夫链一样只是多了奖励函数reward function。在强化学习中我们不知要关注过程还要关注在过程中每一步所能获得到的奖励。 这里我们进一步定义一些概念。范围horizon 是指一个回合的长度每个回合最大的时间步数它是由有限个步数决定的。 **回报return**可以定义为奖励的逐步叠加假设时刻 t t t后的奖励序列为 r t 1 , r t 2 , r t 3 , ⋯ r_{t1},r_{t2},r_{t3},⋯ rt1​,rt2​,rt3​,⋯则回报为 回报return G t G_t Gt​可以表示为从时刻t开始直到回合结束获得的所有奖励的折扣总和 G t r t 1 γ r t 2 γ 2 r t 3 . . . γ T − t − 1 r T G_t r_{t1} \gamma r_{t2} \gamma^2 r_{t3} ... \gamma^{T-t-1} r_T Gt​rt1​γrt2​γ2rt3​...γT−t−1rT​ 其中γ∈[0, 1]为折扣因子。随着时间的推移未来的奖励会打折扣表示我们更看重当前的奖励。 当我们有了回报的概念后就可以定义状态价值函数state-value functionV(s)。状态价值函数表示从状态s出发按照当前策略一直执行下去直到回合结束所能获得的期望回报 V π ( s ) E [ G t ∣ S t s ] E [ r t 1 γ r t 2 γ 2 r t 3 ⋯ γ T − t − 1 r T ∣ S t s ] E [ r t 1 ∣ S t s ] γ E [ G t 1 ∣ S t s ] E [ r t 1 ∣ S t s ] γ E [ V π ( S t 1 ) ∣ S t s ] \begin{align} V^{\pi}(s) \mathbb{E}[G_t \mid S_t s] \\ \mathbb{E}[r_{t1} \gamma r_{t2} \gamma^2 r_{t3} \cdots \gamma^{T-t-1}r_T \mid S_t s] \\ \mathbb{E}[r_{t1} \mid S_t s] \gamma \mathbb{E}[G_{t1} \mid S_t s] \\ \mathbb{E}[r_{t1} \mid S_t s] \gamma \mathbb{E}[V^{\pi}(S_{t1}) \mid S_t s] \end{align} Vπ(s)​E[Gt​∣St​s]E[rt1​γrt2​γ2rt3​⋯γT−t−1rT​∣St​s]E[rt1​∣St​s]γE[Gt1​∣St​s]E[rt1​∣St​s]γE[Vπ(St1​)∣St​s]​​ 其中 G t G_t Gt​是之前定义的折扣回报discounted return。 R ( s ) R(s) R(s)是奖励函数我们对 G t G_t Gt​​取了一个期望期望就是从这个状态开始我们可能获得多大的价值。所以期望也可以看成未来可能获得奖励的当前价值的表现就是当我们进入某一个状态后我们现在有多大的价值。 这些话说的有点拗口通俗来说就是 G G G表示当下即时奖励和所有持久奖励等一切奖励的加权和它是相对与一个序列中的一个状态节点来评估的而价值函数 V ( s ) V(s) V(s)是对某一个状态来评估而把这个状态从序列中抽象出来了。 贝尔曼方程 V ( s ) R ( s ) γ ∑ s ′ ∈ S P ( s ′ ∣ s ) V ( s ′ ) V(s) R(s) \gamma \sum_{s \in S} P(s|s) V(s) V(s)R(s)γs′∈S∑​P(s′∣s)V(s′) 一种快速求 V ( s ) V(s) V(s)的方法。 1.4 马尔可夫决策过程 马尔可夫决策过程(MDP) 马尔可夫奖励(MRP) 智能体动作因素 MDP 的目标是找到一个最优策略 π使得智能体在给定状态下选择最优的动作从而最大化长期累积的折扣奖励。 状态价值函数 V π ( s ) E π [ G t ∣ S t s ] E π [ R t 1 γ G t 1 ∣ S t s ] E π [ R t 1 γ V π ( S t 1 ) ∣ S t s ] \begin{align} V_{\pi}(s) \mathbb{E}_{\pi}[G_t | S_t s] \\ \mathbb{E}_{\pi}[R_{t1} \gamma G_{t1} | S_t s] \\ \mathbb{E}_{\pi}[R_{t1} \gamma V_{\pi}(S_{t1}) | S_t s] \end{align} Vπ​(s)​Eπ​[Gt​∣St​s]Eπ​[Rt1​γGt1​∣St​s]Eπ​[Rt1​γVπ​(St1​)∣St​s]​​ 动作价值状态函数 Q π ( s , a ) E π [ G t ∣ S t s , A t a ] E π [ R t 1 γ G t 1 ∣ S t s , A t a ] E π [ R t 1 γ Q π ( S t 1 , A t 1 ) ∣ S t s , A t a ] \begin{align} Q_{\pi}(s, a) \mathbb{E}_{\pi}[G_t | S_t s, A_t a] \\ \mathbb{E}_{\pi}[R_{t1} \gamma G_{t1} | S_t s, A_t a] \\ \mathbb{E}_{\pi}[R_{t1} \gamma Q_{\pi}(S_{t1}, A_{t1}) | S_t s, A_t a] \end{align} Qπ​(s,a)​Eπ​[Gt​∣St​s,At​a]Eπ​[Rt1​γGt1​∣St​s,At​a]Eπ​[Rt1​γQπ​(St1​,At1​)∣St​s,At​a]​​ A t A_t At​表示t时刻的动作 Q Q Q函数相对上面的 V V V函数来说多考虑进去了一个动作的因素而不只是单纯的状态。 马尔可夫决策的贝尔曼方程 V π ( s ) ∑ a ∈ A π ( a ∣ s ) [ R ( s , a ) γ ∑ s ′ ∈ S P ( s ′ ∣ s , a ) V π ( s ′ ) ] V_{\pi}(s) \sum_{a \in A} \pi(a|s) \left[ R(s, a) \gamma \sum_{s \in S} P(s|s, a) V_{\pi}(s) \right] Vπ​(s)a∈A∑​π(a∣s)[R(s,a)γs′∈S∑​P(s′∣s,a)Vπ​(s′)] Q π ( s , a ) R ( s , a ) γ ∑ s ′ ∈ S P ( s ′ ∣ s , a ) [ ∑ a ′ ∈ A π ( a ′ ∣ s ′ ) Q π ( s ′ , a ′ ) ] Q_{\pi}(s, a) R(s, a) \gamma \sum_{s \in S} P(s|s, a) \left[ \sum_{a \in A} \pi(a|s) Q_{\pi}(s, a) \right] Qπ​(s,a)R(s,a)γs′∈S∑​P(s′∣s,a)[a′∈A∑​π(a′∣s′)Qπ​(s′,a′)] 2. REINFORCE 2.1 策略梯度算法 由于REINFORCE是最简单的侧率梯度算法所以这里先介绍策略梯度算法 强化学习有 3 个组成部分演员actor、环境和奖励函数。显然我们能控制的只有演员环境和奖励函数是客观存在的。智能体玩视频游戏时演员负责操控游戏的摇杆 比如向左、向右、开火等操作环境就是游戏的主机负责控制游戏的画面、负责控制怪兽的移动等奖励函数就是当我们做什么事情、发生什么状况的时候可以得到多少分数 比如打败一只怪兽得到 20 分等。在强化学习里环境与奖励函数不是我们可以控制的它们是在开始学习之前给定的。我们唯一需要做的就是调整演员里面的策略使得演员可以得到最大的奖励。演员里面的策略决定了演员的动作即给定一个输入它会输出演员现在应该要执行的动作。 在下面的例子中我们会用一个神经网络来当做演员把环境输入由神经网络给出动作。例如玩一个走格子的游戏游戏规则如下创建一个 n × n n \times n n×n的棋盘旗子在 ( 0 , 0 ) (0, 0) (0,0)处要到达 ( n , n ) (n, n) (n,n)处并用最少的步数走到。也可以为了增加难度在中间设置一点障碍棋子有四种动作分别是“上、下、左、右”。 有四个动作所以神经网络有四个输出根据四个输出的概率进行采样选择下一步的动作。 智能体的每一步动作都会有一个奖励为了让他能尽快走到终点因此它每走到一个格子除非那个格子是终点我们就把那个格子的奖励设置为-1终点的奖励可以设置为10中间也可以设置障碍例如将某个点的奖励设置为-100这样就让模型学会避开这个点。 我们的游戏过程应该是这样的 在一场游戏里面我们把环境输出的 s s s与演员输出的动作 a a a 全部组合起来就是一个轨迹 τ { s 1 , a 1 , s 2 , a 2 , … , s t , a t } \tau \{s_1, a_1, s_2, a_2, \dots, s_t, a_t\} τ{s1​,a1​,s2​,a2​,…,st​,at​} 给定演员的参数 θ θ θ就是提到的神经网络的参数我们可以计算某个轨迹 τ \tau τ发生的概率为 p θ ( τ ) p ( s 1 ) p θ ( a 1 ∣ s 1 ) p ( s 2 ∣ s 1 , a 1 ) p θ ( a 2 ∣ s 2 ) p ( s 3 ∣ s 2 , a 2 ) ⋯ p ( s 1 ) ∏ t 1 T p θ ( a t ∣ s t ) p ( s t 1 ∣ s t , a t ) \begin{align} p_{\theta}(\tau) p(s_1) p_{\theta}(a_1|s_1) p(s_2|s_1, a_1) p_{\theta}(a_2|s_2) p(s_3|s_2, a_2) \cdots \\ p(s_1) \prod_{t1}^{T} p_{\theta}(a_t|s_t) p(s_{t1}|s_t, a_t) \end{align} pθ​(τ)​p(s1​)pθ​(a1​∣s1​)p(s2​∣s1​,a1​)pθ​(a2​∣s2​)p(s3​∣s2​,a2​)⋯p(s1​)t1∏T​pθ​(at​∣st​)p(st1​∣st​,at​)​​ 这个计算是一步一步的并不是并行的。其中 p ( s t 1 ∣ s t , a t ) p(s_{t1} \mid s_t, a_t) p(st1​∣st​,at​)意思是在环境为 s t s_t st​, 演员采取动作 a t a_t at​的情况下环境变成 s t 1 s_{t1} st1​的概率。 那既然每一把游戏都是一个轨迹 τ \tau τ每一把游戏都会有一个得分这个得分按照我之前设定的规则应该是每个动作的回报 G t G_t Gt​然后求和由于整局游戏我已经玩完了所以之后的动作是什么奖励是什么我也知道因此我们能算出这个 G t G_t Gt​。 G t r t 1 γ r t 2 γ 2 r t 3 . . . γ T − t − 1 r T G_t r_{t1} \gamma r_{t2} \gamma^2 r_{t3} ... \gamma^{T-t-1} r_T Gt​rt1​γrt2​γ2rt3​...γT−t−1rT​ 我们把这局游戏每一步走完之后的 G t G_t Gt​都存下来如果这个 G t G_t Gt​大于零就说明这个动作有好处可以增大采样采到这个动作的概率注意增加的是 p θ ( a t ∣ s t ) p_{\theta}(a_t|s_t) pθ​(at​∣st​)的概率而不是 p θ ( a t ) p_{\theta}(a_t) pθ​(at​)的值需要联系环境来考虑问题。就跟人斗地主一样你是农民你的队友手里只剩下两张王了这个时候最好的决策就是将自己手里的炸弹打出来增加奖励。你出炸弹的概率就几乎是百分之百 p ( 出炸弹 ∣ 队友手里只剩下两张王了 ) 0.99 p(出炸弹 \mid 队友手里只剩下两张王了) 0.99 p(出炸弹∣队友手里只剩下两张王了)0.99而在别的情况下你出炸弹的概率就没必要这么高毕竟很少有人开局就出炸弹。所以模型要提高的是 p ( 出炸弹 ∣ 队友手里只剩下两张王了 ) p(出炸弹 \mid 队友手里只剩下两张王了) p(出炸弹∣队友手里只剩下两张王了)的值而不是 p ( 出炸弹 ) p(出炸弹) p(出炸弹)。这个 G t G_t Gt​暂时不会用到后面会用到。 在强化学习里面除了环境与演员以外还有奖励函数。如下图所示奖励函数根据在某一个状态采取的某一个动作决定这个动作可以得到的分数。对奖励函数输入 s 1 , a 1 s_1, a_1 s1​,a1​它会输出 r 1 r_1 r1​输入 s 2 , a 2 s_2, a_2 s2​,a2​它会输出 r 2 r_2 r2​。 我们把轨迹所有的奖励 r r r都加起来就得到了 R ( τ ) R(\tau) R(τ)其代表某一个轨迹 τ \tau τ的奖励。 那一把游戏能不能衡量一个演员智能体的能力呢可能不行因为你有可能是蒙的那我们如何评价一个演员的能力呢多玩几次求期望 R ˉ θ ∑ τ R ( τ ) p θ ( τ ) \bar{R}_{\theta} \sum_{\tau} R(\tau) p_{\theta}(\tau) Rˉθ​τ∑​R(τ)pθ​(τ) 那么这个 R ˉ θ \bar{R}_{\theta} Rˉθ​就是我们要优化的目标了。也可以表达成这样 R ˉ θ ∑ τ R ( τ ) p θ ( τ ) E τ ∼ p θ ( τ ) [ R ( τ ) ] \bar{R}_{\theta} \sum_{\tau} R(\tau) p_{\theta}(\tau) \mathbb{E}_{\tau \sim p_{\theta}(\tau)}[R(\tau)] Rˉθ​τ∑​R(τ)pθ​(τ)Eτ∼pθ​(τ)​[R(τ)] 因为我们要让奖励越大越好所以可以使用梯度上升gradient ascent来最大化期望奖励。要进行梯度上升我们先要计算期望奖励 R ˉ θ \bar{R}_{\theta} Rˉθ​的梯度。我们对 R ˉ θ \bar{R}_{\theta} Rˉθ​做梯度运算。 R ˉ θ ∑ τ R ( τ ) p θ ( τ ) \bar{R}_{\theta} \sum_{\tau} R(\tau) p_{\theta}(\tau) Rˉθ​τ∑​R(τ)pθ​(τ) 对 θ \theta θ求偏导 ∇ R ˉ θ ∑ τ R ( τ ) ∇ p θ ( τ ) \nabla \bar{R}_{\theta} \sum_{\tau} R(\tau) \nabla p_{\theta}(\tau) ∇Rˉθ​τ∑​R(τ)∇pθ​(τ) 由于 ∇ l o g a ( f ( x ) ) ∇ f ( x ) f ( x ) l n a \nabla log_a(f(x)) \frac{\nabla f(x)}{f(x)lna} ∇loga​(f(x))f(x)lna∇f(x)​ l n a lna lna是常数可以忽略直接将底数看做是e更好理解下面的公式 ∇ p θ ( τ ) p θ ( τ ) ∇ log ⁡ p θ ( τ ) ∇ p θ ( τ ) p θ ( τ ) ∇ log ⁡ p θ ( τ ) \nabla p_{\theta}(\tau) p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) \\ \\ \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \nabla \log p_{\theta}(\tau) ∇pθ​(τ)pθ​(τ)∇logpθ​(τ)pθ​(τ)∇pθ​(τ)​∇logpθ​(τ) 带入 ∇ R ˉ θ \nabla \bar{R}_{\theta} ∇Rˉθ​得 ∇ R ˉ θ ∑ τ R ( τ ) ∇ p θ ( τ ) ∑ τ R ( τ ) p θ ( τ ) ∇ p θ ( τ ) p θ ( τ ) ∑ τ R ( τ ) p θ ( τ ) ∇ log ⁡ p θ ( τ ) E τ ∼ p θ ( τ ) [ R ( τ ) ∇ log ⁡ p θ ( τ ) ] \begin{align} \nabla \bar{R}_{\theta} \sum_{\tau} R(\tau) \nabla p_{\theta}(\tau) \\ \sum_{\tau} R(\tau) p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \\ \sum_{\tau} R(\tau) p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) \\ \mathbb{E}_{\tau \sim p_{\theta}(\tau)} \left[ R(\tau) \nabla \log p_{\theta}(\tau) \right] \end{align} ∇Rˉθ​​τ∑​R(τ)∇pθ​(τ)τ∑​R(τ)pθ​(τ)pθ​(τ)∇pθ​(τ)​τ∑​R(τ)pθ​(τ)∇logpθ​(τ)Eτ∼pθ​(τ)​[R(τ)∇logpθ​(τ)]​​ 由于轨迹是采不完的因此 E τ ∼ p θ ( τ ) \mathbb{E}_{\tau \sim p_{\theta}(\tau)} Eτ∼pθ​(τ)​无法计算我们只能以部分估计总体这也是统计学的精髓多采几次样这里假设采样 N N N个 τ \tau τ并计算每一个 τ \tau τ的 [ R ( τ ) ∇ log ⁡ p θ ( τ ) ] \left[ R(\tau) \nabla \log p_{\theta}(\tau) \right] [R(τ)∇logpθ​(τ)]值再将其求和取平均用来近似 E τ ∼ p θ ( τ ) \mathbb{E}_{\tau \sim p_{\theta}(\tau)} Eτ∼pθ​(τ)​。 那如何处理 log ⁡ p θ ( τ ) \log p_{\theta}(\tau) logpθ​(τ)呢 ∇ log ⁡ p θ ( τ ) ∇ ( log ⁡ p ( s 1 ) ∑ t 1 T log ⁡ p θ ( a t ∣ s t ) ∑ t 1 T log ⁡ p ( s t 1 ∣ s t , a t ) ) ∇ log ⁡ p ( s 1 ) ∇ ∑ t 1 T log ⁡ p θ ( a t ∣ s t ) ∇ ∑ t 1 T log ⁡ p ( s t 1 ∣ s t , a t ) ∑ t 1 T ∇ log ⁡ p θ ( a t ∣ s t ) ∑ t 1 T ∇ log ⁡ p θ ( a t ∣ s t ) \begin{aligned} \nabla \log p_{\theta}(\tau) \nabla \left( \log p(s_1) \sum_{t1}^T \log p_{\theta}(a_t|s_t) \sum_{t1}^T \log p(s_{t1}|s_t, a_t) \right) \\ \nabla \log p(s_1) \nabla \sum_{t1}^T \log p_{\theta}(a_t|s_t) \nabla \sum_{t1}^T \log p(s_{t1}|s_t, a_t) \\ \sum_{t1}^T \nabla \log p_{\theta}(a_t|s_t) \\ \sum_{t1}^T \nabla \log p_{\theta}(a_t|s_t) \end{aligned} ∇logpθ​(τ)​∇(logp(s1​)t1∑T​logpθ​(at​∣st​)t1∑T​logp(st1​∣st​,at​))∇logp(s1​)∇t1∑T​logpθ​(at​∣st​)∇t1∑T​logp(st1​∣st​,at​)t1∑T​∇logpθ​(at​∣st​)t1∑T​∇logpθ​(at​∣st​)​ 第二部中有一些与 θ \theta θ无关的项直接被求偏导变成零了。因为 p p p表示的是根据动作和前面的场景生成的场景为 s t 1 s_{t1} st1​的概率与演员无关。 由上式和之前分析的由部分代替总体的思想一起带入 ∇ R ˉ θ \nabla \bar{R}_{\theta} ∇Rˉθ​可得 E τ ∼ p θ ( τ ) [ R ( τ ) ∇ log ⁡ p θ ( τ ) ] ≈ 1 N ∑ n 1 N R ( τ n ) ∇ log ⁡ p θ ( τ n ) 1 N ∑ n 1 N ∑ t 1 T n R ( τ n ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \begin{aligned} \mathbb{E}_{\tau \sim p_{\theta}(\tau)}[R(\tau) \nabla \log p_{\theta}(\tau)] \approx \frac{1}{N} \sum_{n1}^{N} R(\tau^n) \nabla \log p_{\theta}(\tau^n) \\ \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} R(\tau^n) \nabla \log p_{\theta}(a_t^n|s_t^n) \end{aligned} Eτ∼pθ​(τ)​[R(τ)∇logpθ​(τ)]​≈N1​n1∑N​R(τn)∇logpθ​(τn)N1​n1∑N​t1∑Tn​​R(τn)∇logpθ​(atn​∣stn​)​ 那我们就可以将 ∇ R ˉ θ \nabla \bar{R}_{\theta} ∇Rˉθ​当做损失函数 ∇ R ˉ θ 1 N ∑ n 1 N ∑ t 1 T n R ( τ n ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} R(\tau^n) \nabla \log p_{\theta}(a_t^n|s_t^n) ∇Rˉθ​N1​n1∑N​t1∑Tn​​R(τn)∇logpθ​(atn​∣stn​) 既然有了损失函数那就可以直接套用深度学习神经网络那一套东西更新参数 θ ← θ η ∇ R ˉ θ \theta \leftarrow \theta \eta \nabla \bar{R}_{\theta} θ←θη∇Rˉθ​ 那么网络的训练步骤就非常的简单 采集数据 —— 更新参数——采集数据——…… 值得注意的是采集到的数据只会用一次就丢掉这显然是一个可以优化的点之后在PPO算法中会对其进行优化。 2.2 策略梯度算法的一些实现技巧 2.2.1 基线 如果奖励一直是正的 ∇ R ˉ θ \nabla \bar{R}_{\theta} ∇Rˉθ​就会一直是正的那概率就只会增加不会减少什么意思呢 如图所示: 在某一个状态有 3 个动作 a、b、c可以执行b的奖励最大c的奖励最小。但是如果采样没有采到a只采到了b、c那么b、c的概率就会增大因为奖励是正的因为a、b、c的概率和是1b、c概率增大了a的概率就会减小这显然是不科学的。 因此我们可以引入一个基线就是把奖励统一减去 b b b让奖励有正有负即 ∇ R ˉ θ ≈ 1 N ∑ n 1 N ∑ t 1 T n ( R ( τ n ) − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} (R(\tau^n) - b) \nabla \log p_{\theta}(a_t^n|s_t^n) ∇Rˉθ​≈N1​n1∑N​t1∑Tn​​(R(τn)−b)∇logpθ​(atn​∣stn​) 2.2.2 分配合适的分数 观察损失函数 ∇ R ˉ θ ≈ 1 N ∑ n 1 N ∑ t 1 T n ( R ( τ n ) − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} (R(\tau^n) - b) \nabla \log p_{\theta}(a_t^n|s_t^n) ∇Rˉθ​≈N1​n1∑N​t1∑Tn​​(R(τn)−b)∇logpθ​(atn​∣stn​) 在同一场游戏里面在同一场游戏里面所有的状态-动作对就使用同样的奖励项进行加权。 这显然是不公平的例如 假设游戏都很短只有 3 ~ 4 个交互在 s a s_a sa​ 执行 a 1 a_1 a1​得到 5 分在 s b s_b sb​执行 a 2 a_2 a2​得到 0 分在 s c s_c sc​执行 a 3 a_3 a3​得到 −2 分。 整场游戏下来我们得到 3 分那我们得到 3 分 代表在 s b s_b sb​执行 a 2 a_2 a2​ 是好的吗 这并不一定代表在 s b s_b sb​执行 a 2 a_2 a2​是好的。因为这个正的分数主要来自在 s a s_a sa​执行了 a 1 a_1 a1​与在 s b s_b sb​执行 a 2 a_2 a2​是没有关系的也许在 s b s_b sb​执行 a 2 a_2 a2​反而是不好的 因为它导致我们接下来会进入 s c s_c sc​执行 a 3 a_3 a3​​被扣分。所以整场游戏得到的结果是好的 并不代表每一个动作都是好的。 理想情况下这种情况不会发生只要采样足够多多次遇到 ( s a , a 1 ) (s_a, a_1) (sa​,a1​)​的情况我们就能通过梯度更新来合理评估它的概率但是问题是采样成本很高采样那么多次不太现实因此我们可以为每个状态-动作对分配合理的分数要让大家知道它合理的贡献。 我们之前谈到过 G t G_t Gt​ G t r t 1 γ r t 2 γ 2 r t 3 . . . γ T − t − 1 r T G_t r_{t1} \gamma r_{t2} \gamma^2 r_{t3} ... \gamma^{T-t-1} r_T Gt​rt1​γrt2​γ2rt3​...γT−t−1rT​ 它就能很好的反应每个状态的价值即 ∇ R ˉ θ ≈ 1 N ∑ n 1 N ∑ t 1 T n ( ∑ t ′ t T n γ t ′ − t r t ′ n − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) 1 N ∑ n 1 N ∑ t 1 T n ( G t − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \begin{align} \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} \left( \sum_{tt}^{T_n} \gamma^{t-t} r_{t}^n - b \right) \nabla \log p_{\theta}(a_t^n|s_t^n) \\ \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} \left( G_t - b \right) \nabla \log p_{\theta}(a_t^n|s_t^n) \end{align} ∇Rˉθ​​≈N1​n1∑N​t1∑Tn​​(t′t∑Tn​​γt′−trt′n​−b)∇logpθ​(atn​∣stn​)N1​n1∑N​t1∑Tn​​(Gt​−b)∇logpθ​(atn​∣stn​)​​ 说明 事实上 b b b通常是一个网络估计出来的它是一个网络的输出。我们把 R − b R-b R−b这一项称为优势函数advantage function 用 A θ ( s t , a t ) A^{\theta}(s_t, a_t) Aθ(st​,at​)来代表优势函数。优势函数取决于 s s s和 a a a我们就是要计算在某个状态 s s s采取某个动作 a a a的时候优势函数的值。在计算优势函数值时我们要计算 ∑ t ′ t T n r t ′ n \sum_{tt}^{T_n} r_{t}^n ∑t′tTn​​rt′n​需要有一个模型与环境交互才能知道接下来得到的奖励。优势函数 A θ ( s t , a t ) A^{\theta}(s_t, a_t) Aθ(st​,at​)的上标是 θ \theta θ θ \theta θ 代表用模型 θ \theta θ与环境交互。从时刻 t t t开始到游戏结束为止所有 r r r的加和减去 b b b这就是优势函数。优势函数的意义是假设我们在某一个状态 s t s_t st​执行某一个动作 a t a_t at​相较于其他可能的动作 a t a_t at​有多好。优势函数在意的不是绝对的好而是相对的好即相对优势relative advantage。因为在优势函数中我们会减去一个基线 b b b所以这个动作是相对的好不是绝对的好。 A θ ( s t , a t ) A^{\theta}(s_t, a_t) Aθ(st​,at​)​通常可以由一个网络估计出来这个网络称为评论员critic。 2.3 REINFORCE算法实现 由于在游戏中我的策略是每个格子如果不是终点奖励分数就是-1因此无需使用基线但是代码中使用了“分配合适分数”方法所有函数作用代码中有详细注释因此不再赘述。 import numpy as np import torch import torch.nn as nn import torch.optim as optim import matplotlib.pyplot as plt# 环境定义 class GridWorldEnv:def __init__(self, size5):# 初始化网格世界环境self.size size # 网格的大小self.state (0, 0) # 初始状态self.goal (size - 1, size - 1) # 目标状态self.actions [up, down, left, right] # 可用的动作self.action_space len(self.actions) # 动作空间的大小def reset(self):# 重置环境到初始状态self.state (0, 0)return self.statedef step(self, action):# 根据动作更新状态并返回新的状态、奖励和是否完成x, y self.stateif action 0: # 向上x max(0, x - 1)elif action 1: # 向下x min(self.size - 1, x 1)elif action 2: # 向左y max(0, y - 1)elif action 3: # 向右y min(self.size - 1, y 1)self.state (x, y)reward -1 # 默认奖励if x 2 and y ! 2:reward -10done self.state self.goal # 检查是否到达目标if done:reward 10 # 到达目标的奖励return self.state, reward, donedef render(self):# 渲染当前状态的网格世界grid np.zeros((self.size, self.size)) # 创建一个全零的网格x, y self.stategrid[x, y] 1 # 将当前状态的位置设为1print(grid)# 策略网络 class PolicyNetwork(nn.Module):def __init__(self, input_dim, output_dim):# 初始化策略网络super(PolicyNetwork, self).__init__()self.fc1 nn.Linear(input_dim, 24) # 第一层全连接层self.fc2 nn.Linear(24, 128) # 第二层全连接层self.fc3 nn.Linear(128, output_dim) # 第三层全连接层self.relu nn.ReLU() # ReLU激活函数self.softmax nn.Softmax(dim-1) # Softmax输出层def forward(self, x):# 前向传播x self.relu(self.fc1(x)) # 第一层激活x self.relu(self.fc2(x)) # 第二层激活x self.softmax(self.relu(self.fc3(x))) # 第三层激活return x# REINFORCE算法 class REINFORCE:def __init__(self, state_space, action_space, learning_rate0.01, gamma0.99):# 初始化REINFORCE算法self.policy_network PolicyNetwork(state_space, action_space) # 策略网络self.optimizer optim.Adam(self.policy_network.parameters(), lrlearning_rate) # Adam优化器self.gamma gamma # 折扣因子def choose_action(self, state):# 根据状态选择动作state torch.tensor(state, dtypetorch.float32).unsqueeze(0) # 将状态转换为张量action_probs self.policy_network(state).detach().numpy()[0] # 获取动作概率action np.random.choice(len(action_probs), paction_probs) # 根据概率选择动作return actiondef compute_discounted_rewards(self, rewards):# 计算折扣奖励discounted_rewards np.zeros_like(rewards, dtypenp.float32) # 初始化折扣奖励cumulative 0for i in reversed(range(len(rewards))):cumulative cumulative * self.gamma rewards[i] # 计算累计折扣奖励discounted_rewards[i] cumulativereturn discounted_rewardsdef train(self, states, actions, rewards):# 训练策略网络discounted_rewards self.compute_discounted_rewards(rewards) # 计算折扣奖励# 归一化奖励discounted_rewards (discounted_rewards - np.mean(discounted_rewards)) / (np.std(discounted_rewards) 1e-8)discounted_rewards torch.tensor(discounted_rewards, dtypetorch.float32)states torch.tensor(states, dtypetorch.float32) # 将状态转换为张量actions torch.tensor(actions, dtypetorch.long) # 将动作转换为张量# 计算损失log_probs torch.log(self.policy_network(states)) # 计算对数概率selected_log_probs log_probs[range(len(actions)), actions] # 选择执行动作的对数概率loss -torch.mean(selected_log_probs * discounted_rewards) # 计算损失# 优化网络self.optimizer.zero_grad() # 清零梯度loss.backward() # 反向传播self.optimizer.step() # 更新参数# 主程序 def main():env GridWorldEnv(size5) # 创建网格世界环境agent REINFORCE(state_space10, action_space4, learning_rate0.01) # 创建REINFORCE智能体episodes 1000 # 训练回合数reward_history [] # 奖励历史state env.reset() # 重置环境env.render() # 渲染初始状态for episode in range(episodes):state env.reset() # 重置环境states, actions, rewards [], [], [] # 初始化状态、动作和奖励列表done Falsewhile not done:# 状态转换为独热向量state_onehot np.eye(env.size)[state[0]].tolist() np.eye(env.size)[state[1]].tolist()action agent.choose_action(state_onehot) # 选择动作next_state, reward, done env.step(action) # 执行动作states.append(state_onehot) # 记录状态actions.append(action) # 记录动作rewards.append(reward) # 记录奖励state next_state # 更新状态agent.train(states, actions, rewards) # 训练智能体reward_history.append(sum(rewards)) # 记录总奖励if episode % 100 0:print(fEpisode {episode}, Total Reward: {sum(rewards)}) # 每100回合打印一次总奖励# 绘制奖励曲线plt.plot(reward_history)plt.xlabel(Episodes)plt.ylabel(Total Reward)plt.show()if __name__ __main__:main()3. A2C算法 3.1 策略梯度的一些缺陷 策略梯度算法在理想情况下在采样次数足够多的情况下效果是能很不错的但是当采样不够时就会出现一些问题例如 G t G_t Gt​的取值是很不稳定的下图可以形象说明 由于 G t G_t Gt​的取值不稳定所以 ( s t , a t ) (s_t, a_t) (st​,at​)更新也不稳定。 3.2 DQN中的一些概念 由于 G G G的值有点太不稳定太玄学了因此我们可以想办法去用一个神经网络去预测在 s s s状态下采取行动 a a a时对应的 G G G期望值之后再训练中我们就直接用这个期望值去替代采样的值。为了完成这个目的我们可以使用基于价值的方法深度Q网络深度Q网络有两种函数也就是两种评论员他们分别是 V π ( s ) V_{\pi}(s) Vπ​(s)和 Q π ( s , a ) Q_{\pi}(s,a) Qπ​(s,a) V π ( s ) V_{\pi}(s) Vπ​(s)是指假设演员的策略是 π {\pi} π使用 π {\pi} π与环境交互当智能体看到状态 s s s时接下来累积奖励的期望值是多少。 Q π ( s , a ) Q_{\pi}(s,a) Qπ​(s,a)是指把 s s s与 a a a当作输入它表示在状态 s s s采取动作 a a a接下来用策略 π {\pi} π与环境交互累积奖励的期望值是多少。 V π ( s ) V_{\pi}(s) Vπ​(s)接收输入 s s s输出一个标量。 Q π ( s , a ) Q_{\pi}(s,a) Qπ​(s,a)接收输入 s s s它会给每一个 s s s都分配一个 Q Q Q值。 有了这两个函数我们可以用这两个函数去替换原来的梯度公式 又出现一个问题神经网络本来就不稳定现在还要估计两个神经网络Q网络和V网络那岂不是更不稳定估不准的概率岂不是就翻倍了那就得想点办法只估计一个网络事实上在演员-评论员算法中我们可以只估计网络 V并利用 V V V的值来表示 Q Q Q的值 Q π ( s t n , a t n ) Q_{\pi}(s_t^n, a_t^n) Qπ​(stn​,atn​)可以写成$ r_t^n V_{\pi}(s_{t1}^n) $的期望值即 Q π ( s t n , a t n ) E [ r t n V π ( s t 1 n ) ] Q_{\pi}(s_t^n, a_t^n) \mathbb{E} \left[ r_t^n V_{\pi}(s_{t1}^n) \right] Qπ​(stn​,atn​)E[rtn​Vπ​(st1n​)] 在状态 s s s采取动作 a a a我们会得到奖励 r r r进入状态 s t 1 s_{t1} st1​。但是我们会得到什么样的奖励 r r r进入什么样的状态 s t 1 s_{t1} st1​这件事本身是有随机性的。所以要把$ r_t^n V_{\pi}(s_{t1}^n) $​取期望值才会等于Q函数的值。但我们现在把取期望值去掉即: Q π ( s t n , a t n ) r t n V π ( s t 1 n ) Q_{\pi}(s_t^n, a_t^n) r_t^n V_{\pi}(s_{t1}^n) Qπ​(stn​,atn​)rtn​Vπ​(st1n​) 即Q函数与V函数的差值可以变成 r t n V π ( s t 1 n ) − V π ( s t n ) r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) rtn​Vπ​(st1n​)−Vπ​(stn​)​ 至于究竟为什么可以去掉期望值也没有什么很强有力的数学解释只是研究人员发现这么做效果不错其他方法效果没这个好大家伙就都用这个方法了都直接把期望去掉了。 推了半天得到一个 r t n V π ( s t 1 n ) − V π ( s t n ) r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) rtn​Vπ​(st1n​)−Vπ​(stn​)这个公式就是时序差分误差TD-error它代替了我们之前提到的优势函数就是替代了 A θ ( s t , a t ) A^{\theta}(s_t, a_t) Aθ(st​,at​)。 那么 ∇ R ˉ θ \nabla \bar{R}_{\theta} ∇Rˉθ​就变成了 ∇ R ˉ θ ≈ 1 N ∑ n 1 N ∑ t 1 T n ( r t n V π ( s t 1 n ) − V π ( s t n ) ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} (r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n)) \nabla \log p_{\theta}(a_t^n | s_t^n) ∇Rˉθ​≈N1​n1∑N​t1∑Tn​​(rtn​Vπ​(st1n​)−Vπ​(stn​))∇logpθ​(atn​∣stn​) 算法流程 3.3 Actor网络和Critic网络的损失函数 讲了这么多那么我们要训练两个网络Actor网络和Critic网络既然是训练这两个模型就需要损失函数两个模型就需要两个损失函数那他们分别是什么呢 Actor网络的损失函数如下 L a c t o r − 1 N ∑ n 1 N ∑ t 1 T n ( δ t n ⋅ log ⁡ π θ ( a t n ∣ s t n ) ) L_{actor} -\frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} (\delta_t^n \cdot \log \pi_{\theta}(a_t^n | s_t^n)) Lactor​−N1​n1∑N​t1∑Tn​​(δtn​⋅logπθ​(atn​∣stn​)) ∙ δ t n r t n V π ( s t 1 n ) − V π ( s t n ) 时序差分误差 (TD-error)。 ∙ log ⁡ π θ ( a t n ∣ s t n ) 策略的对数概率表示 Actor 在状态  s t n 下选择动作  a t n 的对数概率。 ∙ N 是采样的轨迹数量。 ∙ T n 轨迹  n 的时间步数。 \begin{align*} \bullet \delta_t^n r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) \text{时序差分误差 (TD-error)。} \\ \bullet \log \pi_{\theta}(a_t^n|s_t^n) \text{策略的对数概率表示 Actor 在状态 } s_t^n \text{ 下选择动作 } a_t^n \text{ 的对数概率。} \\ \bullet N \text{是采样的轨迹数量。} \\ \bullet T_n \text{轨迹 } n \text{ 的时间步数。} \end{align*} ​∙δtn​rtn​Vπ​(st1n​)−Vπ​(stn​)时序差分误差 (TD-error)。∙logπθ​(atn​∣stn​)策略的对数概率表示 Actor 在状态 stn​ 下选择动作 atn​ 的对数概率。∙N是采样的轨迹数量。∙Tn​轨迹 n 的时间步数。​ Critic网络损失函数如下 L c r i t i c 1 N ∑ n 1 N ∑ t 1 T n ( δ t n ) 2 L_{critic} \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} \left( \delta_t^n\right)^2 Lcritic​N1​n1∑N​t1∑Tn​​(δtn​)2 δ t n r t n V π ( s t 1 n ) − V π ( s t n ) 时序差分误差 (TD-error)。 ∙ N 是采样的轨迹数量。 ∙ T n 轨迹  n 的时间步数。 \begin{align*} \delta_t^n r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) \text{时序差分误差 (TD-error)。} \\ \bullet N \text{是采样的轨迹数量。} \\ \bullet T_n \text{轨迹 } n \text{ 的时间步数。} \end{align*} ​δtn​rtn​Vπ​(st1n​)−Vπ​(stn​)时序差分误差 (TD-error)。∙N是采样的轨迹数量。∙Tn​轨迹 n 的时间步数。​ 有了损失函数又改如何求梯度算参数呢 首先需要明白有两个网络Actor网络和Critic网络他们在上述公式中的体现是什么时序差分误差 δ t n r t n V π ( s t 1 n ) − V π ( s t n ) \delta_t^n r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) δtn​rtn​Vπ​(st1n​)−Vπ​(stn​)既然是误差涉及到评估工作因此V网络就是Critic网络其网络参数并未在公式中标注可以将其标注为 ϕ {\phi} ϕ。至于Actor网络公式中已经标明过了 π θ {\pi}_{\theta} πθ​表示 π \pi π这个策略网络的参数就是 θ \theta θ因此求梯度也就很轻松。 Actor网络的梯度公式如下 ∇ θ L a c t o r − 1 N ∑ n 1 N ∑ t 1 T n δ t n ⋅ log ⁡ π θ ( a t n ∣ s t n ) , \nabla_{\theta} L_{actor} -\frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} \delta_t^n \cdot \log \pi_{\theta}(a_t^n|s_t^n), ∇θ​Lactor​−N1​n1∑N​t1∑Tn​​δtn​⋅logπθ​(atn​∣stn​), ∙ δ t n r t n V π ( s t 1 n ) − V π ( s t n ) TD-error。 ∙ ∇ θ log ⁡ π θ ( a t n ∣ s t n ) 策略关于参数 θ 的梯度。 \begin{align*} \bullet \delta_t^n r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) \text{TD-error。} \\ \bullet \nabla_{\theta} \log \pi_{\theta}(a_t^n|s_t^n) \text{策略关于参数}\theta\text{的梯度。} \end{align*} ​∙δtn​rtn​Vπ​(st1n​)−Vπ​(stn​)TD-error。∙∇θ​logπθ​(atn​∣stn​)策略关于参数θ的梯度。​ Critic网络的梯度公式如下 ∇ ϕ L c r i t i c 1 N ∑ n 1 N ∑ t 1 T n 2 ⋅ δ t n ⋅ ∇ ϕ V π ( s t n ; ϕ ) \nabla_{\phi} L_{critic} \frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} 2 \cdot \delta_t^n \cdot \nabla_{\phi} V_{\pi}(s_t^n; \phi) ∇ϕ​Lcritic​N1​n1∑N​t1∑Tn​​2⋅δtn​⋅∇ϕ​Vπ​(stn​;ϕ) ∙ δ t n r t n V π ( s t 1 n ) − V π ( s t n ) TD-error。 ∙ ∇ ϕ V π ( s t n ; ϕ ) 价值函数关于参数 ϕ 的梯度。 \begin{align*} \bullet \delta_t^n r_t^n V_{\pi}(s_{t1}^n) - V_{\pi}(s_t^n) \text{TD-error。} \\ \bullet \ \nabla_{\phi} V_{\pi}(s_t^n; \phi) \text{价值函数关于参数}\phi\text{的梯度。} \\ \end{align*} ​∙δtn​rtn​Vπ​(st1n​)−Vπ​(stn​)TD-error。∙ ∇ϕ​Vπ​(stn​;ϕ)价值函数关于参数ϕ的梯度。​ 3.4 A2C算法实现 实现优势演员-评论员算法的时候有两个一定会用到的技巧。 第一个技巧是我们需要估计两个网络 V V V网络和策略的网络也就是演员。评论员网络 V π ( s ) V_{\pi}(s) Vπ​(s)接收一个状态输出一个标量。演员的策略 π ( s ) {\pi(s)} π(s)​接收一个状态如果动作是离散的输出就是一个动作的分布。如果动作是连续的输出就是一个连续的向量。 离散动作的例子如下连续动作的情况也是一样的。输入一个状态网络决定现在要采取哪一个动作。演员网络和评论员网络的输入都是 s s s​所以它们前面几个层layer是可以共享的。 第二个技巧是我们需要探索的机制。在演员-评论员算法中有一个常见的探索的方法是对 π {\pi} π​输出的分布设置一个约束。这个约束用于使分布的熵entropy不要太小也就是希望不同的动作被采用的概率平均一些。这样在测试的时候智能体才会多尝试各种不同的动作才会把环境探索得比较好从而得到比较好的结果。 这里运用了两个技巧第二个技巧在Actor网络的损失函数上加了个正则项因此Actor损失函数变成了这样 L a c t o r − 1 N ∑ n 1 N ∑ t 1 T n ( δ t n ⋅ log ⁡ π θ ( a t n ∣ s t n ) ) − λ H ( π θ ) L_{actor} -\frac{1}{N} \sum_{n1}^{N} \sum_{t1}^{T_n} (\delta_t^n \cdot \log \pi_{\theta}(a_t^n|s_t^n)) - \lambda H(\pi_{\theta}) Lactor​−N1​n1∑N​t1∑Tn​​(δtn​⋅logπθ​(atn​∣stn​))−λH(πθ​) ∙ H ( π θ ) 策略的熵。 ∙ λ 控制探索的权重。 \begin{align*} \bullet \ H(\pi_{\theta}) \text{策略的熵。} \\ \bullet \ \lambda \text{控制探索的权重。} \end{align*} ​∙ H(πθ​)策略的熵。∙ λ控制探索的权重。​ 代码中主要是以玩一个CartPole的游戏举例来实现的游戏的具体玩法可以去网上搜到大概就是一个平衡杆左右移动让杆子不倒的游戏。 import gym import torch import torch.nn as nn import torch.optim as optim import numpy as np import matplotlib.pyplot as plt # 配置类集中管理所有超参数 class Config:def __init__(self):# 神经网络结构参数self.hidden_dim 128 # 共享网络隐藏层维度self.actor_hidden_dim 64 # Actor网络隐藏层维度self.critic_hidden_dim 64 # Critic网络隐藏层维度# 算法训练参数self.lr 0.001 # 学习率self.gamma 0.99 # 折扣因子用于计算未来奖励的现值self.entropy_coef 0.01 # 熵系数用于鼓励探索self.value_loss_coef 0.5 # 价值损失系数平衡actor和critic损失# 训练过程参数self.max_episodes 5000 # 最大训练回合数self.max_steps 500 # 每个回合的最大步数# 其他设置self.seed 42 # 随机种子确保实验可重复性self.device torch.device(cuda if torch.cuda.is_available() else cpu) # 设备选择self.rewards_history [] # 用于存储每个episode的reward# Actor-Critic网络结构 class ActorCritic(nn.Module):def __init__(self, state_dim, action_dim, config):super(ActorCritic, self).__init__()# 共享特征提取层self.common nn.Sequential(nn.Linear(state_dim, config.hidden_dim), # 状态到特征的映射nn.ReLU() # 非线性激活函数)# Actor网络决策策略self.actor nn.Sequential(nn.Linear(config.hidden_dim, action_dim), # 特征到动作概率的映射nn.Softmax(dim-1) # 输出动作概率分布)# Critic网络状态价值评估self.critic nn.Sequential(nn.Linear(config.hidden_dim, 1) # 特征到状态价值的映射)def forward(self, state):common_out self.common(state) # 提取共享特征policy self.actor(common_out) # 计算动作概率value self.critic(common_out) # 估计状态价值return policy, value# A2C算法实现 class A2C:def __init__(self, state_dim, action_dim, config):self.config configself.model ActorCritic(state_dim, action_dim, config) # 创建神经网络self.optimizer optim.Adam(self.model.parameters(), lrconfig.lr) # Adam优化器self.gamma config.gamma # 折扣因子def compute_loss(self, states, actions, rewards, dones, next_states):# 数据预处理转换为PyTorch张量states torch.FloatTensor(states)next_states torch.FloatTensor(next_states)actions torch.LongTensor(actions)rewards torch.FloatTensor(rewards)dones torch.FloatTensor(dones)# 获取当前状态的策略和价值估计policy, values self.model(states)_, next_values self.model(next_states)# 计算TD目标和优势函数# TD目标 即时奖励 折扣因子 * 下一状态的价值 * (1-终止标志)td_targets rewards self.gamma * next_values.squeeze(1) * (1 - dones)# 优势函数 TD目标 - 当前状态的价值估计advantages td_targets - values.squeeze(1)# 计算策略(Actor)损失action_probs policy.gather(1, actions.unsqueeze(1)).squeeze(1)# 计算策略熵用于鼓励探索entropy -(policy * torch.log(policy 1e-10)).sum(1).mean()# Actor损失 -(log策略 * 优势函数) - 熵系数 * 熵actor_loss -(torch.log(action_probs) * advantages.detach()).mean() - \self.config.entropy_coef * entropy# Critic损失 优势函数的平方误差critic_loss self.config.value_loss_coef * advantages.pow(2).mean()# 总损失 Actor损失 Critic损失return actor_loss critic_lossdef update(self, states, actions, rewards, dones, next_states):loss self.compute_loss(states, actions, rewards, dones, next_states)self.optimizer.zero_grad() # 清除之前的梯度loss.backward() # 反向传播计算梯度self.optimizer.step() # 更新网络参数# 训练主循环 def train_a2c():config Config() # 创建配置对象# 设置随机种子确保可重复性torch.manual_seed(config.seed)np.random.seed(config.seed)# 创建CartPole环境env gym.make(CartPole-v1)state_dim env.observation_space.shape[0] # 状态空间维度action_dim env.action_space.n # 动作空间维度# 创建A2C智能体agent A2C(state_dim, action_dim, config)# 训练循环for episode in range(config.max_episodes):state, _ env.reset() # 重置环境# 初始化回合数据存储states, actions, rewards, next_states, dones [], [], [], [], []total_reward 0 # 记录回合总奖励episode_reward 0 # 记录每个episode的reward# 单回合交互循环for step in range(config.max_steps):# 将状态转换为张量并添加批次维度state_tensor torch.FloatTensor(state).unsqueeze(0)# 获取动作概率分布policy, _ agent.model(state_tensor)# 从概率分布中采样动作action torch.multinomial(policy, 1).item()# 执行动作next_state, reward, done, _, _ env.step(action)# 存储交互数据states.append(state)actions.append(action)rewards.append(reward)dones.append(done)next_states.append(next_state)total_reward reward # 累积奖励episode_reward reward # 累积每个episode的rewardstate next_state # 更新状态if done: # 如果回合结束跳出循环break# 回合结束后更新模型agent.update(states, actions, rewards, dones, next_states)print(fEpisode {episode 1}, Total Reward: {total_reward})# 记录每个episode的rewardconfig.rewards_history.append(episode_reward)# 如果达到目标奖励提前结束训练if total_reward 500:print(Solved!)break# 绘制训练奖励曲线plot_rewards(config.rewards_history)env.close() # 关闭环境# 绘图函数 def plot_rewards(rewards):plt.figure(figsize(10,5))plt.plot(rewards)plt.title(Training Rewards)plt.xlabel(Episode)plt.ylabel(Reward)plt.grid()plt.show()# 程序入口 if __name__ __main__:train_a2c() 设置的reward到达500就提前结束训练结果图 由于平台字数限制下文链接https://blog.csdn.net/ooblack/article/details/144198573
http://www.w-s-a.com/news/370466/

相关文章:

  • 网站建设实习报告范文荆州市城市建设档案馆网站
  • 网站开发信息平台项目总结企业网站如何推广
  • 网站备案名称规定手机免费h5制作软件
  • 接网站建设单子的网站网页设计尺寸多大
  • 订制型网站费用做网站的问题
  • 淮阳住房和城乡建设网站桂林新闻桂林人论坛
  • 公司网站建设价格标准老版本网站开发工具
  • 门户网站开发费怎做账做网站交互demo工具
  • 中山最好的网站建设黄村网站建设价格
  • 企业网站首页应如何布局互联网营销师证书报名入口
  • 绍兴做网站哪家好篮球网站设计
  • 鹤岗市城乡建设局网站西域电商平台官网
  • 外贸网网站建设蓝色管理系统网站模版
  • 网站服务器关闭阿里巴巴logo
  • 青岛 网站制作公司乐从网站制作
  • wordpress 微网站模板怎么用wordpress 文档下载
  • ppt网站建设的目的合肥做网站找哪家好
  • wordpress站点路径redis缓存wordpress
  • 专门设计网站的公司叫什么百度 门户网站
  • 网站建设丶金手指专业旅游网站系统哪个好
  • 苏州工业园区两学一做网站成都企业排名
  • 医药网站开发wordpress境外支付
  • 营销自己的网站网站如何做标题优化
  • 玖云建站系统wordpress nodejs版本
  • 网站开发费用计入什么二级科目重庆企业网站推广
  • wordpress 菜单怎么使用方法宜春网站推广优化
  • dede 网站图标怎么自学建筑设计
  • 河北斯皮尔网站建设做微信小程序和做网站
  • 沈阳市住房和城乡建设局网站创意上海专业网站建设
  • 免费学编程国内网站it需要什么学历