双流融合与稀疏采样:视频行为识别的高效深度网络解析
2026/9/18 16:18:04 网站建设 项目流程

简介:《基于卷积神经网络的人体行为识别方法》是一篇面向深度学习与计算机视觉研究者的学术论文,聚焦视频中的人体行为识别任务,针对长时间视频密集采样导致计算成本过高的问题,提出深度残差网络与BN-Inception网络相组合的空间时间网络。空间网络采用ResNet提取视频帧外观特征,时间网络采用BN-Inception提取光流运动特征,并利用稀疏采样与得分融合提升识别精度,在UCF-101和HMDB-51数据集上分别取得94.5%和70.1%的准确率。资源包为一个PDF文件,共1.09MB,内含论文正文、网络结构图、公式推导与实验数据,读者可系统了解ResNet快捷连接如何缓解梯度消失、BN-Inception如何建模光流,以及双流融合的完整思路,适合行为识别、视频理解方向的学生和工程师深入参考。论文所提方案对视频监控、人机交互、无人驾驶等实际任务亦有借鉴意义,目前已有752人学习,是相关领域值得收藏的文献。

1. 从密集采样到稀疏双流:行为识别计算成本的解法

视频行为识别是计算机视觉的长期热点,视频监控、人机交互、无人驾驶都依赖它把“画面里发生了什么”转成结构化判断。但连续帧外观高度相似,逐帧卷积会让计算成本随视频长度线性膨胀。2019年杭州电子科技大学这篇论文给的解法很务实:用101层深度残差网络(ResNet)构建空间网络提取静态外观,用BN-Inception构建时间网络学习光流运动,按时间把视频切成3段稀疏采样,最后将两路Softmax得分平均融合,在UCF-101上达到94.5%、HMDB-51上70.1%,优于同期iDTs、C3D和TSN。适合正在做视频分类、行为识别或双流网络调参的工程师。

2. ResNet空间流与BN-Inception时间流:双分支选型的内在逻辑

2.1 空间流为什么从BN-Inception换成ResNet

论文在设计空间网络时先考虑了BN-Inception,这是TSN等经典方案常用的空间流主干,批归一化让训练稳定,ImageNet分类表现也不差。但在对比实验中,ResNet在ImageNet上的分类准确率高于BN-Inception,而且ResNet可以做得更深。行为识别里外观信息高度依赖语义层次:浅层特征看到边缘和纹理,深层特征才能看到“人举着手臂”这类动作相关的语义,更深的主干意味着更强的语义提取能力。

直接用BN-Inception堆深行不通。网络加深后梯度消失会先出现,即使通过初始化和中间归一化缓解梯度爆炸,更深网络的训练误差也会饱和甚至上升,这就是退化问题。ResNet通过快捷连接改变学习目标:不再直接学习期望映射H(x),而是学习残差F(x)=H(x)-x,当残差趋于0时网络退化为恒等映射,深层结构至少不会比浅层差,梯度也可以跳过中间层直达浅层。

提示:退化问题和过拟合表现不同。过拟合是训练误差低、测试误差高;退化是训练误差和测试误差一起升高。看到“网络变深反而变差”时,优先查有没有shortcut机制,而不是急着加Dropout。

2.2 残差学习单元的两种形态与101层结构

ResNet的残差单元按网络深度有两种设计。较浅网络用两层结构,两个3×3卷积直接串联,结构简单、参数量小。较深网络改用三层bottleneck结构,先用1×1卷积把通道数压低,再经过3×3卷积,最后用1×1卷积把通道数恢复甚至升高。论文中空间流采用101层ResNet,全部使用三层残差单元,这是深层网络控制计算量的标准做法。

101层ResNet的结构可以按Stage拆解,论文中的流水线关键参数整理如下:

网络层残差单元数内部通道配置输出尺寸
conv1-7×7, 64通道, 步长2112×112
max pool-3×3, 步长256×56
res2364→64→25656×56
res34128→128→51228×28
res423256→256→102414×14
res53512→512→20487×7
avg pool + fc-softmax1×1

