CogACT实战:如何用DiT替换OpenVLA的动作预测模块提升机器人控制精度(附源码解析)

news2026/4/24 12:10:18
CogACT实战用DiT重构机器人动作预测从理论到代码的深度迁移指南如果你正在OpenVLA这类视觉-语言-动作模型上做机器人控制项目大概率遇到过这样的困扰模型对简单指令理解得不错但一到需要精细操作——比如把一根线穿进针眼或者把积木块精准地叠起来——动作输出就开始“飘”了精度总差那么一点。问题往往出在模型最后那一步把连续的、高维的、充满不确定性的机器人动作硬塞进一个为离散语言token设计的预测框架里。去年底清华、微软亚研院等机构联合提出的CogACT其核心思路直击了这个痛点用Diffusion Transformer完全替换掉OpenVLA里那个离散化的动作预测头。这不仅仅是换个模块那么简单它背后是一整套对机器人动作生成本质的重新思考——动作是连续、多模态且具有时间相关性的信号用扩散模型去建模其概率分布比用自回归预测离散token要自然得多。今天这篇文章我们不重复论文里的公式和图表而是直接切入工程现场。我会带你一步步拆解如何把OpenVLA的架构“手术”成CogACT的样式重点放在代码层面的关键改动、训练策略的调整以及在实际机器人仿真或实体上部署时那些容易踩坑的调优细节。无论你是想复现CogACT还是借鉴其思想改进自己的VLA模型这里都有可以直接抄作业的实操指南。1. 理解核心替换从离散Token到连续扩散在动手改代码之前我们必须先想清楚为什么这个替换是有效的以及它到底改变了什么。OpenVLA的动作预测瓶颈OpenVLA继承了RT-2的思路把机器人的7维动作三维平移、三维旋转、一个夹爪开合离散化成一个个token然后让语言模型像预测下一个单词一样自回归地预测这些动作token。这套方法在语义理解和指令跟随上表现惊艳因为它直接复用了大语言模型强大的序列建模能力。但机器人动作有其特殊性连续性机器人的关节角度、末端位姿是连续值。离散化必然引入量化误差就像用256色的调色板去画一幅真彩色的画细节总会丢失。多模态性完成同一个任务可能存在多条合理的动作轨迹。比如抓取一个杯子可以从左边绕过去抓也可以从右边。离散token的自回归预测通常倾向于输出概率最高的那一条容易忽略其他可行解。高精度要求毫米级的位姿误差就可能导致任务失败。离散区间的分辨率直接决定了动作精度的理论上限。DiT带来的范式转变Diffusion Transformer (DiT) 最初是为图像生成设计的但它建模连续、高维、多模态分布的能力恰好与机器人动作生成的需求完美匹配。直接处理连续信号DiT的输入和输出都是连续的向量无需经过离散化/反离散化过程从根本上避免了量化误差。隐式建模多模态分布扩散模型通过逐步去噪的过程可以从同一个噪声起点采样出属于不同模式的多样化解。这对应了机器人动作的多种可行方案。条件生成能力DiT可以通过交叉注意力Cross-Attention或特征拼接Conditional Embedding等方式将VLM输出的“认知特征”作为强条件引导动作的生成方向。这使得动作既符合物理规律又精准响应高级语义指令。用一个简单的比喻OpenVLA的动作预测像是一个翻译官它把“认知”翻译成一套预设的、离散的“动作单词表”。而CogACT的DiT模块更像是一个雕塑家它接收“认知”作为蓝图然后在一块连续的“动作原料”噪声上逐步雕刻出精细的、符合蓝图且具备多种可能形态的雕塑。注意替换动作预测模块并不意味着要重新训练整个庞大的VLM视觉-语言模块。CogACT的策略是冻结或微调预训练的VLM只端到端训练新引入的DiT动作模块以及连接部分的适配层。这大大降低了计算成本和数据需求。2. 工程准备环境、数据与基线模型在开始“手术”前确保你的实验环境是可控且可复现的。2.1 软件与硬件环境搭建你需要一个支持大规模Transformer训练的环境。以下是基于PyTorch的推荐配置# 基础环境 conda create -n cogact python3.10 conda activate cogact # 核心深度学习框架 pip install torch2.1.0 torchvision0.16.0 torchaudio2.1.0 --index-url https://download.pytorch.org/whl/cu118 # 替换cu118为你对应的CUDA版本 # 扩散模型相关 pip install diffusers transformers accelerate # 用于高效训练大模型 pip install deepspeed # 可选用于监控训练过程 pip install wandb tensorboard硬件方面至少需要一张显存 24GB 的GPU如RTX 4090, A5000, A100。由于要端到端训练DiT即使冻结VLM批量大小Batch Size也不能太小否则扩散模型难以收敛。多卡并行训练是更理想的选择。2.2 数据准备与预处理CogACT使用了Open X-Embodiment (OXE)数据集。对于大多数研究者和工程师从OXE中选取与你自己机器人形态相近的子集是关键。数据下载访问OXE项目页面下载你需要的.tfrecord文件。例如如果你研究机械臂抓取可以重点关注包含RT-1,Bridge V2,Language Table等数据。数据解析OXE数据是TFRecord格式。你需要将其转换为适合PyTorch DataLoader的格式。核心是提取每一帧的image: 相机观测图像 (通常resize到224x224或256x256)。language_instruction: 文本指令。action: 7维的动作向量[delta_x, delta_y, delta_z, delta_roll, delta_pitch, delta_yaw, gripper]。timestep: 时间步信息用于构建序列。构建数据管道一个高效的数据加载器至关重要因为OXE数据量巨大。建议使用torchdata或webdataset来构建流式数据管道避免将所有数据加载到内存。import torch from torch.utils.data import Dataset, DataLoader import tensorflow as tf # 用于解析tfrecord class OXEDataset(Dataset): def __init__(self, tfrecord_paths, image_size224): self.feature_description {...} # 定义tfrecord特征描述 self.dataset self._build_dataset(tfrecord_paths) self.image_size image_size def _parse_function(self, example_proto): # 解析单个example features tf.io.parse_single_example(example_proto, self.feature_description) image tf.image.decode_jpeg(features[image/encoded]) image tf.image.resize(image, [self.image_size, self.image_size]) action features[action] instruction features[language_instruction] return image, instruction, action def __getitem__(self, idx): # 返回处理后的图像、指令文本和动作 # 注意需要将文本指令token化 pass def __len__(self): pass2.3 获取并理解OpenVLA基线我们的改造起点是一个训练好的OpenVLA模型。你可以从Hugging Face Model Hub或官方仓库获取预训练权重。from transformers import AutoModelForCausalLM, AutoTokenizer, AutoImageProcessor import torch # 加载OpenVLA的视觉编码器和语言模型 vision_encoder ... # 通常是DINOv2 SigLIP的组合 text_tokenizer AutoTokenizer.from_pretrained(openvla/pretrained-model) language_model AutoModelForCausalLM.from_pretrained(openvla/pretrained-model) # 关键理解OpenVLA的输出结构 # OpenVLA在语言模型的最后隐藏层会输出一个“认知特征”向量对应论文中的cognition token # 我们需要截取这个特征作为DiT的条件输入。 cognition_feature language_model(...).last_hidden_state[:, -1, :] # 假设认知token在序列末尾花点时间阅读OpenVLA的推理代码明确cognition_feature是如何从图像和文本输入中产生的。这个特征向量将是连接VLM“大脑”和DiT“小脑”的桥梁。3. 核心改造集成DiT动作模块这是整个项目的核心环节。我们将构建DiT模块并把它“嫁接”到OpenVLA的视觉-语言骨干上。3.1 DiT模块的代码实现CogACT论文中使用的DiT是基于Peebles等人原始DiT的变体针对机器人动作序列预测做了调整。以下是一个高度简化的核心类实现突出了与标准DiT的不同之处import torch import torch.nn as nn import math class TimestepEmbedder(nn.Module): 将扩散步数编码为向量 def __init__(self, hidden_size, freq_embed_dim256): super().__init__() self.mlp nn.Sequential( nn.Linear(freq_embed_dim, hidden_size), nn.SiLU(), nn.Linear(hidden_size, hidden_size), ) self.freq_embed_dim freq_embed_dim staticmethod def timestep_embedding(t, dim, max_period10000): # 创建正弦位置编码 half dim // 2 freqs torch.exp(-math.log(max_period) * torch.arange(start0, endhalf, dtypetorch.float32) / half) args t[:, None].float() * freqs[None].to(t.device) embedding torch.cat([torch.cos(args), torch.sin(args)], dim-1) if dim % 2: embedding torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim-1) return embedding def forward(self, t): t_freq self.timestep_embedding(t, self.freq_embed_dim) t_emb self.mlp(t_freq) return t_emb class CogACTDiT(nn.Module): CogACT专用的DiT动作预测器 def __init__(self, action_dim7, hidden_size768, depth12, num_heads12, cond_dim4096, future_action_window15): super().__init__() self.action_dim action_dim self.future_window future_action_window self.cond_dim cond_dim # 嵌入层 self.x_embedder nn.Linear(action_dim, hidden_size) # 动作嵌入 self.t_embedder TimestepEmbedder(hidden_size) # 时间步嵌入 self.z_embedder nn.Linear(cond_dim, hidden_size) # 条件认知特征嵌入 # 位置编码1个条件token (未来动作窗口)个动作token self.pos_embed nn.Parameter(torch.randn(1 future_action_window, hidden_size) * 0.02) # DiT Blocks: 使用带条件的Transformer Block self.blocks nn.ModuleList([ DiTBlock(hidden_size, num_heads, mlp_ratio4.0) for _ in range(depth) ]) self.norm nn.LayerNorm(hidden_size, eps1e-6) self.linear nn.Linear(hidden_size, action_dim * 2) # 预测噪声和方差 def forward(self, noisy_actions, timesteps, cond_features): Args: noisy_actions: (B, T, action_dim) 带噪声的未来动作序列 timesteps: (B,) 扩散步数 cond_features: (B, cond_dim) 来自VLM的认知特征 Returns: pred: (B, T, action_dim*2) 预测的噪声和方差 B, T, _ noisy_actions.shape assert T self.future_window, f动作序列长度{T}与模型定义{self.future_window}不符 # 1. 嵌入 x self.x_embedder(noisy_actions) # (B, T, H) t self.t_embedder(timesteps) # (B, H) z self.z_embedder(cond_features) # (B, H) # 2. 组合token序列: [条件token, 动作token1, 动作token2, ...] # 将条件特征z加到时间嵌入t上作为序列的第一个token cond_token (z t).unsqueeze(1) # (B, 1, H) tokens torch.cat([cond_token, x], dim1) # (B, 1T, H) # 3. 添加位置编码并输入Transformer tokens tokens self.pos_embed for block in self.blocks: tokens block(tokens) tokens self.norm(tokens) # 4. 预测我们只关心动作token对应的输出 action_tokens tokens[:, 1:, :] # 去掉条件token pred self.linear(action_tokens) # (B, T, action_dim*2) # 拆分为噪声预测和方差预测 pred_noise, pred_variance torch.chunk(pred, 2, dim-1) return pred_noise, pred_variance class DiTBlock(nn.Module): 带自适应层归一化(AdaLN)的Transformer Block这是DiT的标准设计 def __init__(self, hidden_size, num_heads, mlp_ratio4.0): super().__init__() self.norm1 nn.LayerNorm(hidden_size, elementwise_affineFalse) self.attn nn.MultiheadAttention(hidden_size, num_heads, batch_firstTrue) self.norm2 nn.LayerNorm(hidden_size, elementwise_affineFalse) self.mlp Mlp(in_featureshidden_size, hidden_featuresint(hidden_size*mlp_ratio)) # AdaLN: 根据条件此处是时间步和认知特征的融合生成缩放和偏置参数 self.adaLN_modulation nn.Sequential( nn.SiLU(), nn.Linear(hidden_size, 6 * hidden_size, biasTrue) ) def forward(self, x): # x的形状: (B, L, H) B, L, H x.shape # 假设条件信息c已经通过其他方式传入在CogACTDiT的forward中已融入第一个token # 这里简化处理实际DiT的AdaLN需要从条件计算mod参数 # 为了清晰此处省略了AdaLN参数生成和应用的详细代码 shortcut x x self.norm1(x) x, _ self.attn(x, x, x) x shortcut x shortcut x x self.norm2(x) x self.mlp(x) x shortcut x return x关键点解析输入序列构造DiT的输入不再是单一的当前帧动作而是一个未来动作窗口例如15步。这强制模型学习动作的时间平滑性。条件注入方式CogACT没有采用DiT论文中常见的交叉注意力而是将VLM输出的认知特征与时间步嵌入相加作为一个特殊的cond_token拼接到动作token序列的最前面。这是一种更简洁有效的条件融合方式。输出目标模型预测的是添加到干净动作上的噪声以及可选的方差这是标准扩散模型的训练目标。3.2 替换OpenVLA的预测头现在我们需要将OpenVLA原有的动作预测头通常是一个线性层或小型MLP移除换上我们刚写好的CogACTDiT模块。假设我们有一个原始的OpenVLA模型类OpenVLAModelclass OpenVLAModelWithDiT(nn.Module): def __init__(self, vision_encoder, language_model, dit_config): super().__init__() self.vision_encoder vision_encoder # 冻结或微调 self.language_model language_model # 冻结或微调 self.cognition_proj nn.Linear(language_model.config.hidden_size, dit_config[cond_dim]) self.action_predictor CogACTDiT(**dit_config) # 冻结VLM参数可选推荐在初期微调时冻结 for param in self.vision_encoder.parameters(): param.requires_grad False for param in self.language_model.parameters(): param.requires_grad False def forward(self, images, instructions, noisy_actions, timesteps): # 1. 视觉编码 visual_features self.vision_encoder(images) # (B, num_patches, D_vis) # 2. 文本编码 text_inputs self.language_model.tokenizer(instructions, ...) text_features self.language_model(**text_inputs).last_hidden_state # (B, seq_len, D_text) # 3. 融合视觉与文本生成认知特征这里简化实际OpenVLA有更复杂的融合机制 # 假设我们取语言模型最后一个隐藏状态的特殊token作为认知特征 cognition_feature_raw text_features[:, -1, :] # (B, D_text) # 4. 投影到DiT条件维度 cond_features self.cognition_proj(cognition_feature_raw) # (B, cond_dim) # 5. DiT预测噪声 pred_noise, pred_var self.action_predictor(noisy_actions, timesteps, cond_features) return pred_noise, pred_var连接处的设计决策认知特征提取你需要仔细研究OpenVLA的源码找到它具体是使用哪个token的输出作为后续动作预测的条件。可能是语言模型输出的[CLS]token也可能是一个额外添加的可学习token。维度匹配cognition_proj线性层的作用是将VLM输出的特征维度例如4096映射到DiT条件嵌入的维度例如768。这个投影层是需要从头训练的。微调策略初期建议完全冻结VLM部分只训练cognition_proj和CogACTDiT。在足够数据上微调后可以考虑解冻VLM的最后几层进行联合微调以更好地对齐视觉-语言特征与动作空间。4. 训练、推理与调优实战模型结构搭好了接下来是让模型真正“学起来”和“用起来”的过程。4.1 扩散模型的训练循环训练一个扩散动作预测器与训练普通的监督学习模型有显著不同。你需要一个扩散调度器Scheduler来管理加噪和去噪过程。from diffusers import DDPMScheduler class CogACTTrainer: def __init__(self, model, optimizer, scheduler, device): self.model model.to(device) self.optimizer optimizer self.scheduler scheduler # 学习率调度器 self.noise_scheduler DDPMScheduler(num_train_timesteps1000, beta_schedulesquaredcos_cap_v2) self.device device def train_step(self, batch): images, instructions, true_actions batch # true_actions: (B, T, 7) B, T, _ true_actions.shape # 1. 为扩散过程准备噪声 noise torch.randn_like(true_actions) timesteps torch.randint(0, self.noise_scheduler.num_train_timesteps, (B,), deviceself.device).long() # 2. 根据时间步向真实动作添加噪声 noisy_actions self.noise_scheduler.add_noise(true_actions, noise, timesteps) # 3. 前向传播预测噪声 pred_noise, _ self.model(images, instructions, noisy_actions, timesteps) # 4. 计算损失预测噪声与真实噪声的均方误差 loss nn.functional.mse_loss(pred_noise, noise) # 5. 反向传播与优化 self.optimizer.zero_grad() loss.backward() torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm1.0) # 梯度裁剪 self.optimizer.step() self.scheduler.step() return loss.item()训练技巧损失函数扩散模型的标准损失是噪声预测的MSE。CogACT论文中也使用了此损失。梯度裁剪扩散模型训练可能不稳定梯度裁剪很重要。学习率使用Warmup和Cosine衰减调度器。初始学习率可以设得较低如2e-5。批量大小在GPU内存允许的情况下尽可能使用大的批量大小这对扩散模型的稳定训练有益。4.2 推理与自适应集成策略训练完成后在推理时我们需要运行完整的去噪采样过程。CogACT论文还提出了一个自适应动作集成策略来平滑多步预测并提高成功率。torch.no_grad() def sample_actions(self, images, instructions, num_inference_steps10, cfg_scale1.5): 使用DDIM采样器生成动作序列并应用自适应集成。 B images.shape[0] future_window self.model.action_predictor.future_window # 1. 初始化纯噪声动作序列 noisy_actions torch.randn((B, future_window, 7), deviceself.device) # 2. 获取认知特征条件 cond_features self.model.encode_condition(images, instructions) # 简化表示 # 3. DDIM采样循环 self.noise_scheduler.set_timesteps(num_inference_steps) for t in self.noise_scheduler.timesteps: # 分类器自由引导CFG if cfg_scale 1.0: # 拼接条件输入和无条件输入 uncond_features torch.zeros_like(cond_features) # 无条件用零向量 model_input torch.cat([noisy_actions] * 2) cond_input torch.cat([cond_features, uncond_features]) timesteps torch.cat([t.unsqueeze(0)] * 2 * B).to(self.device) pred_noise self.model.action_predictor(model_input, timesteps, cond_input) noise_pred_cond, noise_pred_uncond pred_noise.chunk(2) pred_noise noise_pred_uncond cfg_scale * (noise_pred_cond - noise_pred_uncond) else: pred_noise self.model.action_predictor(noisy_actions, t, cond_features) # 使用调度器更新 noisy_actions noisy_actions self.noise_scheduler.step(pred_noise, t, noisy_actions).prev_sample # 4. 采样得到去噪后的动作序列 denoised_actions: (B, future_window, 7) denoised_actions noisy_actions # 5. 自适应集成关键 # 假设我们有一个缓存存储了过去K步的预测结果 past_predictions (一个队列) # current_pred denoised_actions[:, 0, :] # 当前时刻的预测动作 # 计算当前预测与过去预测的余弦相似度作为权重 # final_action self._adaptive_integration(current_pred, past_predictions) # 更新缓存 # self._update_prediction_cache(denoised_actions) # 返回集成后的最终动作通常是序列的第一个动作用于当前执行 final_action denoised_actions[:, 0, :] return final_action def _adaptive_integration(self, current_pred, past_predictions, beta0.1): 论文中的公式(3)和(4) if len(past_predictions) 0: return current_pred # past_predictions: (K, action_dim) similarities F.cosine_similarity(current_pred.unsqueeze(0), past_predictions, dim1) # (K,) weights torch.softmax(similarities / beta, dim0) # (K,) # 加权平均 integrated_action torch.sum(weights.unsqueeze(1) * past_predictions, dim0) return integrated_action推理优化要点采样步数论文中使用10步DDIM采样在精度和速度间取得了良好平衡。你可以尝试减少到5步以加速推理但可能会牺牲一些性能。分类器自由引导cfg_scale是一个超参数用于控制条件生成的强度。论文中设为1.5。值太大会导致动作僵硬太小则可能忽略指令。自适应集成的窗口KK值需要根据机器人的运动速度调整。论文中提到他们根据训练数据的动作标准差来设定K如RT-1数据K2BridgeDataV2数据K7。这是一个非常实用的调参经验动作变化快的任务需要更小的集成窗口变化慢的则需要更大的窗口来平滑。4.3 性能评估与调试如何判断你的CogACT改造是否成功除了在标准测试集上跑成功率我强烈建议进行更细致的分析。设计对比实验基线对比在相同的数据和评估环境下对比原始OpenVLA和你改造后的CogACT-style模型。消融实验有无DiT将DiT模块换成一个与OpenVLA原预测头参数量相当的MLP验证DiT架构本身带来的增益。有无自适应集成关闭集成策略直接使用DiT预测的第一个动作观察成功率变化。条件注入方式尝试将认知特征通过交叉注意力注入DiT而不是作为第一个token比较效果。关键评估指标任务成功率在仿真或真实机器人上执行一系列指令化任务计算成功比例。动作平滑度计算相邻时间步动作之间的加速度或jerk加加速度值越低越平滑。轨迹多样性对于同一个起始状态和指令用不同的随机种子采样多次计算最终末端执行器位置的分布方差。方差越大说明模型捕捉的多模态性越好。常见问题与调试训练不收敛检查认知特征cond_features是否有效可以可视化其在不同任务下的分布。尝试降低学习率增加warmup步数。确保扩散噪声调度器的beta schedule设置合理。推理动作抖动增大自适应集成窗口K。检查cfg_scale是否过高。尝试在推理时使用更多的采样步数。模型过于保守可能是CFG权重太大或者训练数据中“失败”轨迹过多导致模型倾向于输出“安全”但无效的动作。可以尝试对训练数据进行清洗或调整损失函数的权重。5. 超越CogACT进阶思路与扩展当你成功复现了CogACT的基本效果后可以沿着以下几个方向进行更深度的探索和定制化改进。1. 更高效的DiT变体CogACT使用的是标准DiT-Base。你可以尝试更高效的架构如DiT-XL/XXL增加深度和宽度以换取更强的表达能力但计算成本也更高。U-ViT一种将Transformer与U-Net思想结合的架构在长序列建模上可能有优势。Latent DiT不在原始高维动作空间做扩散而是先通过一个VAE或自编码器将动作压缩到潜空间在潜空间进行扩散。这可以大幅降低计算量尤其当预测的动作窗口很长时。2. 多模态条件融合CogACT简单地将视觉-语言特征投影后作为条件。你可以设计更精细的融合机制分层条件将视觉特征、语言特征分别通过不同的投影层再输入到DiT的不同层中。跨注意力增强在DiT Block中引入额外的交叉注意力层让动作token直接与视觉或语言token进行交互。3. 面向具体任务的微调与蒸馏领域自适应如果你的机器人平台与OXE数据集中的形态差异很大例如你是足式机器人而OXE多是机械臂你需要在自己的数据上对模型进行微调。此时可以只微调DiT动作模块和最后的投影层VLM部分保持冻结这只需要相对少量的领域数据。知识蒸馏如果CogACT模型太大无法部署到边缘计算设备可以考虑用一个大CogACT模型作为教师蒸馏出一个小而快的学生模型例如用更小的DiT或MLP替代。4. 与规划模块结合CogACT是一个“反应式”的策略模型给定当前观测输出瞬时动作。你可以将其与一个更高层的任务规划器结合基于VLM的规划器用更大的VLM如GPT-4V生成高级任务分解“先移动到红色方块旁边再抓取它”。CogACT作为低层控制器接收规划器生成的子目标可能是图像描述或空间坐标输出具体的关节控制指令。改造OpenVLA的过程就像给一辆优秀的燃油车换上了一套更精准的电动驱动和线控转向系统。DiT模块的引入让机器人动作生成从“猜单词”变成了“精雕细琢”。在实际项目中我最大的体会是数据质量决定上限代码细节决定下限。OXE数据虽然规模庞大但噪声和不一致性也不少仔细的数据清洗和预处理能带来立竿见影的效果。而在代码层面认知特征提取的位置、DiT条件注入的方式、自适应集成的超参数这些看似微小的选择往往对最终性能有着不成比例的影响。多设置实验组用严谨的评估指标说话而不是仅仅盯着最终的成功率数字你才能真的理解每一个组件是如何起作用的。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…