从PyTorch到RV1126:ResNet50边缘AI模型完整部署实战指南

news2026/5/20 13:54:15
1. 项目概述从边缘AI的“芯”需求到RV1126的实战定位最近几年边缘计算的火热程度有目共睹尤其是在安防监控、智能门禁、工业质检这些对实时性、隐私性和成本都极其敏感的领域。大家不再满足于把海量视频流、图像数据一股脑儿往云端传而是希望设备自己就能“看懂”画面做出判断。这就对部署在设备端的AI模型提出了硬性要求既要足够“聪明”识别准确又要足够“轻快”能在资源有限的嵌入式芯片上跑起来。瑞芯微的RV1126芯片就是为这个场景量身定制的典型代表。它集成了独立的NPU神经网络处理单元算力虽然比不上动辄几十T的服务器显卡但应付像ResNet50这样的经典图像分类网络在边缘端进行实时推理完全是绰绰有余。我手头正好有一块基于RV1126的开发板这次的目标很明确不是简单地跑个现成的模型而是从零开始完成一个ResNet50模型在RV1126上的完整生命周期——包括数据准备、模型训练、量化转换、交叉编译直到最终在开发板上部署并验证效果。为什么是ResNet50因为它太经典了。作为图像识别领域的里程碑式网络其残差结构有效解决了深层网络的梯度消失问题在ImageNet等大型数据集上表现优异。虽然现在有更多轻量级网络如MobileNet, ShuffleNet但ResNet50的结构清晰、生态完善作为学习边缘AI部署的“第一课”能让你透彻理解从训练框架到推理引擎的每一个环节。当你掌握了ResNet50的完整流程再去折腾其他模型就会有一种“一览众山小”的通透感。这个教程适合谁如果你是嵌入式工程师想给产品加上“AI眼睛”如果你是算法工程师想了解模型如何落地到真实硬件或者你是一名学生、爱好者对边缘AI充满好奇那么这个从训练到部署的完整路径将是一份不可多得的实战指南。我会尽量把每个步骤的“为什么”讲清楚并分享那些官方文档里不会写的“踩坑”经验。2. 核心思路与工具链选型构建高效可靠的部署流水线在开始动手之前我们必须先搭好“舞台”也就是确定整个项目的技术栈和工作流。边缘AI部署不是一个单点任务而是一条环环相扣的流水线任何一个环节的工具选型不当都可能导致后续步骤失败。2.1 训练框架PyTorch的灵活性与生态优势模型训练方面我选择了PyTorch。相较于其他框架PyTorch的动态图机制对研究和实验更加友好调试直观。更重要的是其庞大的社区和丰富的模型库TorchVision让我们能轻松获取ResNet50的预训练模型这对于在自定义数据集上进行迁移学习至关重要能极大减少训练时间和数据需求。注意虽然RV1126的官方SDK对TensorFlow、Caffe等框架也有一定支持但PyTorch通过ONNX中间格式转换的路径是目前最通用、社区资源最丰富的路线。选择PyTorch意味着你未来部署其他模型时能获得更广泛的支持。2.2 模型转换核心ONNX与RKNN-Toolkit2这是连接训练框架和嵌入式芯片的关键桥梁。ONNXOpen Neural Network Exchange我们的第一步是将训练好的PyTorch模型.pth文件导出为标准化的ONNX格式。ONNX就像一个“通用翻译官”它定义了一种与框架和硬件无关的模型表示格式使得PyTorch模型能够被其他推理引擎识别。RKNN-Toolkit2这是瑞芯微官方提供的核心工具包。它的任务是将ONNX模型“翻译”成RV1126 NPU能够高效执行的RKNN格式模型。这个过程不仅仅是格式转换更包含了模型量化、算子兼容性检查、性能分析等核心步骤。Toolkit2提供了Python API允许我们在x86开发机上模拟NPU的运行环境预先验证模型转换和推理的正确性这对提高开发效率至关重要。2.3 开发与部署环境宿主机与目标板协同我们需要两个环境宿主机开发机一台安装Ubuntu 18.04/20.04的x86电脑。在这里我们将完成模型训练、ONNX导出、RKNN模型转换和交叉编译。宿主机需要安装PyTorch、RKNN-Toolkit2、交叉编译工具链等复杂软件。目标板RV1126开发板。这是模型最终运行的舞台。板上运行着一个精简的Linux系统我们通过交叉编译好的可执行文件或Python脚本调用RKNN模型进行推理。这种“宿主机开发目标板运行”的模式是嵌入式开发的常态。清晰地区分两者能避免很多环境混淆导致的错误。2.4 整体工作流梳理整个项目的流水线可以清晰地分为五个阶段下图展示了从数据到落地应用的完整闭环flowchart TD A[准备自定义数据集] -- B[使用PyTorch训练/微调ResNet50模型] B -- C[导出模型为ONNX格式] C -- D[使用RKNN-Toolkit2量化转换为RKNN模型] D -- E{模型验证} E -- 宿主机仿真验证 -- F[在开发机利用RKNN-Toolkit2仿真推理] E -- 交叉编译与部署 -- G[交叉编译C/Python推理程序] F -- H[性能与精度分析] G -- I[部署至RV1126开发板] H -- J[最终在边缘设备实现实时图像分类] I -- J3. 实战第一步PyTorch环境搭建与模型训练理论清晰了我们开始动手。首先在宿主机上搭建训练环境。3.1 创建并配置Python虚拟环境强烈建议使用虚拟环境避免包版本冲突。# 安装虚拟环境工具如果未安装 sudo apt-get install python3-venv # 创建名为‘rv1126_resnet’的虚拟环境 python3 -m venv rv1126_resnet # 激活虚拟环境 source rv1126_resnet/bin/activate激活后命令行提示符前会出现(rv1126_resnet)字样。3.2 安装PyTorch与依赖根据你的CUDA版本如果使用GPU训练去PyTorch官网获取安装命令。这里以CPU版本为例训练较慢建议有条件的用GPUpip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu pip install onnx onnx-simplifier # 用于后续模型导出 pip install opencv-python pillow pandas matplotlib # 数据处理和可视化常用库3.3 准备自定义数据集ResNet50原本是在ImageNet1000类上训练的。我们通常需要针对特定场景如识别不同种类的工业零件、花卉进行微调Fine-tuning。数据组织采用ImageFolder要求的格式。假设你的项目是“水果分类”数据集目录结构应如下fruits_dataset/ ├── train/ │ ├── apple/ │ │ ├── apple001.jpg │ │ └── ... │ ├── banana/ │ └── orange/ └── val/ # 验证集结构同train数据增强为了提升模型泛化能力防止过拟合必须对训练集进行增强。使用torchvision.transforms可以轻松实现。from torchvision import transforms # 训练集的数据增强和归一化使用ImageNet的均值和标准差 train_transform transforms.Compose([ transforms.RandomResizedCrop(224), # ResNet50标准输入尺寸 transforms.RandomHorizontalFlip(), transforms.ColorJitter(brightness0.2, contrast0.2), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) # 验证集只需调整尺寸和归一化无需增强 val_transform transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])3.4 模型微调训练这里我们加载预训练模型只替换最后的全连接层并对所有参数进行微调。import torch import torch.nn as nn import torch.optim as optim from torchvision import models, datasets from torch.utils.data import DataLoader # 1. 加载数据 train_dataset datasets.ImageFolder(fruits_dataset/train, transformtrain_transform) val_dataset datasets.ImageFolder(fruits_dataset/val, transformval_transform) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse) # 2. 加载预训练模型并修改最后一层 model models.resnet50(pretrainedTrue) num_ftrs model.fc.in_features # 获取原全连接层输入特征数 model.fc nn.Linear(num_ftrs, len(train_dataset.classes)) # 替换为新的全连接层输出类别数为我们的水果种类数 # 3. 定义损失函数和优化器 criterion nn.CrossEntropyLoss() # 所有参数都参与训练 optimizer optim.SGD(model.parameters(), lr0.001, momentum0.9) # 4. 训练循环简略框架需补充完整epoch循环和验证逻辑 device torch.device(cuda:0 if torch.cuda.is_available() else cpu) model.to(device) for epoch in range(10): # 训练10个epoch model.train() running_loss 0.0 for inputs, labels in train_loader: inputs, labels inputs.to(device), labels.to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() print(fEpoch {epoch1}, Loss: {running_loss/len(train_loader)}) # 每个epoch后在验证集上评估准确率...训练完成后保存模型权重torch.save(model.state_dict(), resnet50_fruits.pth)实操心得对于边缘部署我们不一定需要追求极致的准确率。如果验证集准确率已经达到95%以上且不再显著提升就可以考虑停止训练。过度的训练可能导致模型复杂化不利于后续的量化与部署。4. 模型转换与量化从PyTorch到RV1126的“瘦身之旅”训练好的模型是浮点数FP32格式直接在资源受限的RV1126上运行效率低、内存占用大。因此量化是边缘部署的核心步骤它能将模型从FP32转换为INT8等低精度格式大幅减少模型体积和提升推理速度而精度损失在可控范围内。4.1 导出ONNX模型首先将训练好的PyTorch模型导出为ONNX格式。这里有一个关键点需要提供示例输入dummy input来定义网络的输入维度。import torch import onnx # 加载训练好的模型权重 model.load_state_dict(torch.load(resnet50_fruits.pth)) model.eval() # 设置为评估模式 # 创建示例输入batch_size1, channel3, height224, width224 dummy_input torch.randn(1, 3, 224, 224) # 导出ONNX模型 input_names [input] output_names [output] torch.onnx.export(model, dummy_input, resnet50_fruits.onnx, export_paramsTrue, opset_version11, # 建议使用11或12兼容性较好 do_constant_foldingTrue, input_namesinput_names, output_namesoutput_names, dynamic_axes{input: {0: batch_size}, # 支持动态batch output: {0: batch_size}})导出后可以使用onnx.checker.check_model和onnx.helper.printable_graph来检查模型结构是否正确。4.2 安装与配置RKNN-Toolkit2前往瑞芯微官方GitHub仓库下载对应版本的RKNN-Toolkit2。安装过程可能有依赖冲突需仔细阅读官方文档。# 示例安装命令具体版本请以官方为准 pip install packages/rknn_toolkit2-1.x.x-cp38-cp38-linux_x86_64.whl安装完成后在Python中导入测试from rknn.api import RKNN如果没有报错说明安装成功。4.3 使用RKNN-Toolkit2进行量化转换这是最核心的一步我们将ONNX模型转换为RKNN模型并执行量化。# 创建RKNN对象 rknn RKNN(verboseTrue) # 模型配置 print(-- Config model) rknn.config(mean_values[[123.675, 116.28, 103.53]], # ImageNet的均值需根据你的数据调整 std_values[[58.395, 57.12, 57.375]], # ImageNet的标准差 quant_img_RGB2BGRTrue, # 如果你的图像输入是RGB但模型需要BGR这里可以转换 target_platformrv1126) # 指定目标平台 # 加载ONNX模型 print(-- Loading model) ret rknn.load_onnx(modelresnet50_fruits.onnx) if ret ! 0: print(Load model failed!) exit(ret) # 构建模型这一步会进行量化 print(-- Building model) ret rknn.build(do_quantizationTrue, # 开启量化 dataset./dataset.txt) # 量化校准数据集路径 if ret ! 0: print(Build model failed!) exit(ret) # 导出RKNN模型文件 print(-- Export rknn model) ret rknn.export_rknn(./resnet50_fruits.rknn) if ret ! 0: print(Export rknn model failed!) exit(ret) # 释放RKNN上下文 rknn.release()关键点解析dataset.txt这是一个文本文件里面列出了几十到几百张用于量化校准的图片路径。这些图片必须来自你的验证集或训练集用于统计每一层激活值的分布范围从而确定量化参数。这是影响量化后模型精度的最重要因素。mean_values和std_values必须与模型训练时使用的归一化参数完全一致。这里使用的是ImageNet的标准参数如果你训练时改了这里也要同步修改。4.4 在宿主机上进行仿真推理预验证在部署到板子之前先用RKNN-Toolkit2的仿真功能在x86电脑上跑一遍验证转换后的模型是否能正确推理。# 初始化RKNN对象 rknn RKNN() # 加载RKNN模型 print(-- Load RKNN model) ret rknn.load_rknn(resnet50_fruits.rknn) if ret ! 0: print(Load RKNN model failed!) exit(ret) # 初始化运行时环境这里使用‘rknn’模拟NPU print(-- Init runtime environment) ret rknn.init_runtime(targetrknn) # 注意仿真时targetrknn if ret ! 0: print(Init runtime environment failed!) exit(ret) # 准备输入数据需要做同样的预处理 import cv2 import numpy as np img cv2.imread(test_apple.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转为RGB img cv2.resize(img, (224, 224)) img (img - [123.675, 116.28, 103.53]) / [58.395, 57.12, 57.375] # 归一化 img np.expand_dims(img, 0).astype(np.float32) # 增加batch维度 # 执行推理 print(-- Running model) outputs rknn.inference(inputs[img]) print(Simulation inference output:, outputs) # 后处理例如取softmax得到概率 probabilities np.exp(outputs[0]) / np.sum(np.exp(outputs[0])) predicted_class np.argmax(probabilities) print(fPredicted class index: {predicted_class}, Prob: {probabilities[predicted_class]:.4f}) rknn.release()如果仿真结果与PyTorch模型在相同输入下的输出基本一致允许有微小误差说明模型转换成功。5. 交叉编译与RV1126板端部署模型在宿主机上验证通过后就要准备“上板”了。我们需要编写在RV1126上运行的推理代码并在宿主机上交叉编译。5.1 准备RV1126的交叉编译工具链从瑞芯微官方SDK中获取针对RV1126的交叉编译工具链通常是arm-rockchip830-linux-uclibcgnueabihf-前缀。将其路径加入系统环境变量。# 解压工具链 tar -xvf gcc-arm-xxx.tar.gz # 添加环境变量可写入~/.bashrc export PATH/your/path/to/gcc-arm-xxx/bin:$PATH验证工具链arm-rockchip830-linux-uclibcgnueabihf-gcc -v5.2 编写C推理程序示例虽然可以用Python但在资源紧张的边缘设备上C通常是更高效的选择。瑞芯微提供了RKNN的C API。// main.cpp 示例框架 #include stdio.h #include stdlib.h #include rknn_api.h // RKNN头文件从SDK中获取 int main(int argc, char** argv) { const char* model_path resnet50_fruits.rknn; const char* img_path test.bin; // 预处理的二进制图像数据 // 1. 创建RKNN上下文 rknn_context ctx; int ret rknn_init(ctx, model_path, 0, 0, NULL); if (ret 0) { printf(rknn_init fail! ret%d\n, ret); return -1; } // 2. 获取模型输入输出信息 rknn_input_output_num io_num; ret rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, io_num, sizeof(io_num)); // ... 根据io_num分配输入输出内存 // 3. 设置输入 rknn_input inputs[1]; // ... 读取img_path文件数据到inputs[0].buf inputs[0].index 0; inputs[0].type RKNN_TENSOR_FLOAT32; // 根据量化类型调整 inputs[0].fmt RKNN_TENSOR_NHWC; inputs[0].size 224*224*3*sizeof(float); ret rknn_inputs_set(ctx, io_num.n_input, inputs); // 4. 运行推理 ret rknn_run(ctx, nullptr); // 5. 获取输出 rknn_output outputs[io_num.n_output]; // ... 为outputs分配内存 ret rknn_outputs_get(ctx, io_num.n_output, outputs, NULL); // 6. 后处理找到最大概率的类别 float* output_data (float*)outputs[0].buf; int max_index 0; for (int i 1; i outputs[0].size / sizeof(float); i) { if (output_data[i] output_data[max_index]) max_index i; } printf(The image is classified as class %d with score %f\n, max_index, output_data[max_index]); // 7. 释放资源 rknn_outputs_release(ctx, io_num.n_output, outputs); rknn_destroy(ctx); return 0; }5.3 交叉编译C程序使用交叉编译工具链编译上面的代码并链接RKNN的库文件。# 假设RKNN库和头文件在SDK目录下 ARM_CCarm-rockchip830-linux-uclibcgnueabihf-g SDK_PATH/path/to/rv1126_sdk $ARM_CC main.cpp -I${SDK_PATH}/include -L${SDK_PATH}/lib -lrknn_api -o resnet_inference -static-static选项进行静态链接可以将所有依赖库打包进可执行文件避免板子上缺少动态库的麻烦。5.4 部署到RV1126开发板并运行传输文件将编译好的可执行文件resnet_inference、RKNN模型文件resnet50_fruits.rknn和一张测试图片或预处理好的二进制文件test.bin通过ADB或SCP传到开发板上。adb push resnet_inference /userdata/ adb push resnet50_fruits.rknn /userdata/ adb push test.bin /userdata/板端运行通过ADB shell登录开发板执行程序。adb shell cd /userdata chmod x resnet_inference ./resnet_inference查看结果如果一切顺利终端将输出分类结果例如The image is classified as class 0 (apple) with score 0.92。踩坑记录第一次在板子上运行时很可能遇到“librknnrt.sonot found”之类的错误。这是因为运行时库路径问题。有三种解决方法一是将SDK中的librknnrt.so库也传到板子的/usr/lib目录下二是在编译时使用-static静态链接推荐三是在板子上设置LD_LIBRARY_PATH环境变量指向库所在目录。6. 性能评估与优化技巧模型成功跑起来只是第一步我们还需要关注其性能和精度是否符合实际应用要求。6.1 关键性能指标测量在RV1126上我们最关心两个指标推理延迟Latency处理一帧图像所需的时间。吞吐量Throughput单位时间如每秒能处理的帧数FPS。可以在C推理代码中加入计时函数来测量。#include chrono auto start std::chrono::high_resolution_clock::now(); ret rknn_run(ctx, nullptr); auto end std::chrono::high_resolution_clock::now(); std::chrono::durationdouble diff end - start; printf(Inference time: %f seconds\n, diff.count());对于视频流应用FPS至少要达到25或30才能保证流畅。ResNet50在RV1126上经过INT8量化后通常能达到10-20 FPS具体取决于输入分辨率和工作频率。6.2 精度验证与量化误差分析量化必然带来精度损失。我们需要系统性地评估。制作测试集准备一个未参与训练和量化的测试图片集几百张。双端对比在PC上用原始的PyTorch FP32模型跑一遍测试集记录每张图片的预测结果和置信度。在RV1126上用转换后的INT8 RKNN模型跑同样的测试集。计算精度差异对比Top-1和Top-5准确率的下降幅度。通常良好的INT8量化能将精度损失控制在1%以内。如果损失过大3%可能需要检查量化校准数据集是否具有代表性或者尝试RKNN-Toolkit2中的混合量化策略对敏感层保持FP16精度。6.3 模型轻量化与加速进阶思路如果ResNet50的性能仍不满足要求可以考虑以下优化路径模型剪枝Pruning在训练后移除网络中不重要的连接或通道得到一个更稀疏、更小的模型然后再进行量化转换。知识蒸馏Knowledge Distillation用一个庞大的“教师网络”如ResNet50来指导一个轻量级的“学生网络”如MobileNet进行训练让学生网络在保持较小体积的同时获得接近教师网络的性能。使用专为边缘设计的网络直接选用MobileNetV3、ShuffleNetV2、EfficientNet-Lite等原生轻量级网络架构进行训练和部署它们能在精度和速度间取得更好的平衡。7. 常见问题排查与调试心得实录在实际操作中你几乎一定会遇到各种问题。这里把我踩过的坑和解决方案汇总一下。7.1 模型转换阶段常见错误问题现象可能原因解决方案rknn.build失败提示不支持的算子ONNX模型中包含了RKNN-Toolkit2不支持的算子。1. 检查PyTorch到ONNX导出时使用的opset_version尝试更低的版本如11。2. 使用onnx-simplifier简化模型python -m onnxsim input.onnx output_sim.onnx。3. 修改网络结构用支持的算子组合替换掉不支持的算子。量化后精度损失巨大量化校准数据集dataset.txt不具代表性或数量太少。1. 确保校准集来自训练集或验证集且覆盖所有类别。2. 增加校准集图片数量建议200-500张。3. 在rknn.config中尝试调整quantized_algorithm量化算法和quantized_method量化方法。仿真推理结果与PyTorch结果差异大预处理不一致归一化参数、BGR/RGB顺序。仔细核对确保RKNN推理前的图像预处理缩放、减均值、除标准差、颜色通道顺序与PyTorch训练时的transforms完全一致。一个像素一个像素地对齐。7.2 板端运行时问题问题现象可能原因解决方案段错误Segmentation fault1. 内存访问越界。2. 模型输入数据格式或尺寸不对。3. 动态库不匹配。1. 检查C代码中内存分配和释放的逻辑。2. 用printf仔细打印输入数据的维度、地址等信息进行比对。3. 使用file命令检查可执行文件和动态库的架构是否都是arm。尝试静态编译。推理结果全零或混乱1. 输入数据未正确传递到NPU。2. 模型文件损坏或版本不匹配。1. 在C代码中将准备好的输入数据先保存为文件在PC端用仿真推理加载该文件验证隔离板端环境问题。2. 重新在宿主机上执行一遍仿真推理确认模型文件本身正确。NPU利用率低速度不达标1. 输入分辨率过高。2. CPU/NPU频率被系统限制。1. 评估是否可以使用更低的分辨率如192x192输入速度会显著提升。2. 通过系统命令如echo performance /sys/devices/system/cpu/cpufreq/policy0/scaling_governor调整CPU频率策略。查阅RV1126文档看是否有NPU频率调节接口。7.3 调试心得与建议二分法定位当问题出现时首先确定问题发生在哪个阶段训练-ONNX导出-RKNN转换-仿真-板端部署。用仿真推理作为分界线如果仿真正确而板端错误问题就在板端环境或代码如果仿真就错了问题就在模型转换或之前。善用官方示例RKNN-Toolkit2的安装包中自带丰富的示例Python和C。当你不知道如何编写板端代码时最好的方法就是先跑通一个最简单的官方示例然后在此基础上修改。日志是朋友确保在初始化RKNN时开启verboseTrue或verbose_logTrue这些日志信息尤其是WARNING和ERROR是定位问题的第一手资料。保持环境一致宿主机上的RKNN-Toolkit2版本、板端驱动的版本、SDK的版本这三者必须严格匹配。版本混用是绝大多数诡异问题的根源。完成整个流程后你收获的不仅仅是一个能在RV1126上跑起来的ResNet50模型更是一套应对边缘AI部署挑战的方法论。从数据准备到模型优化从工具链使用到底层调试这套经验可以平滑地迁移到其他任何模型和边缘芯片平台上。边缘AI的世界很大RV1126和ResNet50只是一个起点但掌握了这个起点你就已经拿到了入场券。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2628401.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…