【强化学习】12 —— 策略梯度(REINFORCE )

news2025/7/28 14:33:51

文章目录

  • 前言
  • 策略梯度
    • 基于策略的强化学习的优缺点
    • Example:Aliased Gridworld
    • 策略目标函数
    • 策略优化
    • 策略梯度
    • 利用有限差分计算策略梯度
    • 得分函数和似然比
    • 策略梯度定理
    • 蒙特卡洛策略梯度(Monte-Carlo Policy Gradient)
      • Puck World Example
    • Softmax随机策略
  • 代码实践
    • 结果
  • 参考

前言

之前在【强化学习】09——价值和策略近似逼近方法中讨论过使用参数 θ \theta θ来近似价值函数 V V V或状态价值函数 Q Q Q V θ ( s ) ≈ V π ( s ) Q θ ( s , a ) ≈ Q π ( s , a ) \begin{aligned}V_\theta(s)&\approx V^\pi(s)\\Q_\theta(s,a)&\approx Q^\pi(s,a)\end{aligned} Vθ(s)Qθ(s,a)Vπ(s)Qπ(s,a)之后,再通过价值函数推导出相应的策略(比如利用 ϵ \epsilon ϵ-贪婪策略)。

本节将主要讨论直接参数化策略的方法 π θ ( s , a ) \pi_{\theta}(s,a) πθ(s,a)。策略可以是确定性的—— a = π θ ( s ) a=\pi_{\theta}(s) a=πθ(s),也可以是随机的—— π θ ( s , a ) = P [ a ∣ s , θ ] \pi_\theta(s,a)=\mathbb{P}[a\mid s,\theta] πθ(s,a)=P[as,θ]。通过参数化策略可以将可见的已知状态泛化到未知的状态上。在本节中我们主要讨论的是模型无关的强化学习。

强化学习算法主要可以分为基于价值函数(Value-Based)的、基于策略的(Policy-Based)以及基于Actor-Critic(后文会进行介绍)框架的。

在这里插入图片描述
三者区别如下表所示:

MethodsValuePolicy
Value Based学习到的价值函数隐式的策略,如 ϵ \epsilon ϵ-贪婪策略
Policy Based没有价值函数学习到的策略
Actor-Critic学习到的价值函数学习到的策略

策略梯度

基于策略的强化学习的优缺点

优点

  • 具有更好的收敛性质
  • 在高维度或连续的动作空间中更有效
    • 这是最重要的因素:基于值函数的方法,通常需要取最大值
  • 能够学习出随机策略

缺点

  • 通常会收敛到局部最优而非全局最优(基于值函数的方法也可能出现)
  • 评估一个策略通常不够高效并具有较大的方差(variance)

Example:Aliased Gridworld

在这里插入图片描述

  • 智能体无法区分灰色部分的格子
  • 移动方向N, E, S, W

在这里插入图片描述

对于一个确定性的策略,可能会出现以下情况:

  • 在灰色区域同时向W方向移动
  • 或在灰色区域同时向E方向移动

因此,就无法抵达终点,获得奖励。基于价值函数的策略是近于确定性的策略(greedy or ϵ \epsilon ϵ-greedy),因此会在上面的区域经过很长的时间才可能获得奖励。
在这里插入图片描述
对于随机性的策略,在灰色区域向W或E方向移动的概率五五开。 π θ ( wall to N and S, move E ) = 0.5 π θ ( wall to N and S, move W ) = 0.5 \begin{aligned}\pi_\theta(\text{wall to N and S, move E})&=0.5\\\pi_\theta(\text{wall to N and S, move W})&=0.5\end{aligned} πθ(wall to N and S, move E)πθ(wall to N and S, move W)=0.5=0.5随机性的策略很有可能在几步内达到目标状态。基于策略的方法可以学习到最优的随机性策略。

策略目标函数

