当前位置: 首页 > news >正文

【三十四周】文献阅读:DeepPose: 通过深度神经网络实现人类姿态估计

目录

  • 摘要
  • Abstract
  • DeepPose: 通过深度神经网络实现人类姿态估计
  • 研究背景
  • 创新点
  • 方法论
    • 归一化
    • 网络结构
    • 级联细化流程
  • 代码实践
  • 局限性
  • 实验结果
  • 总结

摘要

人体姿态估计旨在通过图像定位人体关节,是计算机视觉领域的核心问题之一。传统方法多基于局部检测与图模型,虽在效率上表现优异,但受限于局部特征与有限的关节交互建模,难以应对遮挡、小关节及复杂姿态等挑战。DeepPose提出了一种基于深度神经网络(DNN)的整体回归框架,通过级联DNN结构实现高精度关节定位。首先输入整张图像,通过7层卷积网络直接回归所有关节的归一化坐标。然后基于初始预测,从高分辨率的局部子图像中进一步修正关节位置。实验表明,DeepPose在FLIC、LSP等数据集上超越当时最优方法,尤其在肢体检测精度(PCP)和关节定位准确率(PDJ)上提升显著。其核心创新在于利用DNN的全局上下文建模能力,结合级联机制逐步细化局部细节,实现了无需手工设计特征或复杂图模型的高效姿态估计。

Abstract

Human pose estimation aims to locate human joints in images. It is a key problem in computer vision. Traditional methods often use local detection and graphical models. These methods are efficient but face challenges like occlusion, small joints, and complex poses. This is because they rely on limited local features and joint interaction modeling.DeepPose proposed a holistic regression framework based on deep neural networks (DNNs). It uses a cascaded DNN structure to achieve high-precision joint localization. First, the entire image is input into a 7-layer convolutional network. This network directly predicts normalized coordinates for all joints. Then, based on initial predictions, joint positions are refined using high-resolution local sub-images.Experiments show DeepPose outperforms the best methods at the time on datasets like FLIC and LSP. It improves significantly in limb detection accuracy (Percentage of Correct Parts, PCP) and joint localization accuracy (Percentage of Detected Joints, PDJ). The key innovation is using DNNs to model global context. Combined with a cascading mechanism, it refines local details step by step. This allows efficient pose estimation without manually designed features or complex graphical models.

DeepPose: 通过深度神经网络实现人类姿态估计


Title: DeepPose: Human Pose Estimation via Deep Neural Networks
Author: Alexander Toshev, Christian Szegedy
Source: IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2014
Link:https://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html


研究背景

人体姿态估计的难点源于人体关节的高度灵活性、局部遮挡、小尺寸关节的模糊性以及复杂背景干扰。早期研究多采用基于部件的模型(如Pictorial Structures),通过树状结构建模关节关系,虽计算高效,但仅能捕捉局部特征,难以建模全局姿态。例如,当右臂被遮挡时,传统方法可能因依赖局部检测器而失效,而人类却能通过整体姿态(如左臂位置或躯干朝向)推断被遮挡关节的位置。

为解决这一问题,部分研究尝试通过全局分类器最近邻匹配提升全局推理能力,但受限于线性模型的表达能力或数据规模,实际效果有限。与此同时,深度学习在图像分类与目标检测中的突破(如AlexNet)启发了研究者探索其在姿态估计中的应用。

在这里插入图片描述

对上图而言,许多关节几乎看不见。但是我们可以猜测左臂在左图中的位置,因为我们看到了姿势的其余部分,并预测了人的运动。同样地,右边的人的左半个身体根本看不见。这些都是需要整体推理的例子。论文作者认为DNN可以自然地提供这种类型的推理。然而,如何将DNN应用于高精度、细粒度的关节定位仍是一个开放问题。DeepPose的提出填补了这一空白,首次将DNN回归与级联细化结合,为姿态估计提供了一种端到端的解决方案。

创新点

  1. 基于深度神经网络:不需要显式设计零件的特征表示和检测器;不需要显式设计模型拓扑结构和关节之间的相互作用。
  2. 整体回归框架:摒弃传统局部检测与图模型,直接以整张图像为输入,通过DNN回归所有关节坐标,充分利用全局上下文信息。
  3. 级联细化机制:通过多阶段DNN逐步修正关节位置,前一阶段的预测用于裁剪高分辨率子图像,使后续网络专注于局部细节,提升定位精度。
  4. 通用网络架构:沿用AlexNet的7层卷积结构,证明通用DNN无需特定领域设计即可胜任复杂姿态估计任务,简化了模型开发流程。

