基于策略的强化学习方法之近端策略优化(PPO)深度解析
PPO(Proximal Policy Optimization)是一种基于策略梯度的强化学习算法,旨在通过限制策略更新幅度来提升训练稳定性。传统策略梯度方法(如REINFORCE)直接优化策略参数,但易因更新步长过大导致性能震荡或崩溃。PPO通过引入近端策略优化目标函数和截断技巧(Clipping Trick)替代TRPO的信任区域约束,约束新旧策略之间的差异,避免策略突变,既保持了策略更新的稳定性,又显著降低了计算成本。其核心思想是:在保证策略改进的同时,限制策略更新的幅度。
前文基础:
(1)基于值函数的强化学习算法之Q-Learning详解:基于值函数的强化学习算法之Q-Learning详解_网格世界q值-CSDN博客
(2)基于值函数的强化学习算法之SARSA详解:基于值函数的强化学习算法之SARSA详解_sarsa算法流程-CSDN博客
(3)基于值函数的强化学习算法之深度Q网络(DQN)详解:基于值函数的强化学习算法之深度Q网络(DQN)详解_dqn算法对传统q-learning算法进行了改进,使用了神经网络(结构可以自行设计)对acti-CSDN博客(4)基于策略的强化学习方法之策略梯度(Policy Gradient)详解:基于策略的强化学习方法之策略梯度(Policy Gradient)详解-CSDN博客
一、理论基础
(一)强化学习与策略梯度方法概述
1. 强化学习基本框架
强化学习(Reinforcement Learning, RL)旨在解决智能体与环境交互过程中的序列决策问题。其核心要素包括:
(1)环境(Environment):用马尔可夫决策过程(MDP)建模,状态空间S,动作空间A,转移概率p(s′|s,a),奖励函数r(s,a,s′)。马尔可夫决策过程(MDP)示例图:
(2)智能体(Agent):通过策略π(a|s)选择动作,目标是最大化长期累积奖励的期望,即回报的期望,其中γ∈[0,1]为折扣因子。
回报公式说明:回报是智能体从时刻t开始的未来累积奖励,通过折扣因子γ对远期奖励进行衰减,体现“即时奖励比远期奖励更重要”的特性。γ=0时仅考虑即时奖励,γ=1时等同蒙特卡洛回报(无折扣)。引入折扣因子可确保无限序列的期望收敛,便于数学处理。
(3)价值函数:状态价值函数,动作价值函数
。
状态价值函数说明:表示在策略π下,从状态s出发的期望回报,是评估策略长期性能的核心指标。满足贝尔曼方程:,体现递归性质。
动作价值函数说明:表示在策略π下,从状态s执行动作a后的期望回报,用于比较不同动作的优劣。与状态价值函数的关系:,即状态价值是动作价值的策略期望。
以下是强化学习核心三要素之间的关系:
强化学习基本框架如下:
2. 策略梯度方法核心思想
策略梯度方法直接对策略进行参数化(θ为参数),通过优化目标函数提升策略性能。常见目标函数
包括:
(1)初始价值(Start Value):,对应从初始状态出发的期望回报。
(2)平均价值(Average Value):,其中
为策略π下的状态分布。
(3)平均奖励(Average Reward):,适用于无限horizon问题。
策略梯度定理表明,在参数θ下的目标函数的梯度可表示为:
该公式揭示了策略优化的本质:通过提升高价值动作的选择概率,降低低价值动作的选择概率。
(二)近端策略优化(PPO)的提出背景
1. 传统策略梯度方法的局限性
(1)高方差问题:直接使用θ参数下的动作价值函数作为优势估计会引入较大方差,通常用优势函数
替代,以减少基线(Baseline)以上的波动。
(2)样本效率低:策略更新后需重新收集数据,导致离线策略(Off-Policy)方法难以直接应用。
2. 信任区域策略优化(TRPO)的改进与不足
TRPO 通过引入信任区域(Trust Region)约束,确保策略更新不会导致性能大幅下降。其优化目标为:
约束条件为:
TRPO通过共轭梯度法求解带约束的优化问题,保证了单调改进,但计算复杂度高(需计算Hessian矩阵),工程实现难度大。
3. PPO的核心创新
PPO通过近端策略优化目标函数和截断技巧(Clipping Trick)替代TRPO的信任区域约束,既保持了策略更新的稳定性,又显著降低了计算成本。其核心思想是:在策略更新时,限制新旧策略的概率比值在合理范围内,避免过大的策略变化。
二、数学基础
(一)策略梯度与重要性采样
先对公式关联关系进行说明:
(1)策略梯度定理是所有策略优化方法的基石,引出了优势函数的核心作用。
(2)重要性采样使离线策略优化成为可能,是PPO复用旧样本的理论基础。
(3)GAE通过加权求和优化优势估计,提升了策略梯度的估计精度,直接影响PPO目标函数的有效性。
(4)TRPO的信任区域思想通过PPO的截断技巧近似实现,平衡了优化效率与稳定性。
(5)梯度裁剪、归一化从数学层面解决了优化过程中的数值稳定性问题,确保理论公式在实际训练中有效落地。
1. 策略梯度推导
目标函数:
梯度推导:
(1)对目标函数求导,利用期望的线性性质和链式法则:
其中,表示轨迹,
是策略的对数概率,其梯度指示策略参数变化对动作概率的影响方向。
(2)引入价值函数作为基线(Baseline),消去常数项以减少方差
其中,为差分误差(TD Error),等价于优势函数
。
(3)代入后化简得策略梯度定理,因此,在θ参数下的策略梯度可简化为:
物理意义:策略梯度是优势函数与策略对数梯度的期望,表明应增加高优势动作的概率,降低低优势动作的概率。
2. 重要性采样(Importance Sampling)
在离线策略优化中,利用旧策略收集的数据训练新策略
,需通过重要性采样权重校正分布差异:
重要性采样权重的说明:用于离线策略优化,校正旧策略
与新策略
的分布差异。权重是轨迹中各动作概率比值的累积乘积,反映新旧策略生成该轨迹的相对概率。
则离线策略梯度可表示为:
通过重要性采样,可利用旧策略收集的数据优化新策略,避免频繁交互环境,提升样本效率。但权重可能导致高方差,需通过优势函数归一化或截断技巧缓解。
(二)优势函数估计与广义优势估计(GAE)
1. 优势函数的作用
优势函数表示动作a在状态s下相对于平均动作的优劣,其估计精度直接影响策略更新的稳定性。若直接使用蒙特卡洛回报
作为优势估计,方差较高;若使用TD误差
,偏差较高。
2. 广义优势估计(GAE)
GAE通过引入参数λ∈[0,1]平衡偏差与方差,其递归公式为:
其中,。表示当前状态价值估计与下一状态价值估计的差异,是单步引导(Bootstrapping)的结果。低方差但有偏差(依赖价值函数估计精度)。当λ=0时,退化为TD误差,等价于单步优势估计(低方差,高偏差);当λ=1时,等价于蒙特卡洛优势估计(无偏差,高方差),通常取λ∈[0.9, 0.99]平衡偏差与方差。将GAE递归公式展开,等价于加权求和,因此,GAE的优势估计可表示为:
该估计具有较低的方差和较好的计算效率,是PPO的关键技术之一。
补充:蒙特卡洛优势:
直接使用实际回报减去状态价值,无偏差但方差高(需完整轨迹)。
(三)PPO目标函数推导
1. 原始目标函数与截断思想
PPO的优化目标基于重要性采样的策略梯度,结合截断技巧防止策略更新幅度过大。定义概率比值:
概率比值用于衡量新旧策略在相同状态下选择相同动作的概率变化,表示新策略更倾向于该动作,反之则更抑制。
则截断目标函数为:
其中,clip(·,l,u)为截断函数,将概率比值限制在[1−ϵ,1+ϵ]范围内。截断目标函数的推导逻辑:
(1)当优势函数时(高价值动作),鼓励
增大以提升动作概率,但不超过1+ϵ,避免过度偏离旧策略;
(2)当时(低价值动作),限制
减小以降低动作概率,但不低于1−ϵ,从而避免策略更新过于激进;
(3)clip函数形成 “安全区间”,确保策略更新在旧策略的“近端”范围内,类似TRPO的信任区域约束。
2. 包含价值函数的联合优化目标
为同时优化价值函数,PPO引入价值损失,并通过熵正则项
增强探索性,最终联合目标函数为:
其中,各分量作用:
(1):策略优化的核心项,平衡性能提升与稳定性。
(2):价值损失通常采用均方误差(MSE),提升优势估计精度(优势估计为:
):
为目标价值,可通过GAE计算的回报
得到。
(3)熵正则项,鼓励策略探索,用于防止策略过早收敛到确定性策略。
3. PPO与TRPO的理论关联
TRPO通过KL散度约束确保策略更新在信任区域内,而PPO通过截断概率比值间接实现类似约束。理论上,当ϵ较小时,PPO的截断操作近似于TRPO的信任区域约束,但计算复杂度显著降低。
(1)TRPO约束条件:
解析:通过KL散度约束新旧策略的分布差异,确保策略更新在“信任区域”内,理论上保证性能单调提升。需计算二阶导数(Hessian 矩阵),计算复杂度高。
(2)PPO的近似性:当ϵ较小时,截断操作近似于KL散度约束。例如,若,则对数概率差异
,根据泰勒展开:
即ϵ间接控制了KL散度的上界,实现与TRPO类似的稳定性保证,但无需显式计算KL散度。
三、网络结构
(一)Actor-Critic 架构
1. 网络组成
PPO采用Actor-Critic架构(策略+价值学习),包含两个神经网络:
(1)Actor策略网络:输入状态s,输出动作概率分布,对于离散动作空间通常使用Softmax层,连续空间则使用高斯分布(输出均值和标准差)。
(2)Critic价值网络:输入状态s,输出价值估计,通常为全连接网络,输出标量值。
2. 共享特征提取层
为提高样本效率,Actor和Critic网络通常共享前几层卷积层(图像输入)或全连接层(状态为向量时),仅在输出层分支为策略输出和价值输出。例如,对于Atari游戏,共享卷积层提取视觉特征,Actor输出各动作概率,Critic输出价值估计。
(二)执行流程图
PPO执行流程:
初始化策略网络π_old和π_new,价值网络V,优化器
for 每个训练周期:
1. 数据收集阶段:
用π_old与环境交互,收集轨迹D = {(s_t, a_t, r_t, s_{t+1})}
计算优势估计Â_t和目标价值Ŕ_t(使用GAE)
2. 策略更新阶段:
将D输入π_new,计算概率比值r_t = π_new(a_t|s_t)/π_old(a_t|s_t)
计算截断目标函数L_CLIP = min(r_t*Â_t, clip(r_t, 1-ε, 1+ε)*Â_t)
计算熵损失L_ent = -E[log π_new(a_t|s_t)]
总策略损失L_pi = -E[L_CLIP + c2*L_ent]
反向传播更新π_new参数
重复K次更新(通常K=3-10)
3. 价值网络更新阶段:
计算价值损失L_v = MSE(V(s_t), Ŕ_t)
反向传播更新V参数
4. 同步策略网络:
π_old = π_new
end for
(三)关键组件细节
1. 经验回放与批量处理
PPO通常不使用大规模经验回放缓冲区(因策略更新需保证数据来自相近策略),而是将每个周期收集的轨迹分割为多个小批量(Mini-Batch),在每个小批量上进行多次更新,以模拟SGD的效果,减少内存占用。
2. 优势归一化
为稳定训练,通常对优势估计进行归一化处理,使其均值为0,标准差为1:
其中ϵ为极小值防止除零。
3. 动作空间处理
(1)离散动作空间:Actor网络输出各动作的logits,经Softmax得到概率分布,采样时根据概率选择动作。
(2)连续动作空间:Actor网络输出动作均值μ和对数标准差,动作通过
采样,其中
。
四、工程化实现技术
(一)优化技巧
1. 梯度裁剪(Gradient Clipping)
为防止梯度爆炸,对策略梯度和价值梯度进行范数裁剪:
前者为值裁剪,后者为范数裁剪,实际中范数裁剪更常用。
解析:将梯度范数限制在c以内,防止梯度爆炸(如||g||过大时,梯度方向不变但幅值缩放)。数学上保证优化过程的稳定性,避免参数更新步长过大导致振荡。
优势归一化:
解析:将优势估计标准化为均值 0、标准差1的分布,避免不同批次数据的尺度差异影响训练。减少梯度方差,加速收敛,尤其在多环境并行训练时效果显著。
2. 学习率衰减
采用线性衰减或指数衰减学习率,提升训练后期的稳定性。例如,线性衰减公式为:
其中t为当前训练步数,为总步数。
3. 参数初始化
使用正交初始化(Orthogonal Initialization)对网络权重进行初始化,激活函数通常选择 ReLU或Tanh。例如,Actor网络的输出层权重初始化为0.01,以避免初始策略过于确定。
(二)并行训练与样本效率提升
1. 向量化环境(Vectorized Environment)
通过并行运行多个环境实例(如使用SubprocVecEnv),同时收集多条轨迹,减少CPU空闲时间。例如,在Python中使用gym.vector库创建向量化环境:
python代码:
from gym.vector import SyncVectorEnvenv = SyncVectorEnv([lambda: gym.make("CartPole-v1") for _ in range(8)])
2. 异步策略更新(Asynchronous Update)
在分布式架构中,多个工作节点(Worker)并行收集数据,参数服务器(Parameter Server)汇总梯度并更新全局模型。该方法可显著提升样本采集速度,但需注意策略过时(Staleness)问题。
(三)部署与泛化能力增强
1. 环境归一化
对状态输入进行归一化处理,如减去均值、除以标准差,可提升模型泛化能力。通常维护一个运行均值和方差,在训练过程中动态更新:
2. 多任务学习与迁移学习
通过预训练模型在相似任务上的参数,初始化目标任务的网络,可加速收敛。例如,在机器人控制中,先在仿真环境中训练PPO模型,再通过域随机化(Domain Randomization)迁移到真实环境。
五、Python 完整示例(以 CartPole 为例)
(一)环境配置与依赖安装
python代码:
import gymimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.distributions import Categoricalimport numpy as np# 超参数LR = 3e-4GAMMA = 0.99EPS_CLIP = 0.2K_EPOCHS = 4UPDATE_INTERVAL = 2000ENTROPY_COEF = 0.01VALUE_COEF = 0.5
(二)Actor-Critic网络定义
python代码:
class ActorCritic(nn.Module):def __init__(self, state_dim, action_dim):super(ActorCritic, self).__init__()self.common = nn.Sequential(nn.Linear(state_dim, 64),nn.ReLU(),nn.Linear(64, 64),nn.ReLU())self.actor = nn.Linear(64, action_dim)self.critic = nn.Linear(64, 1)def forward(self, state):x = self.common(state)action_logits = self.actor(x)value = self.critic(x)return action_logits, valuedef act(self, state):state = torch.from_numpy(state).float().unsqueeze(0)action_logits, _ = self.forward(state)dist = Categorical(logits=action_logits)action = dist.sample()return action.item(), dist.log_prob(action)
(三)PPO算法实现
python代码:
class PPO:def __init__(self, state_dim, action_dim):self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")self.policy = ActorCritic(state_dim, action_dim).to(self.device)self.optimizer = optim.Adam(self.policy.parameters(), lr=LR)self.MseLoss = nn.MSELoss()def select_action(self, state):with torch.no_grad():action, log_prob = self.policy.act(state)return action, log_probdef update(self, transitions):states, actions, log_probs_old, rewards, next_states, dones = zip(*transitions)# 预计算优势函数和目标价值,避免在训练循环中重复计算states_tensor = torch.FloatTensor(states).to(self.device)next_states_tensor = torch.FloatTensor(next_states).to(self.device)# 计算优势函数和目标价值(使用GAE)with torch.no_grad():values = self.policy.forward(states_tensor)[1].squeeze()next_values = self.policy.forward(next_states_tensor)[1].squeeze()rewards_tensor = torch.FloatTensor(rewards).to(self.device)dones_tensor = torch.FloatTensor(dones).to(self.device)deltas = rewards_tensor + GAMMA * next_values * (1 - dones_tensor) - valuesadvantages = self.gae(deltas, values, next_values, dones_tensor)returns = values + advantages# 标准化优势函数advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)# 将数据转换为张量并移动到设备actions_tensor = torch.LongTensor(actions).to(self.device)log_probs_old_tensor = torch.FloatTensor(log_probs_old).to(self.device)# PPO更新 - 每次迭代重新计算损失for _ in range(K_EPOCHS):# 重新计算当前策略下的动作概率和价值估计action_logits, values_pred = self.policy.forward(states_tensor)dist = Categorical(logits=action_logits)log_probs = dist.log_prob(actions_tensor)entropy = dist.entropy().mean()# 计算概率比值和截断目标ratios = torch.exp(log_probs - log_probs_old_tensor)surr1 = ratios * advantagessurr2 = torch.clamp(ratios, 1-EPS_CLIP, 1+EPS_CLIP) * advantagespolicy_loss = -torch.min(surr1, surr2).mean()value_loss = self.MseLoss(values_pred.squeeze(), returns)total_loss = policy_loss + VALUE_COEF * value_loss - ENTROPY_COEF * entropyself.optimizer.zero_grad()total_loss.backward()nn.utils.clip_grad_norm_(self.policy.parameters(), 0.5) # 梯度裁剪self.optimizer.step()def gae(self, deltas, values, next_values, dones):advantages = torch.zeros_like(deltas)running_advantage = 0for t in reversed(range(len(deltas))):running_advantage = deltas[t] + GAMMA * 0.95 * running_advantage * (1 - dones[t])advantages[t] = running_advantagereturn advantages
(四)训练与测试流程
python代码:
def train():env = gym.make("CartPole-v1")state_dim = env.observation_space.shape[0]action_dim = env.action_space.nppo = PPO(state_dim, action_dim)print("开始训练...")running_reward = 0transitions = []for step in range(1, 1000001):state, _ = env.reset()episode_reward = 0while True:action, log_prob = ppo.select_action(state)next_state, reward, terminated, truncated, _ = env.step(action)done = terminated or truncated # 合并终止和截断标志transitions.append((state, action, log_prob, reward, next_state, done))episode_reward += rewardstate = next_stateif len(transitions) >= UPDATE_INTERVAL or done:ppo.update(transitions)transitions = []if done:running_reward = 0.99 * running_reward + 0.01 * episode_reward if running_reward != 0 else episode_rewardprint(f"Step: {step}, Reward: {episode_reward:.2f}, Running Reward: {running_reward:.2f}")break# 训练完成后保存模型torch.save(ppo.policy.state_dict(), "ppo_cartpole.pth") # 修改:使用实例变量ppoenv.close()return ppo # 返回训练好的模型实例def test():env = gym.make("CartPole-v1", render_mode="human")state_dim = env.observation_space.shape[0]action_dim = env.action_space.nppo = PPO(state_dim, action_dim)ppo.policy.load_state_dict(torch.load("ppo_cartpole.pth"))state, _ = env.reset()while True:action, _ = ppo.select_action(state)state, reward, terminated, truncated, _ = env.step(action)done = terminated or truncatedenv.render()if done:breakenv.close()if __name__ == "__main__":trained_ppo = train() # 保存训练好的模型实例test()
要执行的步骤次数在train()函数中修改,当前默认是1000000次,会很久。训练过程如下:
效果如下:
六、总结与扩展
(一)PPO的优缺点分析
1.优点:
(1)稳定性强:通过截断技巧有效控制策略更新幅度,避免性能骤降。
(2)样本效率高:支持离线策略优化,可重复利用旧样本。
(3)工程友好:无需复杂的二阶导数计算,易于实现和调试。
2.缺点:
(1)超参数敏感:ϵ、K_EPOCHS等参数需仔细调整。
(2)连续动作空间处理:需额外设计动作分布(如高斯分布),收敛速度可能慢于离散空间。
(二)扩展方向
1. 连续动作空间优化
对于机器人控制等连续动作场景,可将Actor网络改为输出高斯分布的均值和标准差,并使用Tanh激活函数限制动作范围。此时,概率比值计算需考虑动作空间的雅可比行列式(Jacobian Determinant)。
2. 多智能体强化学习
将PPO扩展至多智能体场景(如MADDPG),需引入全局状态或联合动作空间,并设计通信机制或集中式评论家(Centralized Critic)。
3. 与模仿学习结合
通过逆强化学习(IRL)从专家数据中学习奖励函数,结合PPO进行策略优化,可提升在复杂环境中的表现。
(三)理论延伸:PPO 的收敛性分析
尽管 PPO未严格证明全局收敛性,但其通过截断操作保证了每次更新的单调改进(在理想情况下)。研究表明,当学习率足够小且截断参数ϵ适当,PPO可收敛到局部最优策略,其性能接近TRPO但计算成本更低。
全文总结:
PPO通过理论创新(截断目标函数)和工程优化(梯度裁剪、批量更新),成为当前最流行的策略梯度方法之一。其数学基础融合了策略梯度、重要性采样和信任区域思想,网络结构基于Actor-Critic架构,工程实现中通过多种技巧提升稳定性和样本效率。通过上述深度解析,读者可全面掌握PPO的核心原理与实践方法,并能根据具体场景进行扩展应用。
相关文章:

