自监督行为识别-时空线索解耦(论文复现)
自监督行为识别-时空线索解耦(论文复现)
本文所涉及所有资源均在传知代码平台可获取
文章目录
- 自监督行为识别-时空线索解耦(论文复现)
- 引言
- 论文概述
- 核心创新点
- 双向解耦编码器
- 跨域对比损失的构建
- 结构化数据增强
- 项目部署
- 准备工作
- 数据准备
- 生成数据
- 训练&测试
- 训练
- 测试
- bug修改
引言
自监督骨架行为识别是一种利用未标记的骨架数据进行行为识别的方法。传统的行为识别方法通常需要大量标记好的数据进行训练,但标记数据的获取成本高昂。自监督学习通过设计自动生成标签的任务,可以在缺乏标记数据的情况下进行训练
在自监督骨架行为识别中,骨架数据可以通过传感器或深度摄像头等设备获取。这些数据包含了人体关节的位置和运动信息。自监督学习任务的关键是设计一种能够从未标记的骨架数据中自动生成标签的方法。
在训练过程中,使用未标记的骨架数据进行自监督学习,生成伪标签。然后,将生成的伪标签用于监督骨架行为识别模型的训练。通过这种方式,自监督学习可以在缺乏标记数据的情况下,提供一种有效的方法进行骨架行为识别。
那么目前自监督骨架行为还面临哪些挑战呢?
- 挑战1. 时空信息的混淆
编码器负责将输入映射到可以进行对比的潜在空间。而之前的大多数方法专注于通过常用的时空建模网络获得统一的信息。他们的设计导致了时间、空间信息的纠缠,无法为随后的对比措施提供明确的指示。
- 挑战2.数据增强的局限性
此外,现有技术往往局限于规模转换(常见的增强策略,比如裁剪、旋转),这导致无法充分利用数据增强的潜力。
- 挑战3. 未考虑方法的可迁移性
优化过程中,大多数方法都专注于在相同的表示水平上构建对比对;忽略域之间的差距(同一任务下或数据集中)
论文概述
SCD-NET(SCD-Net: Spatio temporal Clues Disentanglement Network for
Self-Supervised Skeleton-Based Action Recognition AAAI2024)引入了一种新的对比学习框架,即时空线索解耦网络(SCD-Net)。
具体来说,将解耦模块与特征提取器相结合,分别从空间和时间域获得明确的线索。对于SCD-Net的训练,构建了一个全局锚点,鼓励锚点与提取的线索相互作用。此外,本文提出了一种具有结构约束的新的掩码策略,以加强上下文关联,利用掩码图像建模到所提出的SCD-Net。
从实验结果来看,在NTU-RGB+D(60&120)和PKUMMD (I&II)数据集进行了广泛的评估,涵盖了各种下游任务,如动作识别、动作检索、迁移学习和半监督学习。实验结果证明了该方法的有效性,显著优于现有的最先进(SOTA)方法
核心创新点
为了解决自监督在面临的三个挑战,该文分别提出三种方法分别应对。首先在时空信息混淆的问题上,作者提出双向接口编码器;数据增强方面,分别在时间、空间上分设置不同的数据增强策略;方法的可迁移性方面设置了跨越对比损失,详细架构可见下文。
SCD-NET整体架构如下所示:骨架数据->数据增强(data augmentation)后,分别送入编码器层(encoder)以及动量编码器层(Momentum encoder).每个编码器都使用了双向解耦编码器,在经过特征抽取器(feature extractor)后,分别对空间解耦(spatial decoupling)、时间解耦(temporal decoupling)操作,获取不同维度的特征。动量编码器得到的输出作为键向量,正常编码器得到的输出作为查询向量,最后将键向量、查询向量进行对比学习
双向解耦编码器
一般来说,从骨架序列中提取的特征被描述为描述动作的复杂时空关联。然而,本文认为这种范式并不适用于对比学习。由于信息的纠缠性很大,很难为后续的比较提供明确的指导。在SCD-Net中,本文提倡一种双路解耦编码器,从复杂的序列信息中分别提取出时间、空间信息以获得更好的判别性表示。
双向解耦编码器构造如下图:分为建模(projection)和细化(refinement)阶段,空间部分对CT维度进行合并,保留V(代表骨骼关节)维度,而后进行嵌入操作得到骨架图->序列化–>transformer 编码器->空间池化->空间特征;时间部分对CC维度进行合并,保留T(代表视频帧)维度,而后进行嵌入操作得到关节序列->序列化–>transformer 编码器->时间池化->时间特征
# 双向解耦编码器vt = self.gcn_t(x)vt = rearrange(vt, '(B M) C T V -> B T (M V C)', M=2)vt = self.channel_t(vt)vs = self.gcn_s(x)vs = rearrange(vs, '(B M) C T V -> B (M V) (T C)', M=2)vs = self.channel_s(vs)vt = self.t_encoder(vt) # B T Cvs = self.s_encoder(vs)# implementation using amax for the TMP runs faster than using MaxPool1D# not support pytorch < 1.7.0vt = vt.amax(dim=1)vs = vs.amax(dim=1)return vt, vs
跨域对比损失的构建
# 正负样本以及损失函数的设计def forward(self, q_input, k_input):三种查询向量的定义qt, qs, qi = self.encoder_q(q_input) # queries: NxCqt = nn.functional.normalize(qt, dim=1)qs = nn.functional.normalize(qs, dim=1)qi = nn.functional.normalize(qi, dim=1)# 计算key特征with torch.no_grad(): # no gradient to keysself._momentum_update_key_encoder() # update the key encoderkt, ks, ki = self.encoder_k(k_input) # keys: NxCkt = nn.functional.normalize(kt, dim=1)ks = nn.functional.normalize(ks, dim=1)ki = nn.functional.normalize(ki, dim=1)# 正负样本l_pos_ti = torch.einsum('nc,nc->n', [qt, ki]).unsqueeze(1)l_pos_si = torch.einsum('nc,nc->n', [qs, ki]).unsqueeze(1)l_pos_it = torch.einsum('nc,nc->n', [qi, kt]).unsqueeze(1)l_pos_is = torch.einsum('nc,nc->n', [qi, ks]).unsqueeze(1)l_neg_ti = torch.einsum('nc,ck->nk', [qt, self.i_queue.clone().detach()])l_neg_si = torch.einsum('nc,ck->nk', [qs, self.i_queue.clone().detach()])l_neg_it = torch.einsum('nc,ck->nk', [qi, self.t_queue.clone().detach()])l_neg_is = torch.einsum('nc,ck->nk', [qi, self.s_queue.clone().detach()])# 损失函数logits_ti = torch.cat([l_pos_ti, l_neg_ti], dim=1)logits_si = torch.cat([l_pos_si, l_neg_si], dim=1)logits_it = torch.cat([l_pos_it, l_neg_it], dim=1)logits_is = torch.cat([l_pos_is, l_neg_is], dim=1)logits_ti /= self.Tlogits_si /= self.Tlogits_it /= self.Tlogits_is /= self.T
结构化数据增强
本位在空间、时间部分分别提出了不同的增强策略,空间部分提出结构引导的空间掩码,时间部分提出基于管道的时间掩码
- 结构引导的空间掩码
考虑到骨架的物理结构,当选择某个关节进行掩码时,模型可能通过周围的点学习到相关信息,掩码效果不佳。通过施加结构约束,本文的方法在当前随机选择的关节或框架周围的局部区域内应用掩码操作,而不是仅依赖于孤立的点本文同时对其相邻区域的进行掩码。让本文用矩阵p来表示邻接关系,如果关节i和j连通,则Pij = 1,否则Pij= 0。令D = Pn。为了施加结构约束,当节点i被选中时,本文对Dij != 0的所有节点j执行相同的增强操作。
- 基于管道的时间掩码
基于管道的时间掩码的核心思想是通过将时间序列数据分为多个管道,并为每个管道生成对应的时间掩码,来提取关键的行为特征。具体而言,时间掩码是一种二进制序列,用于指示时间序列中的重要时间段。通过对时间序列数据进行分割,并根据具体的行为任务和特征需求,选择性地将时间掩码应用于每个管道。结构图图下:
这种方法的优势在于,它可以将注意力集中在对行为识别最有用的时间段上,从而提高模型对关键动作的感知能力。时间掩码的生成可以根据不同的策略进行,如基于阈值、基于能量或基于模式识别等方法。生成的时间掩码可以作为输入数据的权重,用于调整模型对不同时间段的重视程度
项目部署
准备工作
- Pytorch环境
- 安装依赖包,运行以下命令即可
pip install -r requirements.txt
数据准备
生成数据
下载数据集
- NTU-RGB+D
- PKU-MMD
数据处理
- 用以下代码处理数据:
python ntu_gendata.py
训练&测试
训练
训练 NTU-RGB+D 60数据集 在 Cross-Subject 评价标准下的预训练模型, 运行以下命令
python ./pretraining.py --lr 0.01 --batch-size 64 --encoder-t 0.2 --encoder-k 8192 \--checkpoint-path ./checkpoints/pretrain/ \--schedule 351 --epochs 451 --pre-dataset ntu60 \--protocol cross_subject --skeleton-representation joint
测试
测试论文给出模型在行为识别任务下NTU-RGB+D 60 数据集 Cross-Subject 评价标准上的结果, 运行以下命令
python ./action_classification.py --lr 2 --batch-size 1024 \--pretrained ./checkpoints/pretrain/checkpoint.pth.tar \--finetune-dataset ntu60 --protocol cross_subject --finetune_skeleton_representation joint
测试论文给出模型在行为检索任务下NTU-RGB+D 60 数据集 Cross-Subject 评价标准上的结果, 运行以下命令
python ./action_retrieval.py --knn-neighbours 1 \--pretrained ./checkpoints/pretrain/checkpoint.pth.tar \--finetune-dataset ntu60 --protocol cross_subject --finetune-skeleton-representation joint
bug修改
在复现原文代码的时候,直接运行运行./pretraining文件,会出现如下错误
- 错误如下:
TypeError: init() got an unexpected keyword argument ‘batch_first’
- 原因分析:
init方法没有参数‘batch_first’,所以将batch_first删去即可。在更改batch_first参数的请务必同时输入数据进行同步调整。具体来说,batch_first=True时的输入维度为 (batch, seq, feature),否则对应的输入维度需要调整为(seq, batch, feature)
- 解决方法:
将报错代码中encoder_layer部分替换为如下代码,即可正常运行
encoder_layer = TransformerEncoderLayer(self.d_model, num_head, self.d_model)self.t_encoder = TransformerEncoder(encoder_layer, num_layer)self.s_encoder = TransformerEncoder(encoder_layer, num_layer)def forward(self, x):vt = self.gcn_t(x)vt = rearrange(vt, '(B M) C T V -> B T (M V C)', M=2)vt = self.channel_t(vt)vs = self.gcn_s(x)vs = rearrange(vs, '(B M) C T V -> B (M V) (T C)', M=2)vs = self.channel_s(vs)# batch_first=True时的输入维度为 (batch, seq, feature),# 否则对应的输入维度需要调整为(seq, batch, feature)# 通过transpose函数调整维度vt = vt.transpose(0, 1) # 调整为 (T, B, M*V*C)vs = vs.transpose(0, 1) # 调整为 (T, B*M*V, C)vt = self.t_encoder(vt) # vs = self.s_encoder(vs) #vt = vt.amax(dim=1)vs = vs.amax(dim=1)return vt, vs
文章代码资源点击附件获取
相关文章:

