【传知代码】骨架行为识别-论文复现

简介: 骨架行为识别是计算机视觉中的关键技术,通过分析人体骨架轨迹和姿态来识别行为。它应用于人机交互、智能监控等领域,利用OpenPose等算法提取关键点信息。CTR-GCN是该领域的先进模型,优于2S-AGCN,通过通道拓扑优化和时间建模提高识别效果。模型包含通道细化、特征变换和维度增强三个部分。源码可在相关文章附件获取。骨架行为识别技术在视频理解、人机交互、运动分析等多个场景有广泛应用,并持续发展创新。
本文涉及的源码可从骨架行为识别-论文复现该文章下方附件获取

骨架行为识别-论文复现
20240516-2.gif

骨架行为识别的定义

骨架行为识别是指通过分析人体骨架的运动轨迹和姿态,来识别和理解人体的行为动作

以下是一些关于骨架行为识别的相关内容:

  1. 基本概念:骨架行为识别是计算机视觉和模式识别领域的一个重要研究方向。它通常涉及到从图像或视频中提取人体的关键点信息,然后通过分析这些关键点的运动轨迹和相对位置来识别特定的行为或动作。
  2. 应用领域:骨架行为识别技术在多个领域都有广泛的应用,包括但不限于人机交互、智能监控、运动分析、虚拟现实、机器人技术等。例如,在智能监控系统中,可以通过骨架行为识别来分析行人的活动,以增强安全性;在人机交互领域,可以通过识别用户的手势来控制游戏或应用程序。
  3. 技术方法:为了实现骨架行为识别,研究人员采用了多种技术方法,包括传统的机器学习技术和基于深度学习的方法。其中,OpenPose算法是一种著名的基于深度学习的姿态估计算法,它可以从图像或视频中检测和跟踪人体的关键点和姿态信息。
  4. 数据集与评价指标:在骨架行为识别的研究过程中,通常会使用公开的数据集来训练和测试模型的性能。这些数据集可能包含不同的样本量,从而分为大型数据集和小型数据集。性能评估通常涉及到准确率、召回率等评价指标,以衡量不同方法的效果和适用场景。
  5. 发展趋势:随着技术的不断进步,骨架行为识别方法也在不断地优化和创新。研究人员正在探索如何提高识别的准确性和实时性,以及如何处理更复杂的场景和行为模式。

论文概述

2021年发表在ICCV的"Channel-wise Topology Refinement Graph Convolution for Skeleton-Based Action Recognition" paper链接:CTR-GCN
几乎成为了近两年顶刊顶会人体骨架行为识别论文的基线模型,例如HD-GCN(2023 ICCV),INFO-GCN(2022 CVPR),GAP(2023 ICCV)。

CTR-GCN相较于上一代基线模型2S-AGCN有何改进呢?2s-agcn链接

1.提出了一种新的通道拓扑优化图卷积(ctr - gc)来动态学习不同的拓扑并有效地聚合不同通道中的联合特征,用于基于骨架的动作识别。
2.提出的ctr - gc通过学习共享拓扑作为所有通道的通用先验,并使用每个通道特定于通道的相关性对其进行细化,从而对通道拓扑进行建模。
3.ctr - gc与时间建模模块相结合,我们开发了一个强大的图形卷积网络

简单总结一下,CTR-GCN的突出贡献有2点:

  • 提出一种通道拓扑细化模块,该模块通过对通道维度的压缩与聚合,对每个通道运用不同的图卷积网络进行特征提取。

  • ctr-gc与简化后的多尺度时间卷积模块MS-TCN模块结合MS-TCN,构成了CTR-GCN架构,该模型参数量小,同时相较于baseline提升巨大。

骨干网络架构分析

CTR-GCN整体架构由通道细化拓扑建模(蓝色)特征变换(粉色)通道维度增强(黄色): 三部分构成如下图,分别对应以下三种:

image-20240516161023117.png

1. 通道细化拓扑建模(蓝色):
通过激活函数M,这里为tanh激活函数,对原始特征进行拓扑细化,得到三个通道特征不同的特征x1,x2,x3。

