【OpenGait 之 GaitSet 系列】 了解 GaitSet 代码与原论文算法框架图的对应关系以及算法流程

最近在使用AutoDL云服务器跑步态识别的代码,用的是开放步态识别框架OpenGait,记录一下自己跑代码的步骤和遇到的问题以及解决方式。

这篇文章主要记录OpenGait项目里GaitSet代码与原论文框架图的对应关系以及算法流程。


一、GaitSet论文算法框架图

论文题目:《Gaitset: Regarding gait as a set for cross-view gait recognition》
下载地址:GaitSet2019

注:GaitSet最初版本是2019年发布的,2021年该团队又在2019年版本基础上发表了另一篇文章,题目为《GaitSet: Cross-view gait recognition through utilizing gait as a deep set》,21年和19年文章内容大致相同。2021版本下载地址为:GaitSet2021

Gaitset算法框架图如下:
在这里插入图片描述

二、OpenGait项目里的GaitSet代码

为什么要强调“OpenGait项目里的GaitSet代码”?因为源代码和OpenGait项目里的在组织结构上不太一样,本文只是针对OpenGait项目里的。

OpenGait项目里的GaitSet代码文件路径为:OpenGait/opengait/modeling/models/gaitset.py

gaitset.py内容如下:

import torch
import copy
import torch.nn as nn

from ..base_model import BaseModel
from ..modules import SeparateFCs, BasicConv2d, SetBlockWrapper, HorizontalPoolingPyramid, PackSequenceWrapper