目标:给定策略 π θ ( s , a ) \pi_{\theta}(s,a) πθ(s,a),找到最优的 θ \theta θ。以下为几种衡量策略 π θ ( s , a ) \pi_{\theta}(s,a) πθ(s,a)质量的方法:

  • 在离散episodic的环境中使用起始价值(start value) J 1 ( θ ) = V π θ ( s 1 ) = E π θ [ v 1 ] J_1(\theta)=V^{\pi_\theta}(s_1)=\mathbb{E}_{\pi_\theta}\left[v_1\right] J1(θ)=Vπθ(s1)=Eπθ[v1]
  • 在连续 continuing的环境中使用平均价值(average value) J a v V ( θ ) = ∑ s d π θ ( s ) V π θ ( s ) J_{avV}(\theta)=\sum_sd^{\pi_\theta}(s)V^{\pi_\theta}(s) JavV(θ)=sdπθ(s)Vπθ(s)
  • 或者是每步的平均奖励average reward per time-step J a v R ( θ ) = ∑ s d π θ ( s ) ∑ a π θ ( s , a ) R s a J_{avR}(\theta)=\sum_sd^{\pi_\theta}(s)\sum_a\pi_\theta(s,a)R_s^a JavR(θ)=sdπθ(s)aπθ(s,a)Rsa
  • π θ \pi_{\theta} πθ服从 d π θ ( s ) d^{\pi_\theta}(s) dπθ(s)分布

策略优化

基于策略的强化学习本质是一个优化问题,对于目标函数 J ( θ ) J({\theta}) J(θ),找到合适的 θ \theta θ,使得目标函数最大化。

  • 未使用梯度的方法
    • Hill climbing
    • Simplex / amoeba / Nelder Mead
    • Genetic algorithms
  • 使用梯度的方法
    • Gradient descent
    • Conjugate gradient
    • Quasi-newton
      在本节中,主要讨论基于梯度下降的方法。

策略梯度

在这里插入图片描述

同样的,对于目标函数 J ( θ ) J({\theta}) J(θ),策略梯度算法需要通过不断提升策略的梯度以找到 J ( θ ) J({\theta}) J(θ)的局部最大值, Δ θ = α ∇ θ J ( θ ) \Delta\theta=\alpha\nabla_\theta J(\theta) Δθ=αθJ(θ)。其中 ∇ θ J ( θ ) \nabla_\theta J(\theta) θJ(θ)为策略梯度 ∇ θ J ( θ ) = ( ∂ J ( θ ) ∂ θ 1 ⋮ ∂ J ( θ ) ∂ θ n ) \nabla_\theta J(\theta)=\begin{pmatrix}\frac{\partial J(\theta)}{\partial\theta_1}\\\vdots\\\frac{\partial J(\theta)}{\partial\theta_n}\end{pmatrix} θJ(θ)= θ1J(θ)θnJ(θ)

利用有限差分计算策略梯度

  • 对于维度 k ∈ [ 1 , n ] k\in[1,n] k[1,n]
    • 估计滴 k k k维上目标函数 J ( θ ) J({\theta}) J(θ) θ \theta θ的偏微分
    • 引入偏移量 ϵ u k \epsilon u_k ϵuk,用差分近似微分。其中 u k u_k uk是单位向量,第 k k k个分量中为1,其他分量中为0. ∂ J ( θ ) ∂ θ k ≈ J ( θ + ϵ u k ) − J ( θ ) ϵ \frac{\partial J(\theta)}{\partial\theta_k}\approx\frac{J(\theta+\epsilon u_k)-J(\theta)}\epsilon θkJ(θ)ϵJ(θ+ϵuk)J(θ)
  • 简单、噪声大、效率低,但有时有效
  • 适用于任意策略,即使策略不可微分

得分函数和似然比

似然比(Likelihood ratios)利用下列特性 ∇ θ π θ ( s , a ) = π θ ( s , a ) ∇ θ π θ ( s , a ) π θ ( s , a ) = π θ ( s , a ) ∇ θ log ⁡ π θ ( s , a ) \begin{aligned} \nabla_\theta\pi_\theta(s,a)& =\pi_\theta(s,a)\frac{\nabla_\theta\pi_\theta(s,a)}{\pi_\theta(s,a)} \\ &=\pi_\theta(s,a)\nabla_\theta\log\pi_\theta(s,a) \end{aligned} θπθ(s,a)=πθ(s,a)πθ(s,a)θπθ(s,a)=πθ(s,a)θlogπθ(s,a)其中, ∇ θ log ⁡ π θ ( s , a ) \nabla_\theta\log\pi_\theta(s,a) θlogπθ(s,a)是得分函数(score function)