方法论

归一化

本论文中首先要对输入图像进行归一化。通过归一化,不同尺度的图像(如远距离拍摄的小人体和近距离拍摄的大人体)会被映射到相同的相对坐标系中,使得模型更容易学习关节的相对位置关系。并且归一化后的坐标范围通常在 [0,1] 之间,这使得训练过程更加稳定,避免了因坐标值过大或过小导致的梯度问题。

公式如下所示:
N ( y i ; b ) = ( 1 / b w 0 0 1 / b h ) ( y i − b c ) N(\mathbf{y}_i; b) = \begin{pmatrix} 1/b_w & 0 \\ 0 & 1/b_h \end{pmatrix} (\mathbf{y}_i - b_c) N(yi;b)=(1/bw001/bh)(yibc)

其中:

  • y i \mathbf{y}_i yi 是第 i i i 个关节的绝对坐标,表示为 ( x i , y i ) (x_i, y_i) (xi,yi)
  • b b b 是一个边界框,定义为 b = ( b c , b w , b h ) b = (b_c, b_w, b_h) b=(bc,bw,bh),其中:
    • b c b_c bc 是边界框的中心坐标 ( b c x , b c y ) (b_{cx}, b_{cy}) (bcx,bcy)
    • b w b_w bw 是边界框的宽度。
    • b h b_h bh 是边界框的高度。
  • N ( y i ; b ) N(\mathbf{y}_i; b) N(yi;b) 是归一化后的关节坐标。

一个简单的例子:

如果边界框的中心是 (100,200),而关节坐标是 (120,220),那么中心化后的坐标是 (20,20)。如果边界框的宽度是 200,高度是 400,那么缩放后的坐标是 (20/200,20/400)=(0.1,0.05)。最终,归一化后的坐标 是一个相对值,表示关节在边界框中的位置比例。例如,(0.1,0.05) 表示关节位于边界框中心右侧 10% 宽度、上方 5% 高度的位置。

网络结构

在这里插入图片描述
模型输入为220×220的归一化图像,经过7层卷积网络(含5个卷积层与2个全连接层)输出2k维向量,对应k个关节的归一化坐标。网络结构借鉴AlexNet,但将分类损失替换为L2回归损失,直接最小化预测与真实坐标的欧氏距离。训练时,通过数据增强生成大量随机裁剪图像,并采用自适应梯度下降优化参数。

级联细化流程

初始阶段:以整张图像或检测框为输入,预测初始关节位置。
细化阶段:以每个关节的预测位置为中心,裁剪σ倍于躯干直径的子图像(如FLIC中σ=1.0,LSP中σ=2.0),输入相同结构的DNN回归位置偏移量。
迭代优化:重复细化过程(通常3个阶段),逐步缩小搜索区域,利用高分辨率子图像提升精度。

例如网络结构图所示,若初始预测的右肘位置偏离真实值,第二阶段网络将聚焦于该区域的高分辨率图像,修正偏移量;第三阶段进一步细化,直至关节坐标收敛。

代码实践

  • 骨干网络使用预训练的resnet-50,将最后的全连接层进行修改:
def create_deep_pose_model(num_keypoints: int) -> nn.Module:# 加载预训练的ResNet-50模型,使用ImageNet数据集上的预训练权重res50 = resnet50(weights=ResNet50_Weights.IMAGENET1K_V2)# 获取原始ResNet-50模型中全连接层的输入特征数in_features = res50.fc.in_features# 替换原有的全连接层为一个新的线性层,输出大小为num_keypoints*2,# 因为每个关键点需要两个坐标值(x,y)res50.fc = nn.Linear(in_features=in_features, out_features=num_keypoints * 2)return res50  # 返回修改后的模型
  • 训练