基于策略的强化学习方法之近端策略优化(PPO)深度解析
PPO(Proximal Policy Optimization)是一种基于策略梯度的强化学习算法,旨在通过限制策略更新幅度来提升训练稳定性。传统策略梯度方法(如REINFORCE)直接优化策略参数,但易因更新步长过大导致性能震荡或崩溃…...
跨境电商定价革命:亚马逊“逆向提价“策略背后的价值重构逻辑
导言:打破价格魔咒的销量奇迹 2024年Q3亚马逊平台上演商业悖论:在TOP5000卖家中,12%实施5%-15%温和提价的商户,41%实现单量30.4%的季度增长。这一现象颠覆"低价即流量"的电商铁律,揭开新消费时代"价值定…...

文章复现|(1)整合scRNA-seq 和空间转录组学揭示了子宫内膜癌中 MDK-NCL 依赖性免疫抑制环境
https://www.frontiersin.org/journals/immunology/articles/10.3389/fimmu.2023.1145300/full 目标:肿瘤微环境(TME)在子宫内膜癌(EC)的进展中起着重要作用。我们旨在评估EC的TME中的细胞群体。 方法:我们从GEO下载了EC的单细胞RNA测序(scRNA-seq)和空…...

HTML-3.4 表单form
本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 系列文章目录 HTML-1.1 文本字体样式-字体设置、分割线、段落标签、段内回车以及特殊符号 HTML…...
阿克曼-幻宇机器人系列教程3- 机器人交互实践(Message)
上一篇文章介绍了如何通过topic操作命令实现与机器人的交互,本篇我们介绍如何通过Message(即topic的下一级)实现与机器人的交互。 和topic一样,首先在一个终端通过ssh命令登录机器人、启动机器人,然后打开另外一个终端…...