表中的“内部通道配置”对应bottleneck的三个卷积:降维、3×3卷积、升维。res4有23个残差单元,是整网最深的部分,承担了绝大部分语义抽象。最终经过平均池化和全连接层,用Softmax输出每个动作类别的概率。

bottleneck单元的计算逻辑用伪代码可以这样表达:

def bottleneck(x, in_ch, mid_ch, out_ch, stride=1): # 1x1 卷积降维,压缩 3x3 卷积的输入通道 y = conv_bn_relu(x, mid_ch, 1, stride=stride) # 3x3 卷积提取空间特征,通道数保持不变 y = conv_bn_relu(y, mid_ch, 3, stride=1) # 1x1 卷积升维,得到本阶段输出通道数 y = conv_bn(y, out_ch, 1, stride=1) # 维度不一致时,shortcut 路径上用 1x1 卷积做线性映射 if in_ch != out_ch or stride != 1: x = conv_bn(x, out_ch, 1, stride=stride) return relu(y + x)

参数in_ch、mid_ch、out_ch对应表格中Stage的输入通道、瓶颈通道和输出通道。当特征图尺寸变化(stride=2)或通道数变化时,x必须经过1×1卷积调整形状,否则y和x形状不一致无法相加。注意shortcut路径上的卷积不接ReLU,只做线性映射加BN,这是ResNet原论文的实现要点。

2.3 时间流保留BN-Inception的原因

空间流换成了ResNet,时间流没有跟着换,而是继续用BN-Inception。原因有两层。第一,时间网络的输入是光流场堆叠,输入通道数远高于RGB图像的3通道。典型配置下堆叠L组光流的x和y分量,输入通道数是2L。光流信息本身噪声较大,网络前几层更多在做运动模式的局部匹配,不需要像空间流那样追求极深的语义层次。第二,BN-Inception的批归一化在训练稳定性上有优势。论文中时间网络的初始学习率设为0.005,是空间网络的5倍,能承受这么大的学习率,靠的就是BN层对每层激活值分布的归一化。

2.4 光流输入与时间网络的结构对应

时间网络输入的是连续帧之间堆叠的光流位移场。光流描述了每个像素从上一帧到下一帧的水平位移dx和垂直位移dy,本质上是在显式表达运动。论文中光流场按通道堆叠后送入BN-Inception,网络从底层开始学习运动模式的组合。空间网络和时间网络虽然结构不同,但都输出每个动作类别的得分,只是在信息源上做了分工。

2.5 稀疏采样:3段视频与分段共识函数

如果对视频每一帧都推理,计算量无法接受。论文的做法是将视频按时间均匀划分成3段,每段随机采样一个序列短片段,包含一帧图像和对应的光流序列。每个短片段单独送入网络得到分类得分,3个得分通过分段共识函数合成视频级预测。论文中的分段共识函数采用平均形式,即3个片段的得分取均值。稀疏采样的核心思想是:行为动作的时间结构通常在秒级尺度,采样3个有代表性的瞬间足以覆盖动作的起承转合,不需要逐帧枚举。

采样逻辑可以这样实现:

import random def sparse_sample(video_len, num_segments=3): # video_len: 视频总帧数 # num_segments: 论文设为 3,对应分段共识函数中的片段数 seg_size = video_len // num_segments indices = [] for seg in range(num_segments): # 每段内随机取一个起点,避免采样到动作边界 start = random.randint(seg * seg_size, (seg + 1) * seg_size - 1) indices.append(start) return indices

参数说明:seg_size是每段的帧数区间,random.randint保证每段内的采样位置随机。同一个视频在多次训练迭代中采样到的片段不同,实际上形成了一种时间维度上的数据增强。推理阶段可以固定取每段中点,减少随机性带来的波动。

3. 光流预处理、交叉模态预训练与双流训练实现

3.1 光流提取与输入张量的组织

实现时第一步是从原始视频中提取光流。常见做法有两种:OpenCV自带的Farneback稠密光流,以及TV-L1变分光流。Farneback速度快、参数好调,适合快速验证;TV-L1对运动边界的保持更好,但计算速度慢。论文实验环境是Ubuntu 16.04加GTX Titan X,数据预处理在CPU上做,工程上Farneback是更常用的起点。