import os  import torch  
import torch.amp  
from torch.utils.data import DataLoader  # 数据加载器
from torch.utils.tensorboard import SummaryWriter  # TensorBoard写入器,用于记录训练过程import transforms  # 自定义的数据变换模块
from model import create_deep_pose_model  # 自定义函数,用于创建DeepPose模型
from datasets import WFLWDataset  # 自定义数据集类
from train_utils.train_eval_utils import train_one_epoch, evaluate  # 训练和评估的实用函数# 定义获取命令行参数的解析器函数
def get_args_parser(add_help=True):import argparse  # 命令行选项、参数和子命令解析器parser = argparse.ArgumentParser(description="PyTorch DeepPose Training", add_help=add_help)  # 创建解析器实例parser.add_argument("--dataset_dir", type=str, default="/home/wz/datasets/WFLW", help="WFLW dataset directory")  # 数据集目录parser.add_argument("--device", type=str, default="cuda:0", help="training device, e.g. cpu, cuda:0")  # 训练设备parser.add_argument("--save_weights_dir", type=str, default="./weights", help="save dir for model weights")  # 模型权重保存目录parser.add_argument("--save_freq", type=int, default=10, help="save frequency for weights and generated imgs")  # 权重保存频率parser.add_argument("--eval_freq", type=int, default=5, help="evaluate frequency")  # 评估频率parser.add_argument('--img_hw', default=[256, 256], nargs='+', type=int, help='training image size[h, w]')  # 训练图像尺寸parser.add_argument("--epochs", type=int, default=210, help="number of epochs of training")  # 训练周期数parser.add_argument("--batch_size", type=int, default=32, help="size of the batches")  # 批次大小parser.add_argument("--num_workers", type=int, default=8, help="number of workers, default: 8")  # 数据加载线程数parser.add_argument("--num_keypoints", type=int, default=98, help="number of keypoints")  # 关键点数量parser.add_argument("--lr", type=float, default=5e-4, help="Adam: learning rate")  # 学习率parser.add_argument('--lr_steps', default=[170, 200], nargs='+', type=int, help='decrease lr every step-size epochs')  # 学习率衰减步骤parser.add_argument("--warmup_epoch", type=int, default=10, help="number of warmup epoch for training")  # 预热轮数parser.add_argument('--resume', default='', type=str, help='resume from checkpoint')  # 从检查点恢复训练parser.add_argument('--test_only', action="store_true", help='Only test the model')  # 仅测试模式return parser# 主函数
def main(args):torch.manual_seed(1234)  # 固定随机种子以确保结果可复现dataset_dir = args.dataset_dir  # 数据集目录save_weights_dir = args.save_weights_dir  # 权重保存目录save_freq = args.save_freq  # 权重保存频率eval_freq = args.eval_freq  # 评估频率num_keypoints = args.num_keypoints  # 关键点数量num_workers = args.num_workers  # 数据加载线程数epochs = args.epochs  # 训练周期数bs = args.batch_size  # 批次大小start_epoch = 0  # 初始训练轮次img_hw = args.img_hw  # 图像尺寸os.makedirs(save_weights_dir, exist_ok=True)  # 创建保存权重的目录if "cuda" in args.device and not torch.cuda.is_available():  # 如果指定使用GPU但不可用,则回退到CPUdevice = torch.device("cpu")else:device = torch.device(args.device)print(f"using device: {device} for training.")  # 打印使用的设备信息# tensorboard writer,用于记录训练过程中的信息tb_writer = SummaryWriter()# 创建DeepPose模型实例,并将其移动到指定设备model = create_deep_pose_model(num_keypoints)model.to(device)# 配置数据集和数据加载器data_transform = {"train": transforms.Compose([  # 训练数据变换transforms.AffineTransform(scale_factor=(0.65, 1.35), rotate=45, shift_factor=0.15, fixed_size=img_hw),transforms.RandomHorizontalFlip(0.5),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]),"val": transforms.Compose([  # 验证数据变换transforms.AffineTransform(scale_prob=0., rotate_prob=0., shift_prob=0., fixed_size=img_hw),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])}train_dataset = WFLWDataset(root=dataset_dir, train=True, transforms=data_transform["train"])  # 创建训练数据集val_dataset = WFLWDataset(root=dataset_dir, train=False, transforms=data_transform["val"])  # 创建验证数据集train_loader = DataLoader(train_dataset, batch_size=bs, shuffle=True, pin_memory=True, num_workers=num_workers, collate_fn=WFLWDataset.collate_fn, persistent_workers=True)  # 创建训练数据加载器val_loader = DataLoader(val_dataset, batch_size=bs, shuffle=False, pin_memory=True, num_workers=num_workers, collate_fn=WFLWDataset.collate_fn, persistent_workers=True)  # 创建验证数据加载器# 定义优化器optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)# 定义学习率调度器warmup_scheduler = torch.optim.lr_scheduler.LinearLR(optimizer=optimizer, start_factor=0.01, end_factor=1.0, total_iters=len(train_loader) * args.warmup_epoch)multi_step_scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer=optimizer, milestones=[len(train_loader) * i for i in args.lr_steps], gamma=0.1)lr_scheduler = torch.optim.lr_scheduler.ChainedScheduler([warmup_scheduler, multi_step_scheduler])if args.resume:  # 如果有恢复训练的检查点assert os.path.exists(args.resume)checkpoint = torch.load(args.resume, map_location='cpu')model.load_state_dict(checkpoint['model'])optimizer.load_state_dict(checkpoint['optimizer'])lr_scheduler.load_state_dict(checkpoint['lr_scheduler'])start_epoch = checkpoint['epoch'] + 1print("the training process from epoch{}...".format(start_epoch))if args.test_only:  # 如果仅进行测试evaluate(model=model, epoch=start_epoch, val_loader=val_loader, device=device, tb_writer=tb_writer, affine_points_torch_func=transforms.affine_points_torch, num_keypoints=num_keypoints, img_hw=img_hw)returnfor epoch in range(start_epoch, epochs):  # 开始训练循环# 训练一个周期train_one_epoch(model=model, epoch=epoch, train_loader=train_loader, device=device, optimizer=optimizer, lr_scheduler=lr_scheduler, tb_writer=tb_writer, num_keypoints=num_keypoints, img_hw=img_hw)# 每隔一定周期进行评估if epoch % eval_freq == 0 or epoch == args.epochs - 1:evaluate(model=model, epoch=epoch, val_loader=val_loader, device=device, tb_writer=tb_writer, affine_points_torch_func=transforms.affine_points_torch, num_keypoints=num_keypoints, img_hw=img_hw)# 按照设定的频率保存模型权重if epoch % save_freq == 0 or epoch == args.epochs - 1:save_files = {'model': model.state_dict(), 'optimizer': optimizer.state_dict(), 'lr_scheduler': lr_scheduler.state_dict(), 'epoch': epoch}torch.save(save_files, os.path.join(save_weights_dir, f"model_weights_{epoch}.pth"))if __name__ == '__main__':args = get_args_parser().parse_args()  # 解析命令行参数main(args)  # 调用主函数

