GaitSet学习笔记(不包括三元数损失,仅含主干网络)

2024-01-24 19:10

本文主要是介绍GaitSet学习笔记(不包括三元数损失,仅含主干网络),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

论文

1 Introduction

1.1 旧方法

​ ① 将步态轮廓压缩为一张图(损失了时序信息与细粒度系信息)

​ ② 直接从原始步态轮廓序列中提取特征(极易受到外部条件影响)

image-20220209154551228

1.2 我们提出的方法

​ 步态序列可以看做一个周期,而特定帧有其特定的步态形态,人类很容易可以复原打乱的步态序列的顺序。因此,顺序信息不必需提供给网络,而将步态序列帧看做一个个具有位置信息的帧组成的集合,网络可以通过学习得到序列的时序信息。

image-20220209163759154

​ 基于步态具有位置信息的假设,我们提出了一个端到端的网络,并且具有以下的三大优点:

​ ① 灵活:输入不受到约束

​ ② 快速:直接对二维剪影序列进行特征提取,减少计算(相比于机器学习方法)

​ ③ 高效:缓解协变量影响,提高鲁棒性与泛化能力

image-20220209162309344

2 Related Work

​ 受到PointNet(处理点云信息)的启发,采用了无序集作为网路输入数据。点云模型是三维图形的一种表示模型,点云具有顺序无关性。PointNet利用无序集可以避免量化带来的噪声和数据扩展,并获得高性能。

image-20220209165029696

3 GaitSet

3.1 主干网络简介

​ F:通过卷积层,得到序列的帧级别特征

​ G:通过集合池化(Set Pooling),将帧级别特征映射到集合级别特征

​ H:通过水平金字塔映射,学习集合级别特征的判别性表示

image-20220209170923224

image-20220209191537282

3.2 集合池化(Set Pooling)

​ 作用:集合元素的步态信息,将帧级别特征映射为集合级别特征

​ 两个限制:

​ ① 必须是排列不变函数

​ ② 接受任何数量的集合输入

​ SP的几个实例:

​ ① Statistical Functions:为了满足排列不变,可以引入max,mean和median这类统计函数

​ ② Joint Functions:上述统计函数的两种连接方式

image-20220209174810359

​ ③ Attention:利用全局信息为每个帧级特征学习一个元素级的注意映射,并对其进行细化

image-20220209180742069

3.3 水平金字塔映射(Horizontal Pyramid Mapping)

image-20220209183018802

image-20220210150701061

​ ① 通过划分水平条的方式来获得多尺度的特征,该算法通常划分为S个尺度,由集合池化提取后的特征图在高度尺寸上被分成2^(k-1)条

​ ② 不同的水平条在不同的尺度上描述着不同的感受野,同时在每个尺度上描述不同空间位置的运动特征

​ ③ 结合使用平均与最大池化策略对不同尺度的空间条信息进行提取:平均池化可以感知空间条的全局信息最大池化可以提取最具判别性的信息,结合两种池化得到的融合特征将具有更强的判别能力

​ ④ 通过独立权重的全连接层将特征映射到更具判别力的空间,从而获得步态特征的判别性表示

⑤ MGP模块和主网络模块分别经过HPP操作,宽度和高度这两个维度被压缩成1,2,4,8,16这样的1个维度

3.4 多层全局管道(MGP)

MGP

​ 众所周知,浅层的网络学习局部信息以及细粒度信息,深层网络学习全局信息以及粗粒度信息。MGP的提出正是为了收集不同层次网络的集合级别特征信息

​ 注意,MGP后的HPM与主干网后的HPM不共享参数。

代码

1 主干网卷积网

image-20220210144357377

# 基本卷积核
class BasicConv2d(nn.Module):def __init__(self, in_channels, out_channels, kernel_size, **kwargs):super(BasicConv2d, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, bias=False, **kwargs)def forward(self, x):x = self.conv(x)return F.leaky_relu(x, inplace=True)# 卷积核 + 池化层
class SetBlock(nn.Module):def __init__(self, forward_block, pooling=False):super(SetBlock, self).__init__()self.forward_block = forward_blockself.pooling = poolingif pooling:self.pool2d = nn.MaxPool2d(2)  # 2×2池化def forward(self, x):n, s, c, h, w = x.size()  # n人物数量,s序列数量,c通道数量,h图片高,w图片宽x = self.forward_block(x.view(-1, c, h, w))  # [bs, 30, 1, 64, 44] => [bs * 30, 1, 64, 44]if self.pooling:x = self.pool2d(x)_, c, h, w = x.size()return x.view(n, s, c, h ,w)_set_in_channels = 1
_set_channels = [32, 64, 128]
self.set_layer1 = SetBlock(BasicConv2d(_set_in_channels, _set_channels[0], 5, padding=2))  # C1:1, 32, 5, 2
self.set_layer2 = SetBlock(BasicConv2d(_set_channels[0], _set_channels[0], 3, padding=1), True)  # C2:32, 32, 3, 1 + pooling
self.set_layer3 = SetBlock(BasicConv2d(_set_channels[0], _set_channels[1], 3, padding=1))  # C3:32, 64, 3, 1
self.set_layer4 = SetBlock(BasicConv2d(_set_channels[1], _set_channels[1], 3, padding=1), True)  # C4:64, 64, 3, 1 + pooling
self.set_layer5 = SetBlock(BasicConv2d(_set_channels[1], _set_channels[2], 3, padding=1))  # C5:64, 128, 3, 1
self.set_layer6 = SetBlock(BasicConv2d(_set_channels[2], _set_channels[2], 3, padding=1))  # C6:128, 128, 3, 1

