【RL Latest Tech】分层强化学习:Option-Critic架构算法
📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:
【强化学习】(22)---《分层强化学习:Option-Critic架构算法》
分层强化学习:Option-Critic架构算法
目录
1. 基本概念
2. Option-Critic框架的核心要素
2.1 选项(Option)
2.2 Intra-Option Q-Learning
2.3 选项的终止条件
3. Option-Critic算法工作流程
[Python] Option-Critic实现
算法训练代码
测试和可视化代码
[Notice] 注意事项
4. Option-Critic的优势
5. 相关的挑战
6. 总结
分层强化学习(Hierarchical Reinforcement Learning, HRL)通过将复杂问题分解为更小的子问题,显著提高了强化学习算法在解决高维状态空间和长期目标任务中的效率。Option-Critic架构是分层强化学习中一种非常有影响力的方法,专门用于自动发现和优化子策略(称为“Option”)。它是在经典的Options框架基础上提出的,用来处理分层决策问题,特别是可以在没有明确的子目标定义的情况下自动学习子策略。

1. 基本概念
在Option-Critic架构中,最核心的思想是使用 “选项” 来建模高级行为策略。每个选项代表一段策略或行为,负责特定的子任务。具体地说,选项包括三个部分:
- 初始条件(Initiation set):智能体可以选择该选项的状态集合。
- 内部策略(Intra-option policy):智能体在选项激活时的行动策略,即在特定状态下采取的行动。
- 终止条件(Termination condition):定义选项何时终止或结束。
在这种架构下,智能体不再直接学习每个状态下的单一动作,而是学习 何时选择选项以及如何在选项内行动。这使得学习更加抽象化和高效化。
2. Option-Critic框架的核心要素
2.1 选项(Option)
- 选项 是智能体可以执行的一个序列动作,这些动作组成一个子策略。选项不仅包含具体的操作步骤,还包含 何时开始选项 以及 何时终止选项。
- 在每一个时间步,智能体可以选择:执行一个基础动作或选择一个更高级别的选项。在选项内,智能体执行动作直到达到终止条件,然后选择新的选项。
2.2 Intra-Option Q-Learning
Option-Critic框架引入了 Intra-Option Q-Learning 算法,用于更新选项的内部策略。在传统的强化学习中,Q-learning用于评估在特定状态下选择某个动作的价值。而在Option-Critic中,Intra-Option Q-Learning则用于评估 在选项内 如何选择动作。具体步骤如下:
- 对于每个选项,有一个内部策略
,它定义了在选项激活时的动作选择方式。
- Q函数
代表在状态
选择选项
的期望回报。
- 当智能体在执行选项时,内部策略根据当前状态选择具体动作,并且根据Intra-Option Q-Learning规则更新Q值。
2.3 选项的终止条件
选项的终止条件决定了何时退出当前选项并返回上层策略。例如,一个选项可能在达到某个目标状态时终止,或者在经过一定的时间步数后自动终止。终止条件的优化同样是Option-Critic框架中的一个关键部分。
3. Option-Critic算法工作流程
Option-Critic算法通过以下步骤完成学习过程:
- 选项初始化:初始化选项的初始条件、内部策略和终止条件。
- 执行过程:
- 智能体基于当前状态和Q值函数选择某个选项。
- 执行选项的内部策略,在环境中采取具体行动,直到终止条件触发。
- Q值更新:使用Intra-Option Q-Learning更新每个选项的Q值函数。
- 策略更新:同时更新选项的内部策略和终止条件,使得智能体能够更好地进行决策。
- 重复以上过程,直至收敛。
[Python] Option-Critic实现
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
Option-Critic架构在CartPole环境中的Python代码,使用了OpenAI Gym和PyTorch进行实现。
步骤:
- 设置 CartPole 环境。
- 定义选项的策略网络。
- 定义用于估计每个选项值的Q 网络。
- 实现选项内策略梯度和终止梯度。
- 创建经验回放缓冲区,用于存储和采样经验。
- 使用时间差分学习和策略梯度训练智能体。
- 测试和可视化智能体的表现。
算法训练代码
"""《Option-Critic实现》时间:2024.10.01环境:CartPole 作者:不去幼儿园
"""
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from collections import deque
import random# 超参数调整
GAMMA = 0.98 # 稍微减少折扣因子,减少远期奖励影响
LEARNING_RATE = 0.0005 # 降低学习率,提高训练的稳定性
BATCH_SIZE = 128 # 增加批次大小以稳定训练
MEMORY_SIZE = 20000 # 增大经验回放缓冲区
EPSILON_DECAY = 0.99 # 减慢 epsilon 的衰减速度
MIN_EPSILON = 0.05 # 增大最小 epsilon,保持一定探索
NUM_OPTIONS = 2
NUM_EPISODES = 1000 # 增加训练回合数# 修改后的网络结构
class CriticNetwork(nn.Module):def __init__(self, state_dim, num_options):super(CriticNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加隐藏层神经元数量self.fc2 = nn.Linear(256, num_options)def forward(self, state):x = torch.relu(self.fc1(state))return self.fc2(x)class IntraOptionPolicyNetwork(nn.Module):def __init__(self, state_dim, num_options, action_dim):super(IntraOptionPolicyNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加神经元数量self.fc2 = nn.Linear(256, num_options * action_dim)self.num_options = num_optionsself.action_dim = action_dimdef forward(self, state, option):x = torch.relu(self.fc1(state))policy_logits = self.fc2(x)option_policy = policy_logits.view(-1, self.num_options, self.action_dim)return option_policy[:, option, :]class TerminationNetwork(nn.Module):def __init__(self, state_dim, num_options):super(TerminationNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加神经元数量self.fc2 = nn.Linear(256, num_options)def forward(self, state):x = torch.relu(self.fc1(state))termination_probs = torch.sigmoid(self.fc2(x))return termination_probs# 经验回放缓冲区
class ReplayBuffer:def __init__(self, capacity):self.buffer = deque(maxlen=capacity)def push(self, state, option, action, reward, next_state, done):self.buffer.append((state, option, action, reward, next_state, done))def sample(self, batch_size):states, options, actions, rewards, next_states, dones = zip(*random.sample(self.buffer, batch_size))return np.stack(states), options, actions, rewards, np.stack(next_states), donesdef size(self):return len(self.buffer)# 选择动作
def select_action(policy_net, state, option, epsilon):if random.random() < epsilon:return random.choice([0, 1]) # CartPole 动作空间为 2(0 或 1)else:state = torch.FloatTensor(state).unsqueeze(0)action_probs = torch.softmax(policy_net(state, option), dim=-1)return torch.argmax(action_probs).item()# Option-Critic 智能体
class OptionCriticAgent:def __init__(self, state_dim, action_dim, num_options):self.policy_net = IntraOptionPolicyNetwork(state_dim, num_options, action_dim)self.q_net = CriticNetwork(state_dim, num_options)self.termination_net = TerminationNetwork(state_dim, num_options)self.optimizer_policy = optim.Adam(self.policy_net.parameters(), lr=LEARNING_RATE)self.optimizer_q = optim.Adam(self.q_net.parameters(), lr=LEARNING_RATE)self.optimizer_term = optim.Adam(self.termination_net.parameters(), lr=LEARNING_RATE)self.epsilon = 1.0self.num_options = num_optionsself.memory = ReplayBuffer(MEMORY_SIZE)def train(self, batch_size):if self.memory.size() < batch_size:returnstates, options, actions, rewards, next_states, dones = self.memory.sample(batch_size)states = torch.FloatTensor(states)next_states = torch.FloatTensor(next_states)rewards = torch.FloatTensor(rewards)options = torch.LongTensor(options)actions = torch.LongTensor(actions)dones = torch.FloatTensor(dones)# 更新 Q 函数q_values = self.q_net(states)next_q_values = self.q_net(next_states).detach()target_q_values = rewards + GAMMA * next_q_values.max(1)[0] * (1 - dones)loss_q = nn.functional.mse_loss(q_values.gather(1, options.unsqueeze(1)).squeeze(), target_q_values)self.optimizer_q.zero_grad()loss_q.backward()self.optimizer_q.step()# 更新选项内策略for option in range(self.num_options):policy_logits = self.policy_net(states, option)action_probs = torch.softmax(policy_logits, dim=-1)log_action_probs = torch.log(action_probs)policy_loss = -log_action_probs.gather(1, actions.unsqueeze(1)).mean()self.optimizer_policy.zero_grad()policy_loss.backward()self.optimizer_policy.step()# 更新终止概率terminations = self.termination_net(states)termination_loss = nn.functional.binary_cross_entropy(terminations.gather(1, options.unsqueeze(1)).squeeze(),dones)self.optimizer_term.zero_grad()termination_loss.backward()self.optimizer_term.step()def remember(self, state, option, action, reward, next_state, done):self.memory.push(state, option, action, reward, next_state, done)# 训练智能体
env = gym.make('CartPole-v1')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.nagent = OptionCriticAgent(state_dim, action_dim, NUM_OPTIONS)for episode in range(NUM_EPISODES):state, _ = env.reset()option = random.choice(range(NUM_OPTIONS)) # 随机选择一个选项done = Falseepisode_reward = 0while not done:action = select_action(agent.policy_net, state, option, agent.epsilon)next_state, reward, done, _, __ = env.step(action)agent.remember(state, option, action, reward, next_state, done)agent.train(BATCH_SIZE)# 选项终止时选择新选项if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(NUM_OPTIONS))state = next_stateepisode_reward += rewardagent.epsilon = max(MIN_EPSILON, agent.epsilon * EPSILON_DECAY)print(f"Episode {episode + 1}: Total Reward: {episode_reward}")env.close()# Option-Critic 智能体
class OptionCriticAgent:def __init__(self, state_dim, action_dim, num_options):self.policy_net = IntraOptionPolicyNetwork(state_dim, num_options, action_dim)self.q_net = CriticNetwork(state_dim, num_options)self.termination_net = TerminationNetwork(state_dim, num_options)self.optimizer_policy = optim.Adam(self.policy_net.parameters(), lr=LEARNING_RATE)self.optimizer_q = optim.Adam(self.q_net.parameters(), lr=LEARNING_RATE)self.optimizer_term = optim.Adam(self.termination_net.parameters(), lr=LEARNING_RATE)self.epsilon = 1.0self.num_options = num_optionsself.memory = ReplayBuffer(MEMORY_SIZE)def train(self, batch_size):if self.memory.size() < batch_size:returnstates, options, actions, rewards, next_states, dones = self.memory.sample(batch_size)states = torch.FloatTensor(states)next_states = torch.FloatTensor(next_states)rewards = torch.FloatTensor(rewards)options = torch.LongTensor(options)actions = torch.LongTensor(actions)dones = torch.FloatTensor(dones)# 更新 Q 函数q_values = self.q_net(states)next_q_values = self.q_net(next_states).detach()target_q_values = rewards + GAMMA * next_q_values.max(1)[0] * (1 - dones)loss_q = nn.functional.mse_loss(q_values.gather(1, options.unsqueeze(1)).squeeze(), target_q_values)self.optimizer_q.zero_grad()loss_q.backward()self.optimizer_q.step()# 更新选项内策略for option in range(self.num_options):policy_logits = self.policy_net(states, option)action_probs = torch.softmax(policy_logits, dim=-1)log_action_probs = torch.log(action_probs)policy_loss = -log_action_probs.gather(1, actions.unsqueeze(1)).mean()self.optimizer_policy.zero_grad()policy_loss.backward()self.optimizer_policy.step()# 更新终止概率terminations = self.termination_net(states)termination_loss = nn.functional.binary_cross_entropy(terminations.gather(1, options.unsqueeze(1)).squeeze(),dones)self.optimizer_term.zero_grad()termination_loss.backward()self.optimizer_term.step()def remember(self, state, option, action, reward, next_state, done):self.memory.push(state, option, action, reward, next_state, done)# 在 CartPole 环境中训练智能体
env = gym.make('CartPole-v1')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.nagent = OptionCriticAgent(state_dim, action_dim, NUM_OPTIONS)for episode in range(NUM_EPISODES):state, _ = env.reset()option = random.choice(range(NUM_OPTIONS)) # 初始化为随机选项done = Falseepisode_reward = 0while not done:action = select_action(agent.policy_net, state, option, agent.epsilon)next_state, reward, done, _, __ = env.step(action)agent.remember(state, option, action, reward, next_state, done)agent.train(BATCH_SIZE)if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(NUM_OPTIONS)) # 终止当前选项并选择新选项state = next_stateepisode_reward += rewardagent.epsilon = max(MIN_EPSILON, agent.epsilon * EPSILON_DECAY)print(f"Episode {episode + 1}: Total Reward: {episode_reward}")env.close()
测试和可视化代码
要在 CartPole 环境中测试 Option-Critic 模型并显示动画,需要利用 gym 库中的 render() 方法。以下代码演示了如何在训练完模型后进行测试,并实时显示动画。
import gym
import torch# 测试 Option-Critic 模型并显示动画
def test_option_critic(agent, env, num_episodes=5):for episode in range(num_episodes):state, _ = env.reset()option = random.choice(range(agent.num_options)) # 随机选择一个选项done = Falseepisode_reward = 0env.render() # 初始化渲染环境while not done:env.render() # 渲染环境,显示动画action = select_action(agent.policy_net, state, option, epsilon=0.0) # 使用已学策略选择动作next_state, reward, done, _, __ = env.step(action)# 检查选项是否应终止,并在终止时重新选择新选项if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(agent.num_options))state = next_stateepisode_reward += rewardprint(f"测试 Episode {episode + 1}: Total Reward: {episode_reward}")env.close()# 创建 CartPole 环境并调用测试函数
env = gym.make('CartPole-v1', render_mode='human')
test_option_critic(agent, env)
[Notice] 注意事项
确保您使用的环境和库版本支持 render_mode 参数。如果使用的 Gym 版本较旧,可能不支持此选项。在这种情况下,建议更新 gym 库。
上述采用的是gym == 0.26.2
pip install --upgrade gym
注意 :env.step(action)的返回参数数量,多则删除__
由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳,一是算法不适配上述环境,二是算法未调参和优化,三是等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
4. Option-Critic的优势
Option-Critic架构的优点主要体现在以下几方面:
- 层次化决策:通过分层的结构,智能体能够进行更高级别的决策,不必在每一步都从头开始学习。
- 策略的可重用性:通过选项,智能体可以学习可重复使用的策略片段,用于不同的任务场景。
- 提升效率:在复杂任务中,分层策略减少了动作空间的复杂度,使得学习过程更加高效。
5. 相关的挑战
尽管Option-Critic架构在理论上具备优势,但在实际应用中仍面临一些挑战:
- 选项的设计与优化:选择合适的选项数量和复杂度对于模型性能有很大影响。
- 探索与利用的平衡:在不同的选项之间,如何平衡探索新选项与利用已有的选项是一个难题。
- 终止条件的优化:如何合理地学习选项的终止条件,避免选项过早或过晚终止,同样是一个挑战。
6. 总结
Option-Critic架构通过引入 选项 这一中间层次,将复杂问题分解为多个子任务,并通过学习这些子任务的策略与终止条件来实现有效的分层强化学习。它是一种非常有前景的强化学习框架,适用于处理复杂、长期依赖的任务。
参考文献
Bacon, P.-L., Harb, J., & Precup, D. (2017). The Option-Critic Architecture. Proceedings of the 31st AAAI Conference on Artificial Intelligence (AAAI-17).
完整项目代码:
【RL Latest Tech】分层强化学习:Option-Critic架构算法项目代码实现
Option-Critic架构通过整合选项策略和Q学习算法,提供了一种优雅的解决方案,使得智能体能够高效地在复杂环境中进行学习和决策。
文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者关注VX公众号:Rain21321,联系作者。✨
相关文章:
【RL Latest Tech】分层强化学习:Option-Critic架构算法
📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在…...
分布式数据库
前言 分布式数据库系统(DDBS)包含分布式数据库管理系统(DDBMS)和分布式数据库(DDB)。在分布式数据库系统中,一个应用程序可以对数据库进行透明操作,数据库中的数据分别在不同的…...
MySQL(2)【库的操作】
阅读导航 引言一、创建数据库1. 基本语法2. 创建数据库案例📌创建名为db1的数据库📌创建一个使用utf8字符集的db2数据库📌创建一个使用utf8字符集,并带校对规则的db3数据库 二、字符集和校验规则1. 查看系统默认字符集以及校验规则…...
python pip更换(切换)国内镜像源
国内镜像源列表(个人推荐清华大学的源) 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple阿里云: http://mirrors.aliyun.com/pypi/simple豆瓣: http://pypi.douban.com/simple中国科技大学: https://pypi.mirrors.ustc.e…...
阿里云镜像源无法访问?使用 DaoCloud 镜像源加速 Docker 下载(Linux 和 Windows 配置指南)
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCode💫 Gitee …...
使用 BERT 和逻辑回归进行文本分类及示例验证
使用 BERT 和逻辑回归进行文本分类及示例验证 一、引言 在自然语言处理领域中,文本分类是一项至关重要的任务。本文将详细介绍如何结合 BERT 模型与逻辑回归算法来实现文本分类,并通过实际示例进行验证。 二、环境准备 为了运行本文中的代码…...
【skywalking 】监控 Spring Cloud Gateway 数据
使用Spring Cloud 开发,用Skywalking 监控服务,但是Skywalking 默认是不支持 Spring Cloud Gateway 网关服务的,需要手动将 Gateway 的插件添加到 Skywalking 启动依赖 jar 中。 skywalking相关版本信息 jdk:17skywalking&#x…...
SpringWeb
SpringWeb SpringWeb 概述 SpringWeb 是 spring 框架中的一个模块,基于 Servlet API 构建的 web 框架. springWeb 是 Spring 为 web 层开发提供的一整套完备的解决方案。 在 web 层框架历经 Strust1,WebWork,Strust2 等诸多产品的历代更…...
嵌入式刷题(day21)
MySQL和sqlite的区别 MySQL和SQLite是两种常见的关系型数据库管理系统(RDBMS),但它们在特性、使用场景和架构方面有显著的区别: 1. 架构 MySQL:是一个基于服务器的数据库系统,遵循客户端-服务器架构。MySQL服务器运行在主机上,客户端通过网络连接并发送查询。它可以并…...
OpenAI 下一代旗舰模型现身?奥尔特曼亲自辟谣“猎户座“传闻
在人工智能领域最受瞩目的ChatGPT即将迎来两周岁之际,一场关于OpenAI新旗舰模型的传闻再次引发业界热议。然而,这场喧嚣很快就被OpenAI掌门人奥尔特曼亲自澄清。 事件源于科技媒体The Verge的一则报道。据多位知情人士透露,OpenAI可能会在11…...
【C++】STL初识
【C】STL初识 文章目录 【C】STL初识前言一、STL基本概念二、STL六大组件简介三、STL三大组件四、初识STL总结 前言 本篇文章将讲到STL基本概念,STL六大组件简介,STL三大组件,初识STL。 一、STL基本概念 STL(Standard Template Library,标准…...
框架篇补充(东西多 需要重新看网课)
什么是AOP 面向切面编程 降低耦合 提高代码的复用 Spring的bean的生命周期 实例化bean 赋值 初始化bean 使用bean 销毁bean SpringMVC的执行流程 Springboot自动装配原理 实际上就是为了从spring.factories文件中 获取到对应的需要 进行自动装配的类 并生成相应的Bean…...
合约门合同全生命周期管理系统:企业合同管理的数字化转型之道
合约门合同全生命周期管理系统:企业合同管理的数字化转型之道 1. 引言 在现代企业中,合同管理已经不再是简单的文件存储和审批流程,而是企业合规性、风险管理和业务流程的关键环节之一。随着企业规模的扩大和合同数量的增加,传统…...
等保测评与风险管理:识别、评估和缓解潜在的安全威胁
在信息化时代,数据已成为企业最宝贵的资产之一,而信息安全则成为守护这份资产免受侵害的重中之重。等保测评(信息安全等级保护测评)作为保障信息系统安全的重要手段,其核心在于通过科学、规范、专业的评估手段…...
Golang Agent 可观测性的全面升级与新特性介绍
作者:张海彬(古琦) 背景 自 2024 年 6 月 26 日,ARMS 发布了针对 Golang 应用的可观测性监控功能以来,阿里云 ARMS 团队与程序语言与编译器团队一直致力于不断优化和提升该系统的各项功能,旨在为开发者提…...
SpringBoot的开篇 特点 初始化 ioc 配置文件
文章目录 前言SpringBoot发展历程SpringBoot前置准备SpringBoot特点 SpringBoot项目初始化项目启动Springboot的核心概念IOC概念介绍Bean对象通过注解扫描包 例子配置文件 前言 SpringBoot发展历程 最初,Spring框架的使用需要大量的XML配置,这使得开发…...
docker 可用镜像服务地址(2024.10.25亲测可用)
1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因:镜像服务器地址不可用。 2.可用地址 编辑daemon.json: vi /etc/docker/daemon.json内容修改如下: {"registry-mirrors": ["https://…...
【SQL实验】表的更新和简单查询
完整代码在文章末尾 在上次实验创建的educ数据库基础上,用SQL语句为student表、course表和sc表中添加以下记录 【SQL实验】数据库、表、模式的SQL语句操作_创建一个名为educ数据库,要求如下: (下面三个表中属性的数据类型需要自己设计合适-CSDN博客在这篇博文中已经…...
【C++】 string的了解及使用
标准库中的string类 在使用string类时,必须包含#include头文件以及using namespace std; string类的常用接口说明 C中string为我们提供了丰富的接口来供我们使用 – string接口文档 这里我们只介绍一些常见的接口 string类对象的常见构造 #include <iostrea…...
【K8S】kubernetes-dashboard.yaml
https://raw.githubusercontent.com/kubernetes/dashboard/v3.0.0-alpha0/charts/kubernetes-dashboard.yaml 以下链接的内容: 由于国内访问不了,找到一些方法下载了这个文件内容, 部署是mages 对象的镜像 WEB docker.io/kubernetesui/dash…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