考虑一个简单的单步马尔可夫决策过程

  • 起始状态为𝑠~𝑑(𝑠)
  • 决策过程在进行一步决策后结束,获得奖励值为 r = R s , a r=\mathcal R_{s,a} r=Rs,a

所以策略的价值期望可以写成 J ( θ ) = E π θ [ r ] = ∑ s ∈ S d ( s ) ∑ a ∈ A π θ ( s , a ) R s , a ∇ θ J ( θ ) = ∑ s ∈ S d ( s ) ∑ a ∈ A ∇ θ π θ ( s , a ) = ∑ s ∈ S d ( s ) ∑ a ∈ A π θ ( s , a ) ∇ θ log ⁡ π θ ( s , a ) R s , a = E π θ [ ∇ θ log ⁡ π θ ( s , a ) r ] \begin{aligned} J(\theta)& =\mathbb{E}_{\pi_\theta}\left[r\right] \\ &=\sum_{s\in\mathcal{S}}d(s)\sum_{a\in\mathcal{A}}\pi_\theta(s,a)\mathcal{R}_{s,a} \\ \nabla_\theta J(\theta)&=\sum_{s\in\mathcal{S}}d(s)\sum_{a\in\mathcal{A}}\nabla_\theta\pi_\theta(s,a)\\& =\sum_{s\in\mathcal{S}}d(s)\sum_{a\in\mathcal{A}}\color{red}\pi_\theta(s,a)\nabla_\theta\log\pi_\theta(s,a)\mathcal{R}_{s,a} \\ &=\mathbb{E}_{\pi_\theta}\left[\nabla_\theta\log\pi_\theta(s,a)r\right] \end{aligned} J(θ)θJ(θ)=Eπθ[r]=sSd(s)aAπθ(s,a)Rs,a=sSd(s)aAθπθ(s,a)=sSd(s)aAπθ(s,a)θlogπθ(s,a)Rs,a=Eπθ[θlogπθ(s,a)r]

这一结果可以通过从 d ( s ) d(s) d(s)中采样状态 s s s和从 π θ π_θ πθ中采样动作𝑎来近似估计

策略梯度定理

策略梯度定理把似然比的推导过程泛化到多步马尔可夫决策过程.用长期的价值函数 Q π θ ( s , a ) Q^{\pi_\theta}(s,a) Qπθ(s,a)代替前面的瞬时奖励 r = R s , a r=\mathcal R_{s,a} r=Rs,a。策略梯度定理涉及起始状态目标函数 J 1 J_1 J1,平均奖励目标函数 J a v R J_{avR} JavR ,和平均价值目标函数 J a v V J_{avV} JavV.
定理
对任意可微的策略 π θ ( s , a ) \pi_{\theta}(s,a) πθ(s,a),任意策略的目标函数 J 1 , J a v R , J a v V J_1,J_{avR},J_{avV} J1JavRJavV,其策略梯度是 ∇ θ J ( θ ) = E π θ [ ∇ θ log ⁡ π θ ( s , a ) Q π θ ( s , a ) ] \nabla_\theta J(\theta)=\color{red}{\mathbb{E}_{\pi_\theta}\left[\nabla_\theta\log\pi_\theta(s,a)\right.Q^{\pi_\theta}(s,a)}] θJ(θ)=Eπθ[θlogπθ(s,a)Qπθ(s,a)]这种形式也是 ∂ J ( θ ) ∂ θ = E π θ [ ∂ l o g π θ ( a ∣ s ) ∂ θ Q π θ ( s , a ) ] \frac{\partial J(\theta)}{\partial\theta}=\mathbb{E}_{\pi_\theta}\left[\frac{\partial\mathrm{log}\pi_\theta(a|s)}{\partial\theta}Q^{\pi_\theta}(s,a)\right] θJ(θ)=Eπθ[θlogπθ(as)Qπθ(s,a)]