预测结果如图所示:
请添加图片描述

局限性

在这里插入图片描述

  1. 计算成本高:训练需分布式集群(100个节点耗时3天),限制了实际部署。
  2. 依赖初始检测框:若人体检测框不准确(如FLIC依赖面部检测),可能影响后续回归。
  3. 左右混淆问题:背面拍摄时,模型可能混淆左右关节(如上图最后一列)。
  4. 分辨率限制:输入尺寸固定为220×220,对极小或密集人群场景适应性不足。

实验结果

在这里插入图片描述
在这里插入图片描述

LSP数据集:在PCP指标上,DeepPose对上下肢的检测率(如上肢0.56、下肢0.71)显著优于Dantone(0.49)、Johnson(0.58)等方法。PDJ曲线显示,在0.2倍躯干直径阈值下,DeepPose的关节检测率较次优方法提升10%-15%。

在这里插入图片描述
FLIC数据集:肘部与手腕的PDJ在0.2阈值下分别达到0.9与0.75,较传统方法提升20%以上。

下图绿色为真实姿态标签,红色分别为几个阶段的预测姿态:
在这里插入图片描述

总结

DeepPose作为将深度学习运用到人体姿态估计的开山之作,通过整体回归+级联细化的工作流程,开创了深度学习在人体姿态估计中的新范式。其证明通用卷积网络无需复杂结构调整即可建模全局姿态;通过级联机制将粗粒度推理与细粒度修正解耦,兼顾效率与精度;在多个数据集上实现SOTA性能,尤其在遮挡与小关节场景下表现突出。

相关文章:

【三十四周】文献阅读:DeepPose: 通过深度神经网络实现人类姿态估计

目录 摘要AbstractDeepPose: 通过深度神经网络实现人类姿态估计研究背景创新点方法论归一化网络结构级联细化流程 代码实践局限性实验结果总结 摘要 人体姿态估计旨在通过图像定位人体关节,是计算机视觉领域的核心问题之一。传统方法多基于局部检测与图模型&#x…...

将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南