【MySQL】服务器配置与管理(相关日志)
🔥个人主页: 中草药 🔥专栏:【MySQL】探秘:数据库世界的瑞士军刀 一、系统变量和选项 当通过mysqld启动数据库服务器时,可以通过选项文件或命令行中提供选项。一般,为了确保服务器在每次运行时…...

【问题】Watt加速github访问速度:好用[特殊字符]
前言 GitHub 是全球知名的代码托管平台,主要用于软件开发,提供 Git 仓库托管、协作工具等功能,经常要用到,但是国内用户常因网络问题难以稳定访问 。 Watt Toolkit(原名 Steam)是由江苏蒸汽凡星科技有限公…...

vue3:十三、分类管理-表格--行内按钮---行删除、批量删除实现功能实现
一、实现效果 增加行内按钮的样式效果,并且可以根绝父组件决定是否显示 增加行内删除功能、批量删除功能 二、增加行内按钮样式 1、增加视图层按钮 由于多个表格都含有按钮功能,所以这里直接在子组件中加入插槽按钮 首先增加表格行<el-table-column></el-table-…...
Web3.0:互联网的去中心化未来
随着互联网技术的不断发展,我们正站在一个新时代的门槛上——Web3.0时代。Web3.0不仅仅是一个技术升级,它更是一种全新的互联网理念,旨在通过去中心化技术重塑网络世界。本文将深入探讨Web3.0的核心概念、技术基础、应用场景以及它对未来的深…...