详细证明过程请参考:

  1. Rich Sutton’s Reinforcement Learning: An Introduction (2nd Edition)第13章
  2. 动手学强化学习策略梯度的附录

蒙特卡洛策略梯度(Monte-Carlo Policy Gradient)

  • 利用随机梯度上升更新参数
  • 利用策略梯度定理
  • 利用累计奖励值 G t G_t Gt作为 Q π θ ( s , a ) Q^{\pi_\theta}(s,a) Qπθ(s,a)的无偏采样 Δ θ t = α ∂ log ⁡ π θ ( a t ∣ s t ) ∂ θ G t \Delta\theta_t=\alpha\frac{\partial\log\pi_\theta(a_t|s_t)}{\partial\theta}G_t Δθt=αθlogπθ(atst)Gt

REINFORCE算法伪代码
在这里插入图片描述

Puck World Example

在这里插入图片描述

  • 连续的动作对冰球施加较小的力
  • 冰球接近目标可以得到奖励
  • 目标位置每30秒重置一次
  • 使用蒙特卡洛策略梯度方法训练策略

Softmax随机策略

对于具体策略的设计,通常使用Softmax随机策略。Softmax策略是一种非常常用的随机策略 π θ ( a ∣ s ) = e f θ ( s , a ) ∑ a ′ e f θ ( s , a ′ ) \pi_\theta(a|s)=\frac{e^{f_\theta(s,a)}}{\sum_{a^{\prime}}e^{f_\theta(s,a^{\prime})}} πθ(as)=aefθ(s,a)efθ(s,a)式中, f θ ( s , a ) f_\theta(s,a) fθ(s,a)是用𝜃参数化的状态-动作对得分函数,可以预先定义。其对数似然的梯度是 ∂ log π θ ( a ∣ s ) ∂ θ = ∂ f θ ( s , a ) ∂ θ − 1 ∑ a ′ e f θ ( s , a ′ ) ∑ a ′ ′ e f θ ( s , a ′ ′ ) ∂ f θ ( s , a ′ ′ ) ∂ θ = ∂ f θ ( s , a ) ∂ θ − E a ′ ∼ π θ ( a ′ ∣ s ) [ ∂ f θ ( s , a ′ ) ∂ θ ] \begin{gathered} \frac{\partial\text{log}\pi_\theta(a|s)}{\partial\theta} \begin{aligned}=\frac{\partial f_\theta(s,a)}{\partial\theta}-\frac{1}{\sum_{a^{\prime}}e^{f_\theta(s,a^{\prime})}}\sum_{a^{\prime\prime}}e^{f_\theta(s,a^{\prime\prime})}\frac{\partial f_\theta(s,a^{\prime\prime})}{\partial\theta}\end{aligned} \\ =\frac{\partial f_\theta(s,a)}{\partial\theta}-\mathbb{E}_{a^{\prime}\sim\pi_\theta(a^{\prime}|s)}\left[\frac{\partial f_\theta(s,a^{\prime})}{\partial\theta}\right] \end{gathered} θlogπθ(as)=θfθ(s,a)aefθ(s,a)1a′′efθ(s,a′′)θfθ(s,a′′)=θfθ(s,a)Eaπθ(as)[θfθ(s,a)]

举线性得分函数为例,则有 f θ ( s , a ) = θ T x ( s , a ) ∂ log π θ ( a ∣ s ) ∂ θ = ∂ f θ ( s , a ) ∂ θ − E a ′ ∼ π θ ( a ′ ∣ s ) [ ∂ f θ ( s , a ′ ) ∂ θ ] = x ( s , a ) − E a ′ ∼ π θ ( a ′ ∣ s ) [ x ( s , a ′ ) ] \begin{aligned} &f_{\theta}(s,a)=\theta^{\mathrm{T}}x(s,a) \\ \frac{\partial\text{log}\pi_\theta(a|s)}{\partial\theta}& =\frac{\partial f_{\theta}(s,a)}{\partial\theta}-\mathbb{E}_{a^{\prime}\sim\pi_{\theta}(a^{\prime}|s)}\left[\frac{\partial f_{\theta}(s,a^{\prime})}{\partial\theta}\right] \\ &=x(s,a)-\mathbb{E}_{a^{\prime}\sim\pi_{\theta}(a^{\prime}|s)}[x(s,a^{\prime})] \end{aligned} θlogπθ(as)fθ(s,a)=θTx(s,a)=θfθ(s,a)Eaπθ(as)[θfθ(s,a)]=x(s,a)Eaπθ(as)[x(s,a)]