# start
 self.conv1 = nn.Conv2d(self.in_channels, self.rel_channels, kernel_size=1)
        self.conv2 = nn.Conv2d(self.in_channels, self.rel_channels, kernel_size=1)
        self.conv3 = nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1)
        self.conv4 = nn.Conv2d(self.rel_channels, self.out_channels, kernel_size=1)
 x1, x2, x3 = self.conv1(x).mean(-2), self.conv2(x).mean(-2), self.conv3(x)
        x1 = self.tanh(x1.unsqueeze(-1) - x2.unsqueeze(-2))
        x1 = self.conv4(x1) * alpha + (A.unsqueeze(0).unsqueeze(0) if A is not None else 0)  # N,C,V,V
        x1 = torch.einsum('ncuv,nctv->nctu', x1, x3)
        return x1

2. 特征变换(粉色):

通过对通道进行压缩进行维度变换,进行通道拓扑细化的准备阶段

# start
 self.in_channels = in_channels
        self.out_channels = out_channels
        if in_channels == 3 or in_channels == 9:
            self.rel_channels = 8
            self.mid_channels = 16
        else:
            self.rel_channels = in_channels // rel_reduction
            self.mid_channels = in_channels // mid_reduction

3. 通道维度增强(橘黄色):

将三个进行通道拓扑细化后的特征向量与对应的超参数a卷积,得到输出y

# start
 def forward(self, x):
        y = None
        if self.adaptive:
            A = self.PA
        else:
            A = self.A.cuda(x.get_device())
        # 这里的num_subset为3,3根据图3a中代表CTR-GC的个数
        for i in range(self.num_subset):
            z = self.convs[i](x, A[i], self.alpha)
            y = z + y if y is not None else z
        y = self.bn(y)
        y += self.down(x)
        y = self.relu(y)
        return y

建模部分代码

image-20240516164438980.png

图a蓝色部分为空间建模,空间建模模块由CTR-GC基本块构成,CTR-GC的结构如图b。图a黄色部分为简化的多尺度时间建模,相对于原本的MS-TCN架构删除了一部分卷积分支。

CTR-GC:空间建模的基本单元,代码如下:
# start
# rel_reduction和mid_reduction分别表示基于相对位置关系和中间特征的注意力子模块中间使用的通道数缩减比例,用于控制模型的参数量。
class CTRGC(nn.Module):
    def __init__(self, in_channels, out_channels, rel_reduction=8, mid_reduction=1):
        super(CTRGC, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        if in_channels == 3 or in_channels == 9:
            self.rel_channels = 8
            self.mid_channels = 16
        else:
            self.rel_channels = in_channels // rel_reduction
            self.mid_channels = in_channels // mid_reduction
        self.conv1 = nn.Conv2d(self.in_channels, self.rel_channels, kernel_size=1)
        self.conv2 = nn.Conv2d(self.in_channels, self.rel_channels, kernel_size=1)
        self.conv3 = nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1)
        self.conv4 = nn.Conv2d(self.rel_channels, self.out_channels, kernel_size=1)
        self.tanh = nn.Tanh()
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                conv_init(m)
            elif isinstance(m, nn.BatchNorm2d):
                bn_init(m, 1)

    def forward(self, x, A=None, alpha=1):
        # x.mean(-2)表示对张量x沿着倒数第二个维度进行求平均值的操作。
        x1, x2, x3 = self.conv1(x).mean(-2), self.conv2(x).mean(-2), self.conv3(x)
        x1 = self.tanh(x1.unsqueeze(-1) - x2.unsqueeze(-2))
        x1 = self.conv4(x1) * alpha + (A.unsqueeze(0).unsqueeze(0) if A is not None else 0)  # N,C,V,V
        x1 = torch.einsum('ncuv,nctv->nctu', x1, x3)
        return x1