class GaitSet(BaseModel):
    def build_network(self, model_cfg):
        in_c = model_cfg['in_channels']
        self.set_block1 = nn.Sequential(BasicConv2d(in_c[0], in_c[1], 5, 1, 2),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[1], in_c[1], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        nn.MaxPool2d(kernel_size=2, stride=2))

        self.set_block2 = nn.Sequential(BasicConv2d(in_c[1], in_c[2], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[2], in_c[2], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        nn.MaxPool2d(kernel_size=2, stride=2))

        self.set_block3 = nn.Sequential(BasicConv2d(in_c[2], in_c[3], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[3], in_c[3], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True))

        self.gl_block2 = copy.deepcopy(self.set_block2)
        self.gl_block3 = copy.deepcopy(self.set_block3)
        
        self.set_block1 = SetBlockWrapper(self.set_block1)
        self.set_block2 = SetBlockWrapper(self.set_block2)
        self.set_block3 = SetBlockWrapper(self.set_block3)
        
        self.Head = SeparateFCs(**model_cfg['SeparateFCs'])

        self.set_pooling = PackSequenceWrapper(torch.max)

        self.HPP = HorizontalPoolingPyramid(bin_num=model_cfg['bin_num'])
        
    def forward(self, inputs):
        ipts, labs, _, _, seqL = inputs
        sils = ipts[0]  # [n, s, h, w]
        if len(sils.size()) == 4:
            sils = sils.unsqueeze(1)

        del ipts
        
        outs = self.set_block1(sils)
        gl = self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = self.gl_block2(gl)

        outs = self.set_block2(outs)
        gl = gl + self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = self.gl_block3(gl)

        outs = self.set_block3(outs)
        outs = self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = gl + outs

        feature1 = self.HPP(outs)  # [n, c, p]
        feature2 = self.HPP(gl)  # [n, c, p]
        feature = torch.cat([feature1, feature2], -1)  # [n, c, p]
        embs = self.Head(feature)

        n, _, s, h, w = sils.size()
        retval = {
            'training_feat': {
                'triplet': {'embeddings': embs, 'labels': labs}
            },
            'visual_summary': {
                'image/sils': sils.view(n*s, 1, h, w)
            },
            'inference_feat': {
                'embeddings': embs
            }
        }
        return retval

三、GaitSet 代码与论文算法框架图的对应关系

1、3个set_block:提取每一帧的特征
①代码:

        self.set_block1 = nn.Sequential(BasicConv2d(in_c[0], in_c[1], 5, 1, 2),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[1], in_c[1], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        nn.MaxPool2d(kernel_size=2, stride=2))

        self.set_block2 = nn.Sequential(BasicConv2d(in_c[1], in_c[2], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[2], in_c[2], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        nn.MaxPool2d(kernel_size=2, stride=2))

        self.set_block3 = nn.Sequential(BasicConv2d(in_c[2], in_c[3], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True),
                                        BasicConv2d(in_c[3], in_c[3], 3, 1, 1),
                                        nn.LeakyReLU(inplace=True))

②对应原文算法图位置:
在这里插入图片描述
2、2个gl_block:提取所有帧集合后的特征
①代码

        self.gl_block2 = copy.deepcopy(self.set_block2)
        self.gl_block3 = copy.deepcopy(self.set_block3)

②对应原文算法图位置:
在这里插入图片描述
③注:gl_block只有2个,分别是gl_block2和gl_block3,没有gl_block1,我认为是为了和set_block的数字对应

3、SetBlockWrapper操作:不对应原文图片内容,只是为了把3个set_block 封装起来

        self.set_block1 = SetBlockWrapper(self.set_block1)
        self.set_block2 = SetBlockWrapper(self.set_block2)
        self.set_block3 = SetBlockWrapper(self.set_block3)

4、SeparateFCs:独立全连接操作
①代码

        self.Head = SeparateFCs(**model_cfg['SeparateFCs'])

②对应原文算法图位置:
在这里插入图片描述
5、set_pooling:集合池化操作
①代码:

       self.set_pooling = PackSequenceWrapper(torch.max)

②对应原文算法图位置:
在这里插入图片描述
6、HPP:水平金字塔池化操作
①代码:

       self.HPP = HorizontalPoolingPyramid(bin_num=model_cfg['bin_num'])

②对应原文算法图位置:
在这里插入图片描述

四、GaitSet 代码与算法流程对应关系

1、流程1
①代码

        outs = self.set_block1(sils)
        gl = self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = self.gl_block2(gl)

②流程对应关系:
在这里插入图片描述
③解释:sils经过set_block1输出为蓝色out,所有蓝色out经过set_pooling操作输出为绿色gl,绿色gl经过gl_block2输出为正方体绿色gl,接下来的流程参考该解释

2、流程2
①代码

        outs = self.set_block2(outs)
        gl = gl + self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = self.gl_block3(gl)

②流程对应关系:
在这里插入图片描述
3、流程3
①代码:

        outs = self.set_block3(outs)
        outs = self.set_pooling(outs, seqL, options={"dim": 2})[0]
        gl = gl + outs

②流程对应关系:
在这里插入图片描述
4、流程4
①代码

        feature1 = self.HPP(outs)  # [n, c, p]
        feature2 = self.HPP(gl)  # [n, c, p]
        feature = torch.cat([feature1, feature2], -1)  # [n, c, p]
        embs = self.Head(feature)

②流程对应关系:
在这里插入图片描述


总结

欢迎使用OpenGait研究步态识别的伙伴进行交流

  • 40
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
### 回答1: A:如果您想使用自己的数据集来训练GaitSet模型,可以参考以下步骤: 1. 准备数据集:您需要准备一个含有多个个体的步态数据集,每个个体的数据应该包括多个步态循环。 2. 数据预处理:您需要对数据进行预处理,如去除噪声,对齐步态循环等。你需要将数据转换为适当的格式,以便可以用于GaitSet。 3. 划分训练集和测试集:将数据集划分为训练集和测试集。 4. 训练GaitSet模型:使用训练集,您可以训练GaitSet模型。在训练过程中要注意超参数的调整和监测训练过程的指标,如损失和准确率等。 5. 测试GaitSet模型:使用测试集,您可以测试GaitSet模型的性能,如准确率和召回率等。 6. 优化模型:通过对模型的改进和优化,您可以提高模型的性能。 7. 应用模型:将优化后的模型应用于实际场景中,如步态识别或者行人重识别。 ### 回答2: Gaitset是一个用于步态识别的数据集,要使用自己的数据集进行步态识别,可以按照以下步骤进行: 1.数据采集:使用一个或多个传感器(如加速度计或惯性测量单元)来收集样本数据。数据采集过程中,需要确保被测试者在相同的环境下进行采集,保持姿势和步态一致。 2.数据预处理:对采集到的数据进行预处理,包括去噪、滤波和标准化等操作。去噪可以去除由传感器噪声引起的不良信号,滤波可以平滑数据,标准化可以将数据映射到一个统一的范围。 3.特征提取:从预处理后的数据中提取有效的步态特征。常用的特征包括步态周期、步幅、步频和步态时序等。可以使用不同的特征提取方法,如时域特征、频域特征和时频域特征来获取更全面的信息。 4.模型训练:将提取到的特征与标记好的步态样本进行训练。可以使用机器学习算法如支持向量机(SVM)或深度学习模型如卷积神经网络(CNN)来构建步态识别模型。在训练过程中,可以采用交叉验证等方法来评估模型的性能。 5.模型测试与评估:使用训练好的模型对新的未知数据进行测试,并评估模型的性能指标,如准确率、召回率和F1分数等。可以采用混淆矩阵或ROC曲线等方法来评估模型的分类效果。 6.模型优化:根据测试结果,可以对模型进行调整和优化,如调整模型的参数或增加更多的训练数据等,以提高模型的识别准确率和鲁棒性。 通过以上步骤,就能够使用Gaitset数据集以及自己的数据集进行步态识别的训练和测试。 ### 回答3: Gaitset是一个用于人体步态识别的数据集,使用它可以实现对人体步态的自动识别和辨识。以下是使用Gaitset数据集的步骤: 1. 下载数据集:可以从Gaitset官方网站或其他可信的数据源下载数据集。确保数据集是完整的且包含所需的所有图像和标签。 2. 数据集预处理:在使用数据集之前,需要进行数据的预处理。这包括图像的裁剪、调整大小、灰度化、归一化等。还可以将数据集划分为训练集和测试集,用于训练和评估模型。 3. 特征提取:提取图像数据的特征,以便用于人体步态的识别。可以通过使用卷积神经网络(CNN)或其他特征提取技术,将图像转换为更具代表性的特征向量。 4. 模型训练:使用预处理后的数据集,训练一个适合步态识别的模型。可以选择传统的机器学习模型(如支持向量机)或深度学习模型(如卷积神经网络)。 5. 模型评估:使用测试集进行模型的评估,评估模型的准确率、精确率、召回率等指标,以确定模型的性能如何。 6. 预测和应用:使用训练好的模型对新的步态数据进行预测和识别。可以将该模型应用于实际场景,如安全监控、身份识别等。 需要注意的是,使用Gaitset数据集进行人体步态识别需要对相关的机器学习和图像处理技术有一定的了解,同时还需要使用合适的编程语言和工具进行实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小菜包

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值