代码实践

class PolicyNet(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)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        return F.softmax(self.fc2(x), dim=1)

class REINFORCE:
    def __init__(self, state_dim, hidden_dim, action_dim, learning_rate, gamma,
                device, numOfEpisodes, env):
        self.policy_net = PolicyNet(state_dim, hidden_dim, action_dim).to(device)
        self.optimizer = torch.optim.Adam(self.policy_net.parameters(), lr=learning_rate)
        self.gamma = gamma
        self.device = device
        self.env = env
        self.numOfEpisodes = numOfEpisodes

    # 根据动作概率分布随机采样
    def takeAction(self, state):
        state = torch.tensor(np.array([state]), dtype=torch.float).to(self.device)
        action_probs = self.policy_net(state)
        action_dist = torch.distributions.Categorical(action_probs)
        action = action_dist.sample()
        return action.item()

    def update(self, transition_dict):
        reward_list = transition_dict['rewards']
        state_list = transition_dict['states']
        action_list = transition_dict['actions']
        G = 0
        self.optimizer.zero_grad()
        for i in reversed(range(len(reward_list))):
            reward = reward_list[i]
            state = torch.tensor(np.array([state_list[i]]), dtype=torch.float).to(self.device)
            action = torch.tensor(np.array([action_list[i]]), dtype=torch.int64).view(-1, 1).to(self.device)
            log_prob = torch.log(self.policy_net(state).gather(1, action))
            G = self.gamma * G + reward
            loss = -log_prob * G  # 每一步的损失函数
            loss.backward()  # 反向传播计算梯度
        self.optimizer.step()  # 梯度下降

    def REINFORCERun(self):
        returnList = []
        for i in range(10):
            with tqdm(total=int(self.numOfEpisodes / 10), desc='Iteration %d' % i) as pbar:
                for episode in range(int(self.numOfEpisodes / 10)):
                    # initialize state
                    state, info = self.env.reset()
                    terminated = False
                    truncated = False
                    episodeReward = 0
                    transition_dict = {
                        'states': [],
                        'actions': [],
                        'next_states': [],
                        'rewards': [],
                        'terminateds': [],
                        'truncateds':[]
                    }
                    # Loop for each step of episode:
                    while (not terminated) or (not truncated):
                        action = self.takeAction(state)
                        next_state, reward, terminated, truncated, info = self.env.step(action)
                        if terminated or truncated:
                            break
                        transition_dict['states'].append(state)
                        transition_dict['actions'].append(action)
                        transition_dict['next_states'].append(next_state)
                        transition_dict['rewards'].append(reward)
                        transition_dict['terminateds'].append(terminated)
                        transition_dict['truncateds'].append(truncated)
                        state = next_state
                        episodeReward += reward
                    self.update(transition_dict)
                    returnList.append(episodeReward)
                    if (episode + 1) % 10 == 0:  # 每10条序列打印一下这10条序列的平均回报
                        pbar.set_postfix({
                            'episode':
                                '%d' % (self.numOfEpisodes / 10 * i + episode + 1),
                            'return':
                                '%.3f' % np.mean(returnList[-10:])
                        })
                    pbar.update(1)
        return returnList

结果

在这里插入图片描述

可以看到,随着收集到的轨迹越来越多,REINFORCE 算法有效地学习到了最优策略。不过,相比于前面的 DQN 算法,REINFORCE 算法使用了更多的序列,这是因为 REINFORCE 算法是一个在线策略算法,之前收集到的轨迹数据不会被再次利用。此外,REINFORCE 算法的性能也有一定程度的波动,这主要是因为每条采样轨迹的回报值波动比较大,这也是 REINFORCE 算法主要的不足。