spatial modeling:空间建模,由CTR-GC和残差连接组成,残差连接的目的是为了保存部分原始特征。
# start
class unit_gcn(nn.Module):
    def __init__(self, in_channels, out_channels, A, coff_embedding=4, adaptive=True, residual=True):
        super(unit_gcn, self).__init__()
        inter_channels = out_channels // coff_embedding
        self.inter_c = inter_channels
        self.out_c = out_channels
        self.in_c = in_channels
        self.adaptive = adaptive
        self.num_subset = A.shape[0]
        self.convs = nn.ModuleList()
        for i in range(self.num_subset):
            self.convs.append(CTRGC(in_channels, out_channels))

        if residual:
            if in_channels != out_channels:
                self.down = nn.Sequential(
                    nn.Conv2d(in_channels, out_channels, 1),
                    nn.BatchNorm2d(out_channels)
                )
            else:
                self.down = lambda x: x
        else:
            self.down = lambda x: 0
        if self.adaptive:
            self.PA = nn.Parameter(torch.from_numpy(A.astype(np.float32)))
        else:
            self.A = Variable(torch.from_numpy(A.astype(np.float32)), requires_grad=False)
        self.alpha = nn.Parameter(torch.zeros(1))
        self.bn = nn.BatchNorm2d(out_channels)
        self.soft = nn.Softmax(-2)
        self.relu = nn.ReLU(inplace=True)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                conv_init(m)
            elif isinstance(m, nn.BatchNorm2d):
                bn_init(m, 1)
        bn_init(self.bn, 1e-6)

    def forward(self, x):
        y = None
        if self.adaptive:
            A = self.PA
        else:
            A = self.A.cuda(x.get_device())
        # 这里的num_subset为3,3根据图3a中代表CTR-GC的个数
        for i in range(self.num_subset):
            z = self.convs[i](x, A[i], self.alpha)
            y = z + y if y is not None else z
        y = self.bn(y)
        y += self.down(x)
        y = self.relu(y)
        return y
temporal modeling:时间建模,是简化版的MS-TCN架构
# start
class MultiScale_TemporalConv(nn.Module):
    def __init__(self,
                 in_channels,
                 out_channels,
                 kernel_size=3,
                 stride=1,
                 dilations=[1,2,3,4],
                 residual=True,
                 residual_kernel_size=1):

        super().__init__()
        # 检查每一个分支膨胀率+2 是否能整除
        assert out_channels % (len(dilations) + 2) == 0, '# out channels should be multiples of # branches'

        # Multiple branches of temporal convolution
        # 分支的数量=膨胀率+2
        self.num_branches = len(dilations) + 2
        # 分支的通道数 = 输出通道 / 分支数
        # 这个计算的目的是确保每个分支的输出通道数相等,从而使得多分支结构中各个分支的特征映射可以合并在一起。
        branch_channels = out_channels // self.num_branches
        #
        if type(kernel_size) == list:
            assert len(kernel_size) == len(dilations)
        else:
            kernel_size = [kernel_size]*len(dilations)
        # Temporal Convolution branches
        self.branches = nn.ModuleList([
            nn.Sequential(
                nn.Conv2d(
                    in_channels,
                    branch_channels,
                    kernel_size=1,
                    padding=0),
                nn.BatchNorm2d(branch_channels),
                nn.ReLU(inplace=True),
                TemporalConv(
                    branch_channels,
                    branch_channels,
                    kernel_size=ks,
                    stride=stride,
                    dilation=dilation),
            )
            for ks, dilation in zip(kernel_size, dilations)
        ])

        # Additional Max & 1x1 branch
        self.branches.append(nn.Sequential(
            nn.Conv2d(in_channels, branch_channels, kernel_size=1, padding=0),
            nn.BatchNorm2d(branch_channels),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=(3,1), stride=(stride,1), padding=(1,0)),
            nn.BatchNorm2d(branch_channels)  # 为什么还要加bn
        ))

        self.branches.append(nn.Sequential(
            nn.Conv2d(in_channels, branch_channels, kernel_size=1, padding=0, stride=(stride,1)),
            nn.BatchNorm2d(branch_channels)
        ))

        # Residual connection
        if not residual:
            self.residual = lambda x: 0
        elif (in_channels == out_channels) and (stride == 1):
            self.residual = lambda x: x
        else:
            self.residual = TemporalConv(in_channels, out_channels, kernel_size=residual_kernel_size, stride=stride)

        # initialize
        self.apply(weights_init)

    def forward(self, x):
        # Input dim: (N,C,T,V)
        res = self.residual(x)
        branch_outs = []
        for tempconv in self.branches:
            out = tempconv(x)
            branch_outs.append(out)

        out = torch.cat(branch_outs, dim=1)
        out += res
        return out
本文涉及的源码可从骨架行为识别-论文复现该文章下方附件获取

代码部署

  • 数据集下载

  • 生成骨架数据

  • 训练和测试