将 Vue 项目打包后部署到 Spring Boot 项目中的全面指南 在现代 Web 开发中,前后端分离架构已经成为主流。然而,在某些场景下,我们可能需要将前端项目(如 Vue)与后端项目(如 Spring Boot)集成部…...

Linux 权限系统和软件安装(二):深入理解 Linux 权限系统

在 Linux 的世界里,权限系统犹如一位忠诚的卫士,严密守护着系统中的文件与目录,确保只有具备相应权限的用户才能进行操作。与其他一些操作系统不同,Linux 并不依据文件后缀名来标识文件的操作权限,而是构建了一套独特且…...

计算机网络常考大题

运输层的主要功能 运输层为应用进程之间提供端到端的逻辑通信。 运输层还要对收到的报文进行差错检测。 运输层需要有两种不同的运输协议,即面向连接的 TCP 和无连接的 UDP 传输控制协议 TCP 概述 TCP 是面向连接的运输层协议。 每一条 TCP 连接只能有两个端点…...

百度首页上线 DeepSeek 入口,免费使用

大家好,我是小悟。 百度首页正式上线了 DeepSeek 入口,这一重磅消息瞬间在技术圈掀起了惊涛骇浪,各大平台都被刷爆了屏。 百度这次可太给力了,PC 端开放仅 1 小时,就有超千万人涌入体验。这速度,简直比火…...

《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战

前一篇文章,使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一:AlexNet【下】【论文精读】】的心得。 《跟李沐…...

Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg

参考文章: https://blog.csdn.net/whatareyouding/article/details/144317654 https://www.cnblogs.com/Gredae/p/18362900 https://www.cnblogs.com/kn-zheng/p/17422707.html https://blog.51cto.com/u_16099344/10281495 https://www.tulingxueyuan.cn/tlzx/jsp…...

Node.js高频面试题精选及参考答案

目录 什么是 Node.js?它的主要特点有哪些? Node.js 的事件驱动和非阻塞 I/O 模型是如何工作的? 为什么 Node.js 适合处理高并发场景? Node.js 与传统后端语言(如 Java、Python)相比,有哪些优势和劣势? 简述 Node.js 的运行原理,包括 V8 引擎的作用。 什么是 Nod…...

公开整理-最新中国城市统计NJExcel+PDF版本(1985-2024年)

数据简介:《中国城市统计NJ》从1985年开始,本NJ内容共分四个部分:第一部分是全国城市行政区划,列有不同区域、不同级别的城市分布情况;第二、三部分分别是地级以上城市统计资料和县级城市统计资料,具体包括人口、劳动力及土地资源、综合经济、工业、交通…...

ModuleNotFoundError: No module named ‘xgboost‘

问题: --------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Cell In[1], line 64 import pickle5 from sklearn.metrics import mean_squared_error, r2_…...

应用层协议HTTP

应用层协议HTTP 引言 应用层协议是程序员自己制定的,但是良好的协议是保证网络通信的基础,前代的计算工程师已经帮助我们制定了一些很好用的应用层协议,http(hybertext transfer protocol)(超文本传输协议)就是其中之一。 http协议是客户端…...

常见的“锁”有哪些?

悲观锁 悲观锁认为在并发环境中,数据随时可能被其他线程修改,因此在访问数据之前会先加锁,以防止其他线程对数据进行修改。常见的悲观锁实现有: 1.互斥锁 原理:互斥锁是一种最基本的锁类型,同一时间只允…...

PAT 甲级 1091 Acute Stroke

一开始只是简单的递归&#xff08;bfs&#xff09;&#xff0c;导致最后两个没法通过&#xff08;爆栈了&#xff09; //最后两个案例没有通过&#xff0c;只是最简单的bfs暴力算法 #include<cstdio> using namespace std; int v[62][1288][130]{0}; int find(int i,int…...

flowable适配达梦数据库

文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错&#xff1a;inStream参数为null分析解决 liquibase相关问题问题一&#xff1a;不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访…...

Git入门:数据模型 to 底层原理

版本控制系统&#xff08;VCS&#xff09;是软件开发中不可或缺的工具&#xff0c;而Git作为现代版本控制的事实标准&#xff0c;其底层设计远比表面命令更加优雅。本文将从数据模型的角度&#xff0c;揭示Git的核心工作原理。 Git的核心概念 1. 快照&#xff08;Snapshot&am…...

Bootstrap Blazor UI 中 <Table> 组件 <TableColumn> 使用备忘01:EF Core 外码处理