REINFORCE 算法是策略梯度乃至强化学习的典型代表,智能体根据当前策略直接和环境交互,通过采样得到的轨迹数据直接计算出策略参数的梯度,进而更新当前策略,使其向最大化策略期望回报的目标靠近。这种学习方式是典型的从交互中学习,并且其优化的目标(即策略期望回报)正是最终所使用策略的性能,这比基于价值的强化学习算法的优化目标(一般是时序差分误差的最小化)要更加直接。 REINFORCE 算法理论上是能保证局部最优的,它实际上是借助蒙特卡洛方法采样轨迹来估计动作价值,这种做法的一大优点是可以得到无偏的梯度。但是,正是因为使用了蒙特卡洛方法,REINFORCE 算法的梯度估计的方差很大,可能会造成一定程度上的不稳定,这也是后面将介绍的 Actor-Critic 算法要解决的问题。

参考

[1] 伯禹AI
[2] https://www.davidsilver.uk/teaching/
[3] 动手学强化学习
[4] Reinforcement Learning

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1156441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣刷题-栈-逆波兰表达式求值

150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值。 有效的运算符包括 , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。 说明: 整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达…

YOLO算法改进3【中阶改进篇】:添加HorNet卷积模块

论文地址:https://arxiv.org/pdf/2207.14284.pdf 源码地址:https://github.com/raoyongming/HorNet. HorNet是在Swin transformer结构的基础上,结合大核思想提出的新的网络结构模块,使用该模块,作者在ImageNet-1k数据集上做分类,分割以及检测任务都在当时达到了SOTA的效果…

基于Langchain+向量数据库+ChatGPT构建企业级知识库

▼最近直播超级多,预约保你有收获 近期直播:《基于 LLM 大模型的向量数据库企业级应用实践》 1— LangChain 是什么? 众所周知 OpenAI 的 API 无法联网的,所以如果只使用自己的功能实现联网搜索并给出回答、总结 PDF 文档、基于某…

【机器学习】二、决策树

目录 一、决策树定义: 二、决策树特征选择 2.1 特征选择问题 2.2 信息增益 2.2.1 熵 2.2.2 信息增益 三、决策树的生成 3.1 ID3算法 3.1.1理论推导 3.1.2代码实现 3.2 C4.5 算法 3.2.1理论推导 ​ 3.2.2代码实现 四、决策树的剪枝 4.1 原理 4.2 算法思路&#xff1a…

VMware虚拟网络连接的三种方式

桥接模式(Bridged) 什么是桥接模式?桥接模式就是将主机网卡与虑拟机虑拟的网卡利用虑拟网桥进行通信。在桥接的作用下,类似于把物理主机虑拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当…

cocos creator,vscode打开脚本报错,找不到cc模块问题

cocosCreator,用VSCODE打开写脚本代码的时候,会误报飘红,但实际上能正常运行。 我的版本是当前最新版本的3.8.1 解决方案: 在CocosCreator 的安装目录下 C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin.dec…

Python---排序算法

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 Python中的排序算法用于对数据进行排序。排序算法可以使数据按照一定的规则进行排列,以便于数据的查找、统计、比较等操作。在数据分析、机器学习、图形计算等领域&#xff0c…

企业中很多老师傅都说没前途,该不该放弃嵌入式单片机行业?

今日话题,很多老师傅都说没前途,该不该放弃嵌入式单片机行业?许多新手在探讨嵌入式和单片机行业时,往往过于强调技术技能,而忽略了 行业的广度和深度。事实上,行业内有各种不同的产品领域,而你的…

IBM引入模块化设计助力波音与摩根大通快速实现量子计算服务

​(图片来源:网络) 经典计算机具有局限性,无法完成某些特定任务,例如准确预测金融市场或开发药物来对抗新兴疾病,而量子计算能打破“僵局”。部署IBM Quantum量子系统的负责人Chris Lirakis 说&#xff1a…