代码部署详细步骤请参考骨架行为识别第三部分

小结

骨架行为识别技术是一种重要的人工智能技术,它在多个领域具有广泛的应用场景,并且展现出巨大的意义和作用。

  • 视频理解:骨架行为识别在视频理解中扮演着关键角色,它能够帮助计算机系统理解和解释人类行为,从而应用于各种视频分析任务,如监控、娱乐和教育等。
  • 人机交互:通过识别用户的骨架动作,可以实现更自然的人机交互方式,例如在游戏、虚拟现实和智能家居控制中的应用,提升用户体验。
  • 运动分析:在体育训练、健身指导和医疗康复等领域,骨架行为识别可以用于分析运动技巧,帮助用户改进动作或进行康复训练。
  • 安全监控:在公共安全领域,骨架行为识别可以帮助监控人员及时发现异常行为,如打斗、跌倒等,从而快速做出响应。
  • 研究发展:骨架行为识别技术的发展推动了相关领域的研究,如计算机视觉、深度学习和模式识别等,促进了新技术和新方法的产生。
  • 数据驱动:随着大量数据集的收集和标注,如NTU-RGB+D,研究者能够开发出更为精确和鲁棒的行为识别模型,这些模型能够自动学习数据中的时空模式,提高识别的准确性和泛化能力。
  • 技术创新:为了克服传统方法的局限性,研究人员提出了许多创新的网络架构,如时空图卷积网络(ST-GCN),这些技术不仅提高了模型的表达能力,还增强了其对新数据的适应能力。
  • 多学科融合:骨架行为识别的研究和应用涉及到多个学科的知识融合,包括计算机科学、认知科学、机械工程等,这种跨学科的研究有助于推动整个科技领域的发展。

骨架行为识别技术在多个领域具有广泛的应用场景和重要的意义和作用。随着技术的不断发展和完善,相信它将为我们的生活带来更多的便利和可能性。