浏览器设置代理ip后不能上网?浏览器如何改ip地址教程
使用代理IP已成为许多用户保护隐私、绕过地域限制或进行网络测试的常见做法。当浏览器设置代理IP后无法上网时,通常是由于代理配置问题或代理服务器本身不可用。以下是排查和解决问题的详细步骤,以及更改浏览器IP的方法: 一、代理设置后无法上…...
Java应用OOM排查:面试通关“三部曲”心法
开篇点题:OOM——Java应用的“内存爆仓”警报 OOM (OutOfMemoryError) 是啥病?想象一下,你的Java应用程序是一个大仓库,内存就是仓库的存储空间。如果货物(程序运行时创建的对象)越来越多,超出了…...

R语言的专业网站top5推荐
李升伟 以下是学习R语言的五个顶级专业网站推荐,涵盖教程、社区、资源库和最新动态: 1.R项目官网 (r-project.org) R语言的官方网站,提供软件下载、文档、手册和常见问题解答。特别适合初学者和高级用户,是获取R语言核心资源的…...
设计模式系列(03):设计原则(二):DIP、ISP、LoD
本文为设计模式系列第3篇,聚焦依赖倒置、接口隔离、迪米特法则三大设计原则,系统梳理定义、实际业务场景、优缺点、最佳实践与常见误区,适合系统学习与团队协作。 目录 1. 引言2. 依赖倒置原则(DIP)3. 接口隔离原则(ISP)4. 迪米特法则(LoD)5. 常见误区与反例6. 最佳实…...
Java Socket编程完全指南:从基础到实战应用
Socket编程是构建网络应用的基石,Java通过java.net包提供了强大的Socket API。本文将深入解析Java Socket类的核心用法,涵盖TCP/UDP协议实现、多线程通信及性能优化技巧,助您快速掌握网络编程精髓。 一、Socket编程核心概念 1.1 网络通信模型…...