应用场景&#xff1a;将外码转换为对应的文本进行显示、编辑。 例如&#xff0c;有一个【用户】表&#xff0c;其中有一个【用户类型ID】字段&#xff1b;另有一个【用户类型】表&#xff0c;包含【ID】、【名称】等字段。现在要求在 <Table> 组件显示列表中&#xff0c…...

Redis过期数据处理

Redis缓存过期后数据还能恢复吗&#xff1f; Redis缓存过期后&#xff0c;数据通常会被删除&#xff0c;但可以通过以下几种方法尝试恢复数据&#xff1a; 1. 数据备份恢复 RDB 持久化恢复&#xff1a;Redis 提供了 RDB&#xff08;Redis Database Backup&#xff09;持久化…...

零基础学C/C++160——字符串

题目描述 给定两个由小写字母组成的字符串A和B&#xff0c;判断B中的字符是否全部在A中出现。 输入 输入为多组测试数据。 输入数据只有一行&#xff0c;包含2个字符串A和B&#xff0c;每个字符串后面有一个#字符标记&#xff08;#不属于A或B&#xff09;&#xff0c;其中B…...

Spring Boot+Vue项目从零入手

Spring BootVue项目从零入手 一、前期准备 在搭建spring bootvue项目前&#xff0c;我们首先要准备好开发环境&#xff0c;所需相关环境和软件如下&#xff1a; 1、node.js 检测安装成功的方法&#xff1a;node -v 2、vue 检测安装成功的方法&#xff1a;vue -V 3、Visu…...

Linux 命令大全完整版(13)

5.文件管理命令 patch 功能说明&#xff1a;修补文件。语  法&#xff1a;patch [-bceEflnNRstTuvZ][-B <备份字首字符串>][-d <工作目录>][-D <标示符号>][-F <监别列数>][-g <控制数值>][-i <修补文件>][-o <输出文件>][-p &l…...

MySQL面试学习

MySQL 1.事务 事务的4大特性 事务4大特性&#xff1a;原子性、一致性、隔离性、持久性 原⼦性&#xff1a; 事务是最⼩的执⾏单位&#xff0c;不允许分割。事务的原⼦性确保动作要么全部完成&#xff0c;要么全不执行一致性&#xff1a; 执⾏事务前后&#xff0c;数据保持⼀…...

CentOS中shell脚本对多台机器执行下载安装

1.建立免密ssh连接 详情见这篇&#xff1a; CentOS建立ssh免密连接&#xff08;含流程剖析&#xff09;-CSDN博客 2.脚本编写 我这里只是简单写了个demo进行演示&#xff0c;如果服务器很多可以先暂存成文件再逐行读取host进行连接并执行命令 用node1去ssh连接node2和node…...

【Java】多线程和高并发编程(四):阻塞队列(上)基础概念、ArrayBlockingQueue

文章目录 四、阻塞队列1、基础概念1.1 生产者消费者概念1.2 JUC阻塞队列的存取方法 2、ArrayBlockingQueue2.1 ArrayBlockingQueue的基本使用2.2 生产者方法实现原理2.2.1 ArrayBlockingQueue的常见属性2.2.2 add方法实现2.2.3 offer方法实现2.2.4 offer(time,unit)方法2.2.5 p…...

C语言多人聊天室 ---chat(客户端聊天)

head.h #ifndef __HEAD_H #define __HEAD_H// 常用头文件 #include <stdio.h> #include <stdlib.h> #include <string.h>// 网络编程涉及的头文件 #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h>#include <…...

设计模式教程:命令模式(Command Pattern)

1. 什么是命令模式&#xff1f; 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式。它将请求封装成一个对象&#xff0c;从而使你能够用不同的请求、队列和日志请求以及支持可撤销操作。 简单来说&#xff0c;命令模式通过把请求封装成对象的方式解耦了…...

【华三】STP的角色选举(一文讲透)

【华三】STP的角色选举 一、引言二、STP基础概念扫盲三、根桥选举过程详解四、根端口选举过程详解五、指定端口选举过程详解六、阻塞端口七、总结与配置建议七、附录**1. BPDU字段结构图&#xff08;文字描述&#xff09;****2. 华三STP常用命令速查表** 文章总结 一、引言 在…...

Trae+Qt+MSVC环境配置