相关文章
|
30天前
|
自然语言处理
杨笛一团队最新百页论文:首次统计学上证明,LLM生成的idea新颖性优于人类
【10月更文挑战第12天】斯坦福大学杨笛一团队发布百页论文,首次通过统计学方法证明大型语言模型(LLMs)在生成研究想法的新颖性上优于人类专家。研究招募100多名NLP专家进行盲评,结果显示LLM在新颖性方面显著胜出,但在可行性上稍逊。研究揭示了LLM在科研创新中的潜力与局限。
38 2
|
2月前
|
传感器 人工智能 算法
AI计算机视觉笔记二十七:YOLOV8实现目标追踪
本文介绍了使用YOLOv8实现人员检测与追踪的方法。通过为每个人员分配唯一ID,实现持续追踪,并可统计人数,适用于小区或办公楼出入管理。首先解释了目标检测与追踪的区别,接着详细描述了使用匈牙利算法和卡尔曼滤波实现目标关联的过程。文章提供了基于IOU实现追踪的具体步骤,包括环境搭建、模型加载及追踪逻辑实现。通过示例代码展示了如何使用YOLOv8进行实时视频处理,并实现人员追踪功能。测试结果显示,该方法在实际场景中具有较好的应用潜力。
|
3月前
|
人工智能 自然语言处理 Python
🔍显微镜下的AI魔法:深入剖析生成式模型提示词工程,细节决定成败🔍
【8月更文挑战第1天】在人工智能领域,生成式模型作为连接现实与想象的桥梁展现出独特创造力。提示词工程在此扮演关键角色,通过精细调整引发内容生成的重大变化。以创意广告生成为例:初始宽泛提示词难以激发独特文案,经深度剖析与微调后,加入情感元素的提示词能更好引导模型创造共鸣内容。示例代码模拟此过程,展示优化提示词的重要性,强调细节在生成式AI中的决定性作用。
66 8
|
6月前
|
机器学习/深度学习 自然语言处理 搜索推荐
【传知代码】图神经网络长对话理解-论文复现
在ACL2023会议上发表的论文《使用带有辅助跨模态交互的关系时态图神经网络进行对话理解》提出了一种新方法,名为correct,用于多模态情感识别。correct框架通过全局和局部上下文信息捕捉对话情感,同时有效处理跨模态交互和时间依赖。模型利用图神经网络结构,通过构建图来表示对话中的交互和时间关系,提高了情感预测的准确性。在IEMOCAP和CMU-MOSEI数据集上的实验结果证明了correct的有效性。源码和更多细节可在文章链接提供的附件中获取。
【传知代码】图神经网络长对话理解-论文复现
|
6月前
|
机器学习/深度学习 自然语言处理 PyTorch
【传知代码】transformer-论文复现
Transformer模型,革新NLP的里程碑,摒弃CNN/RNN,采用自注意力机制解决长距离依赖问题,加速训练。模型包含编码器和解码器,用位置编码补充序列信息。关键组件包括:嵌入层(位置编码增强词向量)、多头注意力层(捕获不同侧面的上下文)、前馈层(非线性变换)及残差连接和层归一化(提升训练稳定性)。Transformer的创新应用,推动了现代大语言模型的发展。
152 1
【传知代码】transformer-论文复现
|
6月前
|
机器学习/深度学习 人工智能 PyTorch
【传知代码】Modnet 人像抠图-论文复现
MODNet是一种轻量级、实时的无trimap人像抠图模型,强调高效和鲁棒性。它由语义预测、细节预测和语义-细节混合三个模块构成,通过自监督学习策略SOC保持模块间一致性。MODNet在人像抠图任务中表现出色,适用于多种场景,如展馆互动、商场引流、图像编辑、广告制作等。论文和源码可在给定链接中获取,项目还提供了WebUI方便用户直接使用。
179 2
【传知代码】Modnet 人像抠图-论文复现
|
6月前
|
机器学习/深度学习 算法 数据可视化
【传知代码】知识图谱推理-论文复现
本文探讨了基于图神经网络(GNN)的知识图谱推理,提出了一种创新的自适应传播策略AdaProp,旨在解决大规模知识图谱处理中的效率和准确性问题。AdaProp通过动态调整传播路径,优化了传统GNN方法。研究在KDD '23会议上发表,提供了tensorboard可视化结果和开源代码。实验表明,AdaProp在效率和性能上超越了传统方法,如全传播、渐进式传播和受限传播。通过Python和PyTorch实现, AdaProp在多个数据集上展示了优秀性能,为知识图谱推理领域开辟了新思路。
【传知代码】知识图谱推理-论文复现
|
6月前
|
机器学习/深度学习 数据采集 自然语言处理
【传知代码】BERT论文解读及情感分类实战-论文复现
本文介绍了BERT模型的架构和技术细节,包括双向编码器、预训练任务(掩码语言模型和下一句预测)以及模型微调。文章还提供了使用BERT在IMDB数据集上进行情感分类的实战,包括数据集处理、模型训练和评估,测试集准确率超过93%。BERT是基于Transformer的预训练模型,适用于多种NLP任务。在实践中,BERT模型加载预训练权重,对输入数据进行预处理,然后通过微调适应情感分类任务。
294 0
【传知代码】BERT论文解读及情感分类实战-论文复现
|
6月前
|
机器学习/深度学习 监控 自动驾驶
【传知代码】从零开始搭建图像去雾神经网络-论文复现
本文介绍了基于集成学习的双分支非均匀去雾神经网络的复现,该网络由迁移学习子网和数据拟合子网组成,分别处理全局表示和数据拟合。网络使用Res2Net作为编码器,并结合通道和像素注意力模块。代码可在提供的链接下载。网络在交通监控、自动驾驶、航海和目标跟踪等领域有广泛应用,通过提升图像质量来提高系统性能。实验在O-Haze、I-Haze和NH-Haze数据集上进行,展示了网络在去除雾霾方面的效果,尽管存在细节模糊和色彩饱和度低的问题。
156 1
|
6月前
|
自然语言处理 数据可视化 算法
【传知代码】私人订制词云图-论文复现
本文介绍了词云图的原理和生成步骤,包括分词、统计词频、去除停用词等,并提供了Python实现示例,利用`wordcloud`和`jieba`库。此外,还分享了技巧,如处理中文乱码、选择背景图、词库转换及自定义文字颜色。词云图能直观展示文本关键信息,适用于数据分析和文本挖掘,但也有其局限性,如无法显示词汇的语法关系。源码和更多资源可在文章附件获取。
【传知代码】私人订制词云图-论文复现