自监督行为识别-时空线索解耦(论文复现)
自监督行为识别-时空线索解耦(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 自监督行为识别-时空线索解耦(论文复现)引言论文概述核心创新点双向解耦编码器跨域对比损失的构建结构化数据增强项目部署准备工作数据…...

MyBatisPlus:自定义SQL
由于SQL不能写在业务层,所以可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分 ①基于Wrapper 构建Where条件 Testpublic void test7(){//需求:将id满足ids的数据项的balance字段减200int amount200;List…...

变电站谐波治理设备有哪些
在变电站中,由于非线性负载(如电力电子设备、变频器等)会引入谐波,对电网造成干扰,因此需要进行谐波治理。以下是常见的变电站谐波治理设备及其特点: 1、静止无功发生器(SVG) 工作原…...

Mybatis全局配置介绍
【mybatis全局配置介绍】 mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。 1、mybatis全局配置文件是mybatis框架的核心配置,整个框架只需一个;…...

error: cannot find symbol import android.os.SystemProperties;
背景:AS独立编译系统工程应用,使用了hide接口,导致编译不过。 尽管使用了framework.jar依赖。依然编译不过,导致各种类找不到。 例如: /SettingsLib/src/main/java/com/android/settingslib/location/RecentLocatio…...

债券市场金融基础设施 (2020版)
前言:我国债券市场格局简介 我国金融市场主要包括货币市场、资本市场、外汇市场、金融衍生工具市场等,其中,资本市场是金融市场重要组成部分,承担着实体经济直接融资的重责,做大做强资本市场对整个国民经济具有重要意义。债券市场是资本市场两大组成部分之一,对提高直接…...

OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在指定的窗口中显示一幅图像。 函数 imshow 在指定的窗口中显示一幅图像。如果窗口是以 cv::WINDOW_AUTOSIZE 标志创建的,图像将以原…...

for循环和while循环的区别
for循环和while循环的主要区别在于使用场景和结构。for循环适合已知循环次数的情况,而while循环则更灵活,适用于条件动态变化的情况。 for循环的特点 1. 已知迭代次数:for循环在开始前就需要知道具体的迭代次数。例如,遍历一个列…...

机器学习和神经网络的研究与传统物理学的关系
机器学习和神经网络的研究与传统物理学的关系 机器学习和神经网络是现代科学研究中非常热门的领域,它们与传统物理学在某些方面有着密切的关系,在人类科学研究中相互影响和促进作用也越来越显著。 首先,机器学习和神经网络在物理学研究中具…...

LabVIEW提高开发效率技巧----事件触发模式
事件触发模式在LabVIEW开发中是一种常见且有效的编程方法,适用于需要动态响应外部或内部信号的场景。通过事件结构(Event Structure)和用户自定义事件(User Events),开发者可以设计出高效的事件驱动程序&am…...

Kimi AI助手重大更新:语音通话功能闪亮登场!
Kimi人工智能助手近日发布了一项令人瞩目的重大更新,其中最引人注目的是新增的语音通话功能。这一创新不仅拓展了用户与AI互动的方式,还为学习和工作场景提供了突破性的解决方案。 Ai 智能办公利器 - Ai-321.com 人工智能 - Ai工具集 - 全球热门人工智能…...

Linux——进程管理
目录 进程基础 ps 显示系统执行的进程 终止进程 kill 和 killall pstree 查看进程树 服务(service)管理 service 管理指令 服务的运行级别(runlevel) chkconfig 设置服务在不同运行级别下是否开启自启动 systemctl 管理…...

【ARM 嵌入式 编译系列 2.9 -- GCC 编译如何避免赋值判断 if ( x = 0)】
> ARM GCC 编译精讲系列课程链接 < 文章目录 GCC 编译避免赋值判断参数说明示例编译命令解决方法 GCC 编译避免赋值判断 在 GCC 编译中,为了避免误将赋值操作用于条件判断(例如 if (break_var 0x0))导致的错误,可以使用 -…...

PyTorch搭建GNN(GCN、GraphSAGE和GAT)实现多节点、单节点内多变量输入多变量输出时空预测
目录 I. 前言II. 数据集说明III. 模型3.1 GCN3.2 GraphSAGE3.3 GAT IV. 训练与测试V. 实验结果 I. 前言 前面已经写了很多关于时间序列预测的文章: 深入理解PyTorch中LSTM的输入和输出(从input输入到Linear输出)PyTorch搭建LSTM实现时间序列…...

51单片机快速入门之数码管的拓展应用2024/10/15
51单片机快速入门之数码管的拓展应用 在前面的文章中,我们已经了解到数码管的基础应用,今天来讲讲拓展应用 我们知道单个数码管分为以下 但是当我们碰到 如下这种数码管的时候又应该如何去控制呢? 这里就不得不说其拓展应用之-----------扫描显示 扫描显示: 扫描显示,又称…...

vue 音频播放控件封装
<template> <div> <audio @timeupdate="updateProgress" controls ref="audioRef" style="display: none" > <source :src="audioUrl" type="audio/mpeg" /> 您的浏览器不支持音频播放 </audio&…...

秋招面试题记录
嵌入式软件开发 网上搜集的题目 1.Static关键词的作用? static 关键字有三个主要作用: 局部变量:在函数内部,static 局部变量只初始化一次,且在函数调用结束后仍然保留其值。全局变量/函数:在文件内部&a…...

金字塔流(Pyramid Flow): 用于生成人工智能长视频的新文本-视频开源模型
在 "生成式人工智能 "中的文本生成模型和图像生成模型大行其道之后,现在该是文本-视频模型大显身手的时候了,这个列表中的新模型就是 pyramid-flow-sd3,它是一个开源模型,用于从文本或图像生成长达 10 秒的视频…...

施磊C++ | 进阶学习笔记 | 5.设计模式
五、设计模式 文章目录 五、设计模式1.设计模式三大类型概述一、创建型设计模式二、结构型设计模式三、行为型设计模式 2.设计模式三大原则3.单例模式1.饿汉单例模式2.懒汉单例模式 4.线程安全的懒汉单例模式1.锁双重判断2.简洁的线程安全懒汉单例模式 5.简单工厂(Simple Facto…...

智绘城市地图:使用百度地图 API 实现智能定位
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

【稳定性】稳定性建设之变更管理
作者:京东物流 冯志文 背景 在软件开发和运维领域,变更管理是一个至关重要的环节。无论是对现有系统的改进、功能的增加还是修复漏洞,变更都是不可避免的。这些变更可能涉及到软件代码的修改、配置的调整、服务器的扩容、三方jar包的变更等等…...

c语言中字符串函数strlen,strcmp,strcpy,srtcat,strncpy,strncmp,strncat
1.strlen的使用和模拟实现 strlen 用来求字符串的长度,统计\0之前字符的个数。 模拟实现1:计数参数法 模拟实验2:指针方法 模拟实验3:递归方法 2,strcpy 的使用和模拟实现(拷贝字符串) char*…...

高级SQL技巧
高级SQL技巧涵盖了许多方面,包括但不限于窗口函数、递归查询、公共表表达式(CTEs)、子查询、集合操作、临时函数、日期时间操作、索引优化等。以下是对这些技巧的详细讲解和示例。 窗口函数 窗口函数是一种特殊的SQL函数,能够在…...

新大话西游图文架设教程
开始架设 1. 架设条件 新大话西游架设需要准备: linux 系统服务器,建议 CentOs 7.6或以上版本游戏源码,。 2. 安装宝塔面板 宝塔是一个服务器运维管理软件,安装命令: yum install -y wget && wget -O in…...

Maven 快速入门
Maven 快速入门 一、简介1、概述2、特点3、工作原理4、常用命令5、生命周期6、优缺点🎈 面试题 二、安装和配置1、安装2、环境配置3、命令测试是否安装成功4、功能配置5、idea配置本地 maven6、maven 工程依赖包查询网站 三、基于IDEA创建Maven工程1、maven 工程中的…...

OpenCV-人脸检测
文章目录 一、人脸检测流程二、关键方法三、代码示例四、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库,它提供了多种人脸检测方法,以下是对OpenCV人脸检测的详细介绍: 一、人脸检测流程 人脸检测是识别图像中人脸位置的过程&…...

【重磅升级】基于大数据的股票量化分析与预测系统
温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 伴随全球经济一体化和我国经济的快速发展,中国股票市场对世界经济的影响力不断攀升,中国股市已成为全球第二大股票交易市场。在当今的金融市场中,股票价格的波动…...

python全栈学习记录(二十四)元类、异常处理
元类、异常处理 文章目录 元类、异常处理一、元类1.元类控制类的实例化2.属性/方法的查找顺序3.单例 二、异常处理 一、元类 1.元类控制类的实例化 类的__call__方法会在产生的对象被调用时自动触发,args和kwargs就是调用实例时传入的参数,返回值是调用…...

Golang Slice扩容机制及注意事项
Golang Slice扩容机制及注意事项: 在 Go语言中,Slice(切片)是一种非常灵活且强大的数据结构,它是对数组的抽象,提供了动态数组的功能。Slice 的扩容机制是自动的,但了解其背后的原理对于编写高…...

华为OD机试 - 猜数字 - 暴力枚举(Python/JS/C/C++ 2024 E卷 100分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…...