2 MGP

image-20220210150905085

_gl_in_channels = 32
_gl_channels = [64, 128]
self.gl_layer1 = BasicConv2d(_gl_in_channels, _gl_channels[0], 3, padding=1)  # 32, 64, 3, 1
self.gl_layer2 = BasicConv2d(_gl_channels[0], _gl_channels[0], 3, padding=1)  # 64, 64, 3, 1
self.gl_layer3 = BasicConv2d(_gl_channels[0], _gl_channels[1], 3, padding=1)  # 64, 128, 3, 1
self.gl_layer4 = BasicConv2d(_gl_channels[1], _gl_channels[1], 3, padding=1)  # 128, 128 3, 1
self.gl_pooling = nn.MaxPool2d(2)

3 Set Pooling

image-20220210145813534

def frame_max(self, x):return torch.max(x, 1)  # 第二维度(frame)的最大值。论文表示,利用max作为SP,且不采用1×1卷积的综合效果最好:

image-20220210145716585

image-20220210150539624

4 HPM + FC

self.bin_num = [1, 2, 4, 8, 16]  # 水平条的尺度
# 全连接层,hidden_dim = 256
# sum(self.bin_num) * 2, 128, hidden_dim = 31 * 2, 128, 256 = 62, 128, 256
# 反向传播过程中,利用该全连接矩阵与最后特征做tensor乘法以实现维度扩展,注意实现参数初始化
self.fc_bin = nn.ParameterList([nn.Parameter(nn.init.xavier_uniform_(torch.zeros(sum(self.bin_num) * 2, 128, hidden_dim)))])

5 参数初始化

for m in self.modules():if isinstance(m, (nn.Conv2d, nn.Conv1d)):nn.init.xavier_uniform_(m.weight.data)elif isinstance(m, nn.Linear):nn.init.xavier_uniform_(m.weight.data)nn.init.constant(m.bias.data, 0.0)elif isinstance(m, (nn.BatchNorm2d, nn.BatchNorm1d)):nn.init.normal(m.weight.data, 1.0, 0.02)nn.init.constant(m.bias.data, 0.0)

6 前向传播过程

6.1 主干网 + MGP

image-20220210153031588

'''bs: batch_size'''x = silho.unsqueeze(2) # [bs, 30, 64, 44] => [bs, 30, 1, 64, 44]  扩展通道# 主干网卷积层1
x = self.set_layer1(x)  # 1:[bs, 30, 32, 64, 44] Conv
x = self.set_layer2(x)  # 2: [bs, 30, 32, 32, 22] Conv + Pooling# MGP卷积层1
gl = self.gl_layer1(self.frame_max(x)[0]) # 3: [bs, 64, 32, 22] SP + Conv
gl = self.gl_layer2(gl)  # 4: [bs, 64, 32, 22] Conv
gl = self.gl_pooling(gl)  # 5: [bs, 64, 16, 22] Pooling# 主干网卷积层2
x = self.set_layer3(x)  # 6: [bs, 30, 64, 32, 22] Conv
x = self.set_layer4(x)  # 7: [bs, 30, 64, 16, 11] Conv + Pooling # MGP卷积层2
gl = self.gl_layer3(gl + self.frame_max(x)[0])  # 8: [bs, 128, 16, 11] SP + Concat + Conv
gl = self.gl_layer4(gl)  # 9: [bs, 128, 16, 11] Conv# 主干网卷积层3
x = self.set_layer5(x)  # 10: [bs, 30, 128, 16, 11] Conv
x = self.set_layer6(x)  # 11: [bs, 30, 128, 16, 11] Conv
x = self.frame_max(x)[0]  # 12:[bs, 128, 16, 11] SPgl = gl + x  # 13: [bs, 128, 16, 11] Concat

6.2 HPM + FC

image-20220210155612583

image-20220210155359324

feature = list()
n, c, h, w = gl.size()  # 8, 128, 16, 11for num_bin in self.bin_num:  # 1 2 4 8 16,不同尺度的感受野# 主干网 + HPPz = x.view(n, c, num_bin, -1)  # 将长和宽压缩为一维,16*11 => 1,2,4,8,16  # [bs, 128, 1, 176], [bs, 128, 2, 88], [bs, 128, 4, 44], [bs, 128, 8, 22], [bs, 128, 16, 11]z = z.mean(3) + z.max(3)[0]  # 第四维度的平均池化 + 最大池化  # [bs, 128, 1], [bs, 128, 2], [bs, 128, 4], [bs, 128, 8], [bs, 128, 16]feature.append(z)  # 将水平条放入feature列表# 主干网 + MGP + HPPz = gl.view(n, c, num_bin, -1)  # 操作同上z = z.mean(3) + z.max(3)[0]feature.append(z)feature = torch.cat(feature, 2).permute(2, 0, 1).contiguous()  # [62, bs, 128] 连接水平条并对换维度
feature = feature.matmul(self.fc_bin[0])  # [62, bs, 256] 使用矩阵乘法实现全连接层
feature = feature.permute(1, 0, 2).contiguous()  # [bs, 62, 256]  对换维度,得到最终网络输出

这篇关于GaitSet学习笔记(不包括三元数损失,仅含主干网络)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640703

相关文章

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依