[训练和优化] 3. 模型优化
👋 你好!这里有实用干货与深度分享✨✨ 若有帮助,欢迎: 👍 点赞 | ⭐ 收藏 | 💬 评论 | ➕ 关注 ,解锁更多精彩! 📁 收藏专栏即可第一时间获取最新推送🔔…...
基于FPGA的车速检测系统仿真设计与实现
标题:基于FPGA的车速检测系统仿真设计与实现 内容:1.摘要 本文旨在设计并实现基于FPGA的车速检测系统仿真。随着汽车行业的快速发展,精确的车速检测对于车辆的安全性和性能评估至关重要。本研究采用FPGA作为核心处理单元,结合传感器数据采集与处理技术进…...

无人设备遥控器之无线通讯技术篇
无人设备遥控器的无线通讯技术是确保遥控操作准确、稳定、高效进行的关键。以下是对无人设备遥控器无线通讯技术的详细解析: 一、主要无线通讯技术类型 Wi-Fi通讯技术 原理:基于IEEE 802.11标准,通过无线接入点(AP)…...
Redis(2):Redis + Lua为什么可以实现原子性
Redis 作为一款高性能的键值对存储数据库,与 Lua 脚本相结合,为实现原子性操作提供了强大的解决方案,本文将深入探讨 Redis Lua 实现原子性的相关知识 原子性概念的厘清 在探讨 Redis Lua 的原子性之前,我们需要明确原子性的概念…...