Trae Trae是字节跳动基于VSCode推出的AI集成开发环境&#xff08;IDE&#xff09;&#xff0c;是一款专为中文开发者深度定制的智能编程工具。其目标是通过AI技术实现从“Copilot”到“Autopilot”的编程模式演进。 类似这样的IDE比如Windsurf、Cursor&#xff0c;都是基于VS…...

SpringSecurity初始化的本质

一、对SpringSecurity初始化的几个疑问 通过前面第一次请求访问的分析我们明白了一个请求就来后的具体处理流程 对于一个请求到来后会通过FilterChainProxy来匹配一个对应的过滤器链来处理该请求。那么这里我们就有几个疑惑。 FilterChainProxy什么时候创建的?过滤器链和对应的…...

3D Gaussian Splatting(3DGS)的核心原理

3D Gaussian Splatting&#xff08;3DGS&#xff09;的核心原理 1. 基本概念 3D Gaussian Splatting&#xff08;3DGS&#xff09; 是一种基于 高斯分布的点云表示与渲染技术&#xff0c;核心思想是将三维场景建模为一系列 可学习的高斯分布&#xff0c;每个高斯分布具有以下…...

Transformers快速入门-学习笔记

一、自然语言处理 NLP 是借助计算机技术研究人类语言的科学自然语言处理发展史 一、不懂语法怎么理解语言 依靠语言学家人工总结文法规则 Chomsky Formal Languages 难点&#xff1a;上下文有关文法 规则增多&#xff0c;存在矛盾 二、只要看得足够多&#xff0c;就能处理语言…...

【Http和Https区别】

概念&#xff1a; 一、Http协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档&#xff08;如HTML&#xff09;的应用层协议&#xff0c;主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议&#xff0c;客户端通常…...

学习路程二 LangChain基本介绍

前面简单调用了一下deepseek的方法&#xff0c;发现有一些疑问和繁琐的问题&#xff0c;需要更多的学习&#xff0c;然后比较流行的就是LangChain这个东西了。 目前大部分企业都是基于 LangChain 、qwen-Agent、lammaIndex框架进行大模型应用开发。LangChain 提供了 Chain、To…...

简识Kafka集群与RocketMQ集群的核心区别

前记&#xff1a;各位潘安、各位子健/各位彦祖、于晏&#xff0c;文字较多&#xff0c;优先看目录。 Kafka集群与RocketMQ集群的核心区别及架构图例说明 一、核心区别对比 特性Kafka 集群RocketMQ 集群设计目标高吞吐量实时日志流系统&#xff08;如日志收集、大数据流水线&a…...

基于Python+django+mysql旅游数据爬虫采集可视化分析推荐系统

2024旅游推荐系统爬虫可视化&#xff08;协同过滤算法&#xff09; 基于Pythondjangomysql旅游数据爬虫采集可视化分析推荐系统 有文档说明 部署文档 视频讲解 ✅️基于用户的协同过滤推荐算法 卖价就是标价~ 项目技术栈 Python语言、Django框架、MySQL数据库、requests网络爬虫…...

9-1. MySQL 性能分析工具的使用——last_query_cost,慢查询日志

9-1. MySQL 性能分析工具的使用——last_query_cost&#xff0c;慢查询日志 文章目录 9-1. MySQL 性能分析工具的使用——last_query_cost&#xff0c;慢查询日志1. 数据库服务器的优化步骤2. 查看系统性能参数3. 统计SQL的查询成本&#xff1a;last_query_cost4. 定位执行慢的…...

网络安全监测探针安装位置 网络安全监测系统

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 软件简介&#xff1a; SockMon(SocketMonitor)网络安全监控系统是一款为电脑专业人员打造的一款出色的安防监控软件。在如今这个恶意软件&#xff0c;攻击&#…...

Git版本控制系统---本地操作(万字详解!)

目录 git基本配置 认识工作区、暂存区、版本库 添加文件--情况一&#xff1a; 添加文件-情况二: 修改文件: 版本回退&#xff1a; git基本配置 1.初始化本地仓库&#xff0c;注意&#xff1a;一定要在一个目录下进行&#xff0c;一般都是新建一个文件夹&#xff0c;在文件…...

forge-1.21.x模组开发(二)给物品添加功能

功能效果 创建一个兑换券&#xff0c;当使用兑换券对着兑换机右键时&#xff0c;获得一条烤鱼 创建兑换券 创建ExchangeCouponsItem.java&#xff0c;继承Item&#xff0c;定义兑换券内容 public class ExchangeCouponsItem extends Item {public ExchangeCouponsItem(Prop…...