#stm32整理(一)flash读写

以这篇未开始我将进行stm32学习整理为期一个月左右完成stm32知识学习整理内容顺序没有一定之规写到哪想到哪想到哪写到哪,主要是扫除自己知识上的盲区完成一些基本外设操作。 以stm32f07为例子进行flash读写操作 stm32flash简介 参考资料正点原子和野火开发手册 …

国际权威媒体聚焦:孙宇晨和波场TRON在迪拜荣获加密行业重磅奖项

近日,在迪拜举行的区块链生态大会(Blockchain Life Conference)上,波场TRON创始人、火币HTX全球顾问委员会委员孙宇晨斩获“年度加密企业家”称号,波场TRON荣膺“年度最佳 Layer 1”大奖。这一消息迅速得到彭博社、雅虎财经、美联社和法国最大媒体之一Le Figaro等国际权威媒体的…

决赛入围名单公示!“山东工行杯”山东省第五届数据应用创新创业大赛

“山东工行杯”山东省第五届数据应用创新创业大赛8月30日启动以来,共计吸引2651人、1235支团队报名,累计收到作品1451件。 10月18日—24日,大赛组委会本着“公平、公正、公开”的原则,邀请到来自省内外各高校、企事业单位的、在数…

Python 应用 之 转换音频格式

目录 一、python音频转换 1、pydub 音频包安装 2、 ffmpeg安装 1)、解压后,添加到环境变量中 2)、可以直接放在python安装目录下 3、python程序 1)、引入相关包 2)、重命名 3)、to Mp3 4&#xf…

基于差分进化算法的无人机航迹规划-附代码

基于差分进化算法的无人机航迹规划 文章目录 基于差分进化算法的无人机航迹规划1.差分进化搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用差分进化算法来优化无人机航迹规划。 …

化肥厂的污水处理设备需要哪些

化肥厂的污水处理设备需要包括多级反渗透系统、生物处理系统、滤网、沉淀池、活性炭吸附器、曝气池和膜分离器等。 这些设备的主要作用是处理化肥厂产生的大量污水,包括对污水进行物理、化学和生物处理,以去除其中的污染物质和有害成分,达到…

Vue过渡动画详解及使用场景

文章目录 Vue过渡和动画的主要概念1. `<transition>` 组件2. `<transition-group>` 组件3. CSS 过渡类4. 过渡钩子函数Vue过渡和动画应用场景1. 页面切换动画2. 表单验证反馈3. 列表排序和过滤4. 模态框和对话框✍创作者:全栈弄潮儿 🏡 个人主页: 全栈弄潮儿的…

C语言实现贪吃蛇小游戏

#include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define PI 3.14 #define NODE_WIDTH 40 //绘制蛇的节点 typedef struct {int x;int y;…

【Java 进阶篇】Java Response 重定向详解

在Java Web开发中&#xff0c;重定向&#xff08;Redirect&#xff09;是一种常见的技术&#xff0c;用于将用户从一个URL地址自动重定向到另一个URL地址。这在很多情况下都非常有用&#xff0c;例如在用户登录后将其重定向到其个人资料页面&#xff0c;或者在进行某些操作后将…

自己动手实现一个深度学习算法——二、神经网络的实现

文章目录 1. 神经网络概述1&#xff09;表示2&#xff09;激活函数3&#xff09;sigmoid函数4&#xff09;阶跃函数的实现5&#xff09;sigmoid函数的实现6)sigmoid函数和阶跃函数的比较7&#xff09;非线性函数8&#xff09;ReLU函数 2.三层神经网络的实现1&#xff09;结构2&…

现代的简洁,诠释轻奢的精致!福州中宅装饰,福州装修

轻奢风是一种生活新时尚 优雅、低调、舒适、简单&#xff0c;不断地推陈出新 站在时尚的前沿&#xff0c;引领潮流 中宅装饰集团轻奢风格产品 追求高品质生活细节 以设计精致的空间构造营造出 一种优雅、时尚生活氛围 将低调奢华之美注入现代家居设计中 客厅|The Sitt…