PyTorch LSTM练习案例:股票成交量趋势预测
文章目录 案例介绍源码地址代码实现导入相关库数据获取和处理搭建LSTM模型训练模型测试模型绘制折线图主函数 绘制结果 案例介绍 本例使用长短期记忆网络模型对上海证券交易所工商银行的股票成交量做一个趋势预测,这样可以更好地掌握股票买卖点,从而提高…...

CK3588下安装linuxdeployqt qt6 arm64
参考资料: Linux —— linuxdeployqt源码编译与打包(含出错解决) linux cp指令报错:cp: -r not specified; cp: omitting directory ‘xxx‘(需要加-r递归拷贝) CMake Error at /usr/lib/x86_64…...

木马查杀引擎—关键流程图
记录下近日研究的木马查杀引擎,将关键的实现流程图画下来 PHP AST通道实现 木马查杀调用逻辑 模型训练流程...

二程运输的干散货船路径优化
在二程运输中,干散货船需要将货物从一个港口运输到多个不同的目的地港口。路径优化的目标是在满足货物运输需求、船舶航行限制等条件下,确定船舶的最佳航行路线,以最小化运输成本、运输时间或其他相关的优化目标。 影响因素 港口布局与距离:各个港口之间的地理位置和距离…...

华为数字政府与数字城市售前高级专家认证介绍
华为数字政府与数字城市售前高级专家认证面向华为合作伙伴售前高级解决方案专家、华为数字政府与数字城市行业解决方案经理(VSE)。 通过认证验证的能力 您将了解数字政府、数字城市行业基础知识,了解该领域内的重点场景;将对华…...
在VSCode中接入DeepSeek的指南
本文将介绍三种主流接入方式,涵盖本地模型调用和云端API接入方案。 一、环境准备 1.1 基础要求 VSCode 1.80+Node.js 16.x+Python 3.8+(本地部署场景)已部署的DeepSeek服务(本地或云端)1.2 安装必备插件 # 打开VSCode插件面板(Ctrl+Shift+X) 搜索并安装: - DeepSeek Of…...