光流提取后,需要按照时间网络要求的通道数组织张量。论文输入尺寸为256×340,训练时再从{168,192,224,256}中随机选择裁剪区域,最终调整成224×224。对光流序列,常见做法是取连续10帧计算9组光流,将每组光流的dx和dy按通道堆叠,得到18通道输入。输入通道数直接对应网络第一层卷积的输入维度。

提取并堆叠光流的示例:

import cv2 import numpy as np def extract_flow_stack(prev, frames, max_flow=20): # prev: 起始帧灰度图, frames: 后续帧列表 # 返回堆叠后的光流张量, 通道数 = 2 * len(frames) flows = [] cur = prev for f in frames: # 逐对计算光流 g = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY) flow = cv2.calcOpticalFlowFarneback( cur, g, None, 0.5, 3, 15, 3, 5, 1.2, 0) # 将 dx, dy 分别裁剪到 [-max_flow, max_flow] flows.append(np.clip(flow[..., 0], -max_flow, max_flow)) flows.append(np.clip(flow[..., 1], -max_flow, max_flow)) cur = g return np.stack(flows, axis=-1) # (H, W, 2*N)

参数说明:calcOpticalFlowFarneback的9个参数依次是金字塔尺度比例0.5、金字塔层数3、窗口大小15、迭代次数3、邻域大小5、高斯标准差1.2和flags。这些参数在视频分辨率256×340附近表现稳定,分辨率更高时建议把窗口适当加大到21。裁剪到±20像素是为了后续线性变换到[0,255]时不被个别离群光流点拉偏分布。

3.2 把光流塞进ImageNet预训练网络:交叉模态预训练

行为识别数据集规模有限,UCF-101共13320个视频片段、101类,HMDB-51只有6766个片段、51类。拿这样的数据量从头训练101层ResNet必然过拟合。空间网络直接用ImageNet预训练权值初始化,输入是RGB帧,不存在模态差异。

时间网络的情况特殊:光流的第一层输入通道数是2L,与ImageNet预训练模型的3通道RGB不一致。论文采用交叉模态预训练,先用线性变换把浮点光流场映射到[0,255],然后用RGB预训练权值初始化光流分支的第一层卷积。

具体做法常见有两种。第一种是权重复制:把预训练模型的RGB三通道权值在通道方向求平均,得到单通道模板,再复制2L份填满光流的输入通道。第二种是把3个通道的权值直接拼接到2L通道上,多出来的通道用较小的随机值初始化。第一种更常用,因为保留了预训练模型学到的边缘和纹理滤波器,后续微调只需要适应光流特有的运动模式。

def replicate_rgb_weight(pretrained_weight, num_flow_ch): # pretrained_weight: 预训练第一层卷积权重 (3, 3, k, k) # num_flow_ch: 光流输入通道数,例如 18 或 20 # 对 RGB 通道求平均,压缩成单通道模板 single = pretrained_weight.mean(axis=0, keepdims=True) # 复制输出通道,覆盖光流堆叠的每个输入通道 new_weight = np.repeat(single, num_flow_ch, axis=0) return new_weight

这段代码的语义是:把(3, 3, k, k)的RGB权重压缩成(1, 3, k, k),再复制num_flow_ch次。mean加keepdims=True才能保留通道维度。复制后得到的权重对所有光流输入通道共享同一套滤波器初始化,训练早期会快速分化,实际收敛速度比随机初始化快很多。

3.3 训练超参数配置与Caffe Solver配置

论文实验基于Caffe框架,使用SGD优化。两个数据集、两个网络的超参数不同,整理成表:

数据集网络批量大小初始学习率学习率调度最大迭代
UCF-101空间ResNet80.001每1000次×0.83500
UCF-101时间BN-Inception320.00512000/18000次×0.120000
HMDB-51空间ResNet80.001每1000次×0.82500
HMDB-51时间BN-Inception320.0054000/6000次×0.17000

时间网络学习率是空间的5倍,批量也更大。原因在于光流输入的单样本计算量小于深度ResNet,更大的batch可以让BN统计量更稳定,支撑更大的学习率。

对应的Caffe solver配置,UCF-101空间网络是经典step策略:

net: "resnet_101_ucf101_train.prototxt" type: "SGD" base_lr: 0.001 momentum: 0.9 weight_decay: 0.0005 lr_policy: "step" stepsize: 1000 gamma: 0.8 max_iter: 3500 solver_mode: GPU

时间网络使用multistep策略,在两个迭代点各降低10倍学习率:

net: "bn_inception_ucf101_flow_train.prototxt" type: "SGD" base_lr: 0.005 momentum: 0.9 weight_decay: 0.0005 lr_policy: "multistep" stepvalue: 12000 stepvalue: 18000 gamma: 0.1 max_iter: 20000 solver_mode: GPU

配置说明:momentum和weight_decay是Caffe SGD的标准默认值;stepsize=1000配合gamma=0.8表示每1000次迭代学习率乘以0.8,是较温和的衰减曲线。multistep在指定迭代点一次性缩小10倍,衰减更剧烈,适合训练中后期快速收敛。

3.4 数据增强:尺度抖动与水平翻转

论文使用两种数据增强:尺度抖动和多尺度裁剪。输入图像或光流场固定为256×340,训练时从{168,192,224,256}中随机选择裁剪区的高度和宽度,裁剪后调整为224×224。这个策略的直观效果是模拟目标在不同距离和尺度下的表现,让空间网络对动作主体的尺度变化不敏感。

水平翻转是行为识别里为数不多可以安全使用的翻转方式。垂直翻转会把站立动作变成倒立,破坏动作语义,论文没有使用。测试阶段不做随机裁剪,直接取固定中心区域。

4. 得分融合策略、实验对比与计算成本控制

4.1 Softmax得分平均融合

空间网络和时间网络各自独立训练,测试时分别对视频片段输出行为类别的Softmax概率。两个网络看到的信息不同:空间网络看到静态帧,时间网络看到光流运动。融合时最常见的做法是对两路得分做加权平均,论文实验取的是等权平均,即两路权重各0.5。表1说明中也明确是通过取空间网络和时间网络识别准确率的平均值来评估融合性能。

融合脚本用Python几行就能完成:

import numpy as np def fuse_and_predict(spatial_scores, temporal_scores): # spatial_scores: (N, C) 空间网络 Softmax 输出 # temporal_scores: (N, C) 时间网络 Softmax 输出 # N: 视频片段数, C: 行为类别数(UCF-101 为 101, HMDB-51 为 51) fused = (spatial_scores + temporal_scores) / 2.0 predictions = np.argmax(fused, axis=1) return fused, predictions

参数说明:输入必须先经过Softmax得到概率分布,而不是直接对网络末层的logits做平均。两个网络的输出尺度不同,ResNet的logits分布与BN-Inception的分布未必对齐,直接在logits上平均会让数值更大的网络主导结果。等权平均不是唯一选择,如果想进一步调优,可以在验证集上网格搜索融合权重,但论文实验显示等权平均已经足够稳定。

4.2 与iDTs、C3D、TSN等方法的对比

论文在UCF-101和HMDB-51上报告了3个分割方案的平均准确率。对比方法覆盖了传统手工特征和主流深度学习方法:

识别方法UCF-101HMDB-51
iDTs85.957.2
MIFS88.563.8
C3D85.2-
LTC91.764.8
AdaScan93.266.9
TSN94.269.4
ResNet+BN-Inception双流94.570.1

注意C3D在HMDB-51上的准确率论文原表为空。对比能看出几个趋势:传统手工特征iDTs在UCF-101上明显低于深度方法,说明深度学习对行为特征的表征能力更强;C3D用3D卷积直接建模时空,UCF-101只有85.2%,低于双流TSN的94.2%,说明在数据量有限时,分开建模空间和时间再融合,比端到端3D卷积更容易训练。

论文方法在UCF-101上比TSN高0.3个百分点,HMDB-51高0.7个百分点。HMDB-51上的提升更明显,说明ResNet替换TSN的空间主干后,对复杂背景下的外观语义提取更有效——HMDB-51的视频大多来自真实电影场景,背景杂、视角多,对外观特征的鲁棒性要求更高。