elasticsearch在windows上的配置

写在最前面&#xff1a; 上资源 第一步 解压&#xff1a; 第二步 配置两个环境变量 第三步 如果是其他资源需要将标蓝的文件中的内容加一句 xpack.security.enabled: false 不同版本的yaml文件可能配置不同&#xff0c;末尾加这个 xpack.security.enabled: true打开bin目…...

机器学习数学通关指南——拉格朗日乘子法

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 一句话总结 拉格朗日乘子法…...

Matplotlib,Streamlit,Django大致介绍

Matplotlib&#xff1a;是一个用于创建各种类型的静态、动态和交互式图表的Python绘图库。可以通过pip install matplotlib命令进行安装&#xff0c;安装完成后&#xff0c;在Python脚本中使用import matplotlib语句导入即可开始使用。Streamlit&#xff1a;是一个用于快速构建…...

智慧废品回收小程序php+uniapp

废品回收小程序&#xff1a;数字化赋能环保&#xff0c;开启资源循环新时代 城市垃圾治理难题&#xff0c;废品回收小程序成破局关键 随着城市化进程加速与消费水平提升&#xff0c;我国生活垃圾总量逐年攀升&#xff0c;年均增速达5%-8%&#xff0c;其中超30%为可回收物。然…...

深搜专题2:组合问题

描述 组合问题就是从n个元素中抽出r个元素(不分顺序且r < &#xff1d; n)&#xff0c; 我们可以简单地将n个元素理解为自然数1&#xff0c;2&#xff0c;…&#xff0c;n&#xff0c;从中任取r个数。 例如n &#xff1d; 5 &#xff0c;r &#xff1d; 3 &#xff0c;所…...

Redis 如何实现消息队列?

在当今的分布式系统架构中&#xff0c;消息队列起着至关重要的作用&#xff0c;它能够帮助系统实现异步通信、解耦组件以及缓冲流量等功能。Redis&#xff0c;作为一款高性能的键值对存储数据库&#xff0c;也为我们提供了便捷的方式来构建消息队列。今天&#xff0c;咱们就深入…...

Day1 初识AndroidAudio

今日目标 搭建Android Audio开发环境理解音频基础概念实现第一个音频播放/录制Demo了解车载音频的特殊性 上午&#xff1a;环境搭建与理论学习 步骤1&#xff1a;开发环境配置 安装Android Studio&#xff08;最新稳定版&#xff09;创建新项目&#xff08;选择Kotlin语言&a…...

2025保险与金融领域实战全解析:DeepSeek赋能细分领域深度指南(附全流程案例)

🚀 2025保险与金融领域实战全解析:DeepSeek赋能细分领域深度指南(附全流程案例)🚀 📚 目录 DeepSeek在保险与金融中的核心价值保险领域:从风险建模到产品创新金融领域:从投资分析到财富管理区块链与联邦学习的应用探索客户关系与私域运营:全球化体验升级工具与资源…...

YARN的工作机制及特性总结

YARN hadoop的资源管理调度平台&#xff08;集群&#xff09;——为用户程序提供运算资源的管理和调度 用户程序&#xff1a;如用户开发的一个MR程序 YARN有两类节点&#xff08;服务进程&#xff09;&#xff1a; 1. resourcemanager 主节点master ----只需要1个来工作 2. nod…...

财务运营域——营收稽核系统设计

摘要 本文主要介绍了营收稽核系统的背景、特点与作用。营收稽核系统的产生源于营收管理复杂性、财务合规与审计需求、提升数据透明度与决策效率、防范舞弊与风险管理、技术进步与自动化需求、多元化业务模式以及跨部门协作与数据整合等多方面因素。其特点包括自动化与智能化、…...

22.回溯算法4

递增子序列 这里不能排序&#xff0c;因为数组的顺序是对结果有影响的&#xff0c;所以只能通过used数组来去重 class Solution { public:vector<int> path;vector<vector<int>> res;void backtracking(vector<int>& nums,int start){if(path.si…...

C#上位机--跳转语句

在 C# 编程中&#xff0c;跳转语句用于改变程序的执行流程。这些语句允许程序从当前位置跳转到其他位置&#xff0c;从而实现特定的逻辑控制。本文将详细介绍 C# 中四种常见的跳转语句&#xff1a;GOTO、Break、Continue 和 Return&#xff0c;并通过具体的示例代码来展示它们的…...