【docker】--容器管理
文章目录 容器重启--restart 参数选项及作用**对比 always 和 unless-stopped****如何查看容器的重启策略?** 容器重启 –restart 参数选项及作用 重启策略 no:不重启(默认)。on-failure:失败时重启(可限…...

基于OpenCV的人脸微笑检测实现
文章目录 引言一、技术原理二、代码实现2.1 关键代码解析2.1.1 模型加载2.1.2 图像翻转2.1.3 人脸检测 微笑检测 2.2 显示效果 三、参数调优建议四、总结 引言 在计算机视觉领域,人脸检测和表情识别一直是热门的研究方向。今天我将分享一个使用Python和OpenCV实现…...
使用PEFT库将原始模型与LoRA权重合并
使用PEFT库将原始模型与LoRA权重合并 步骤如下: 基础模型加载:需保持与LoRA训练时相同的模型配置merge_and_unload():该方法会执行权重合并并移除LoRA层保存格式:合并后的模型保存为标准HuggingFace格式,可直接用于推…...

2025-5-15Vue3快速上手
1、setup和选项式API之间的关系 (1)vue2中的data,methods可以与vue3的setup共存 (2)vue2中的data可以用this读取setup中的数据,但是反过来不行,因为setup中的this是undefined (3)不建议vue2和vue3的语法混用…...

【金仓数据库征文】从生产车间到数据中枢:金仓数据库助力MES系统国产化升级之路
目录 前言一、金仓数据库:国产数据库的中坚力量二、制造业MES系统:数据驱动的生产智能MES系统的核心价值MES系统关键模块与数据库的关系1. BOM管理2. 生产工单与订单管理3. 生产排产与资源调度4. 生产报工与实时数据采集 5. 采购与销售管理 三、从MySQL到…...

HTML17:表单初级验证
表单初级验证 常用方式 placeholder 提示信息 <p>名字:<input type"text" name"username" maxlength"8" size"30" placeholder"请输入用户名"></p>required 非空判断 <p>名字:<input type"…...