4.3 3D卷积层上的轨迹提取实验

论文在实验过程中尝试过在多个3D卷积层提取运动轨迹,期望捕获更丰富的运动信息。但实验发现,最终识别效果没有明显提升,反而增加了计算成本,最终只在第一个3D卷积层提取运动轨迹。

这个结果在工程上很有价值。深层卷积特征语义抽象程度高,但空间分辨率低,逐层做轨迹匹配的代价高、收益小。行为识别里运动信息本质上是一种中低层线索,底层光流和浅层特征已经能表达“手臂挥动”“身体移动”这类基本运动,高层特征再做轨迹匹配属于重复劳动。

提示:如果在自己设计的双流或3D网络里尝试多尺度运动建模,先用可视化工具确认深层特征是否真的包含额外的运动信息,再决定是否增加相应的计算模块,避免无效计算。

4.4 双流互补的类别分析

论文对识别结果做了逐类分析,发现两个网络的错误模式高度互补。UCF-101里的击剑动作在时间网络上识别准确率很低,因为击剑移动幅度小、光流信号弱,但空间网络能充分借助外观信息——击剑服、剑的形态、对峙姿势——获得很好的识别结果。反过来,FrontCrawl、HandstandWalking、Highjump这类动作,空间网络容易混淆,因为静态帧里看不出运动趋势,但时间网络借助光流提取的运动信息能准确建模动作过程。

这类互补关系解释了为什么等权平均融合能稳定涨点:当某个动作在一个网络上得分低时,另一个网络通常有较高的正确得分,平均后的排名仍然靠前。这也是双流架构在行为识别中长期占据主流地位的原因。

5. 光流输入规范、三分割验证与显存占用控制

5.1 光流线性变换的输入规范

交叉模态预训练的前提是光流输入和RGB图像处于同一数值区间。RGB图像输入网络前归一化到[0,255],浮点光流的量纲是像素位移,位移量可能从0到几十不等。论文的做法是先用线性变换把流场映射到[0,255],再送入时间网络。

实践上常用的线性变换实现是裁剪加归一化:先设定一个最大位移阈值,把超出阈值的位移截断,然后线性映射到[0,255]。阈值的选择会直接影响识别效果——阈值太大,小幅度运动的细节被压缩;阈值太小,大幅度运动被截断后损失信息。在UCF-101这类运动幅度较大的数据集上,阈值取20像素是常见的起点,具体数据集上建议在验证集上做一次小网格搜索。

5.2 三分割方案验证:报告平均值比单次结果可信

UCF-101和HMDB-51各自提供了3个官方训练/测试划分。论文在这3个划分上都做了实验,报告平均准确率。这是行为识别论文的标准做法,但复现时经常被忽略。

单次划分的准确率受随机性影响较大,数据集只有一万多个视频片段时,训练/测试分布稍有不同,结果可能波动1到2个百分点。3个划分的平均值能更真实地反映方法的泛化能力。复现时建议把3个划分的训练都跑一遍,对比表1中的分方案结果:空间网络在UCF-101上3个方案的准确率分别是85.0、85.7、85.5,时间网络是87.6、90.2、91.3。如果单方案结果和这些数字差距超过2个百分点,优先检查数据预处理的分割方式是否正确。

5.3 显存占用控制:双流分开训练、推理时再融合

ResNet-101空间网络的单卡显存占用在12GB的GTX Titan X上,批量大小设为8已经接近上限。如果显存不足,优先降低batch而不是减少输入分辨率,因为输入尺寸从224×224降到192×192会损失外观细节,对空间网络的精度影响更直接。

双流网络实际训练时先训练空间网络,再训练时间网络,两者完全独立,不是联合训练。推理时再把两个模型的预测结果加载到内存中融合。这意味着显存不够时,可以先后加载两个模型分别推理,保存各自的Softmax输出到磁盘,最后用融合脚本合并,避开同时加载两个模型的显存压力。监控训练曲线时,重点看时间网络的loss是否在12000次迭代后明显下降,那是multistep学习率衰减生效的标志,如果衰减点之后loss没有变化,说明学习率衰减过猛,可以把gamma从0.1放宽到0.2再试。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询