ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SlowFast网络实战:从环境搭建到源码解析的完整行为识别教程

2026/8/22 10:37:00 拓冰建站 浏览量
SlowFast网络实战:从环境搭建到源码解析的完整行为识别教程 最近在复现行为识别领域的经典论文时发现 SlowFast 网络虽然效果卓越但其环境搭建和源码理解的门槛让不少同学望而却步。网上的资料要么版本过时要么步骤零散很难形成一个从零到一的完整闭环。本文将为你提供一份保姆级的 SlowFast 实战教程内容涵盖从零搭建 PyTorch 环境、下载并处理数据集、配置与训练模型到逐模块解析源码核心逻辑的全过程。无论你是正在为毕设寻找可靠方案的研究生还是希望深入理解视频理解模型的开发者都能从本文获得可直接复现的代码和清晰的思路。1. 背景与核心概念为什么是 SlowFast在深入动手之前我们有必要理解 SlowFast 网络解决了什么问题以及它的设计哲学是什么。行为识别Action Recognition是计算机视觉的一个重要分支其目标是让机器理解视频中的人物或物体正在执行什么动作。例如识别“打篮球”、“走路”、“开门”等。这项技术是智能监控、人机交互、视频内容分析等应用的基础。传统的视频理解模型如 C3D、I3D通常对视频的所有帧或片段进行均匀、高计算成本的采样和处理。然而人类视觉系统在处理动态信息时存在一个有趣的特性我们对场景的语义信息是什么物体在哪里变化感知较慢但对快速变化的运动信息如何动感知非常敏锐。SlowFast 网络正是受此生物学观察启发由 Facebook AI Research (FAIR) 在 2019 年提出。它的核心思想是设计一个双路径Two-Stream架构Slow 路径慢路径以较低的帧率例如每秒采样 2 帧处理输入通道数多旨在捕捉视频的空间语义信息场景、物体、姿态。Fast 路径快路径以较高的帧率例如每秒采样 16 帧处理输入但通道数较少通常是 Slow 路径的 1/8旨在捕捉时间运动信息快速的姿态变化、物体位移。两条路径通过横向连接Lateral Connection进行信息融合使得模型能同时兼顾外观和运动在保持高精度的同时计算量相对可控。该模型在 Kinetics-400、AVA 等多个行为识别数据集上取得了当时 state-of-the-art 的性能成为后续许多研究的基石。2. 环境准备与版本说明工欲善其事必先利其器。一个稳定、版本匹配的环境是成功复现的第一步。以下配置是经过验证可稳定运行 SlowFast 官方代码的。2.1 硬件与操作系统GPU强烈建议使用 NVIDIA GPU。显存至少 8GB如 GTX 1080 Ti, RTX 2070, RTX 3060 及以上用于训练 Kinetics 等大型数据集需要 11GB 或更多如 RTX 2080 Ti, RTX 3090。CPU无特殊要求建议 4 核以上。内存16GB 或以上处理视频数据时内存消耗较大。存储预留至少 100GB 的 SSD 空间用于存放数据集和模型。操作系统Ubuntu 18.04/20.04 LTS 或 Windows 10/11 with WSL2。本文以Ubuntu 20.04为例进行说明。2.2 核心软件版本版本兼容性是深度学习项目最大的“坑”。以下是经过测试的稳定组合组件推荐版本说明Python3.83.7-3.9 均可避免使用 3.10 可能存在的兼容性问题。PyTorch1.9.0 / 1.10.0CUDA 11.1 或 11.3 对应版本。这是与 SlowFast 代码兼容的关键。CUDA11.1 或 11.3需与 PyTorch 版本和 NVIDIA 驱动匹配。cuDNN8.0.5 或以上对应 CUDA 版本。ffmpeg4.3用于视频解码版本影响不大但必须安装。2.3 一步步搭建环境我们使用conda来创建独立的环境避免污染系统。步骤 1安装 Miniconda (如果未安装)# 下载 Miniconda 安装脚本 (Python 3.8 版本) wget https://repo.anaconda.com/miniconda/Miniconda3-py38_4.12.0-Linux-x86_64.sh # 运行安装脚本 bash Miniconda3-py38_4.12.0-Linux-x86_64.sh # 按照提示操作安装完成后重启终端或运行 source ~/.bashrc步骤 2创建并激活 conda 环境# 创建一个名为 slowfast 的 Python 3.8 环境 conda create -n slowfast python3.8 -y # 激活环境 conda activate slowfast步骤 3安装 PyTorch 和 TorchVision访问 PyTorch 历史版本官网 查找对应命令。以 CUDA 11.3 为例# 安装 PyTorch 1.10.0 CUDA 11.3 pip install torch1.10.0cu113 torchvision0.11.1cu113 torchaudio0.10.0cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html安装后验证python -c import torch; print(torch.__version__); print(torch.cuda.is_available())应输出类似1.10.0cu113和True。步骤 4安装系统依赖和 FFmpeg# Ubuntu/Debian sudo apt-get update sudo apt-get install -y ffmpeg git vim # 通过 pip 安装一些必要的 Python 包 pip install numpy1.24.0 # SlowFast 对 numpy 版本敏感1.24 可能报错 pip install opencv-python pillow scikit-learn matplotlib tqdm pandas步骤 5克隆 SlowFast 仓库并安装项目依赖# 克隆官方仓库 git clone https://github.com/facebookresearch/SlowFast.git cd SlowFast # 安装项目所需的 Python 包 (requirements.txt 可能不全我们手动安装核心包) pip install simplejson av psutil moviepy detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu113/torch1.10/index.html # 注意detectron2 的安装需严格匹配 PyTorch 和 CUDA 版本。上述链接适用于 PyTorch 1.10 CUDA 11.3。 # 将当前目录加入 Python 路径方便后续导入模块 export PYTHONPATH$(pwd):$PYTHONPATH # 可以将其写入 ~/.bashrc 或环境配置文件至此基础环境搭建完成。3. 数据集准备以 Kinetics-400 为例SlowFast 支持多种数据集最常用的是 Kinetics-400。它包含约 30 万个视频片段覆盖 400 个人类动作类别。3.1 数据集下载与结构由于版权原因官方不提供视频直接下载但提供了 YouTube 的 ID 列表和下载脚本。你需要准备足够的网络和存储空间。方案 A使用官方脚本下载耗时需要稳定网络下载标注文件cd SlowFast # 下载 Kinetics-400 的标注文件 (train/val 列表) wget https://storage.googleapis.com/deepmind-media/Datasets/kinetics400.tar.gz tar -zxvf kinetics400.tar.gz # 解压后得到 kinetics400/ 目录包含 train.csv, val.csv, test.csv 等使用tools/kinetics_download下的脚本下载。但此过程非常缓慢且容易因视频失效而失败不推荐个人研究者使用。方案 B使用已预处理好的帧数据推荐许多研究机构提供了将视频预处理成 JPEG 或 PNG 帧的数据集直接使用帧可以跳过繁琐的视频解码和抽帧步骤。数据集格式通常数据集被组织为数据集根目录/类别名/视频ID/图片帧.jpg的结构。路径设置你需要将数据集的路径配置到 SlowFast 的配置文件中。方案 C使用小型数据集测试如 UCF-101对于初次验证和毕设演示UCF-101101个动作类别约1.3万视频是更轻量的选择。你可以从官方渠道下载并使用 SlowFast 提供的tools/run_net.py脚本进行训练但需要修改配置文件中的数据集路径和类别数。本文假设你已获得以帧格式存储的 Kinetics-400 数据集其目录结构如下/path/to/kinetics400/ ├── train/ │ ├── abseiling/ │ │ ├── -0T4wnlFmBQ_000000_000010/ # 视频ID_起始帧_结束帧 │ │ │ ├── img_00001.jpg │ │ │ ├── img_00002.jpg │ │ │ └── ... │ │ └── ... │ └── ... └── val/ └── ... (结构同train)3.2 生成数据集列表文件SlowFast 需要文本文件来索引所有训练和验证样本。你需要根据你的帧文件夹结构生成对应的列表。可以使用以下 Python 脚本 (gen_list.py) 来生成import os import argparse def generate_list(data_root, split, output_file): data_root: 数据集根目录例如 /path/to/kinetics400 split: train 或 val output_file: 输出的列表文件路径 split_path os.path.join(data_root, split) classes sorted(os.listdir(split_path)) class_to_idx {cls_name: i for i, cls_name in enumerate(classes)} with open(output_file, w) as f: for cls_name in classes: class_dir os.path.join(split_path, cls_name) if not os.path.isdir(class_dir): continue for video_id in os.listdir(class_dir): frame_dir os.path.join(class_dir, video_id) if not os.path.isdir(frame_dir): continue # 计算该视频的帧数 frames sorted([f for f in os.listdir(frame_dir) if f.endswith(.jpg)]) if len(frames) 0: continue # 格式: path_to_frames num_frames label # 注意path_to_frames 是到包含帧的目录而不是单个文件 relative_path os.path.join(split, cls_name, video_id) line f{relative_path} {len(frames)} {class_to_idx[cls_name]}\n f.write(line) print(fGenerated {output_file} with {sum(1 for line in open(output_file))} samples.) if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--data_root, requiredTrue, helpRoot path of the dataset) parser.add_argument(--split, defaulttrain, choices[train, val], helpSplit to process) parser.add_argument(--output, requiredTrue, helpOutput list file path) args parser.parse_args() generate_list(args.data_root, args.split, args.output)运行脚本python gen_list.py --data_root /path/to/kinetics400 --split train --output kinetics400_train_list.txt python gen_list.py --data_root /path/to/kinetics400 --split val --output kinetics400_val_list.txt生成的train_list.txt内容示例train/abseiling/-0T4wnlFmBQ_000000_000010 250 0 train/archery/--0a1LbCqPM_000005_000015 250 1 ...4. 模型训练与验证环境与数据就绪后我们开始训练。SlowFast 的配置系统基于 yaml 文件非常灵活。4.1 配置文件解析与修改SlowFast 的配置文件在configs/目录下。我们以 Kinetics-400 的 8x8 模型在 8 个 GPU 上每 GPU batch size 为 8为例其配置文件为configs/Kinetics/SLOWFAST_8x8_R50.yaml。我们需要修改几个关键参数以适应单卡或数据路径数据路径修改DATA.PATH_TO_DATA_DIR为你的数据集根目录。数据列表修改DATA.PATH_PREFIX和列表文件路径。训练参数根据你的 GPU 显存调整TRAIN.BATCH_SIZE和TEST.BATCH_SIZE。单卡训练可能需要大幅减小BATCH_SIZE例如改为 4 或 2并相应调整学习率。输出目录修改OUTPUT_DIR为你希望保存模型和日志的路径。你可以创建一个自定义配置文件例如my_slowfast_config.yaml通过继承和覆盖来修改# package _global_ MODEL: NUM_CLASSES: 400 ARCH: slowfast MODEL_NAME: SlowFast DROPOUT_RATE: 0.5 LOSS_FUNC: cross_entropy SLOWFAST: ALPHA: 4 # 时间维度下采样率 (Fast path帧率 / Slow path帧率) BETA_INV: 8 # 通道数比例 (Slow path通道数 / Fast path通道数) FUSION_CONV_CHANNEL_RATIO: 2 FUSION_KERNEL_SZ: 5 DATA: NAME: kinetics PATH_TO_DATA_DIR: /path/to/kinetics400 # 修改为你的数据集根目录 PATH_PREFIX: # 如果帧路径是绝对路径这里留空如果是相对路径则设为 DATA.PATH_TO_DATA_DIR TRAIN_LIST: kinetics400_train_list.txt # 你的训练列表文件 VAL_LIST: kinetics400_val_list.txt # 你的验证列表文件 TEST_LIST: kinetics400_val_list.txt NUM_FRAMES: 32 # 每个视频片段采样的帧数 SAMPLING_RATE: 2 # 采样步长 (Slow path) TRAIN_CROP_SIZE: 224 TEST_CROP_SIZE: 256 INPUT_CHANNEL_NUM: [3, 3] TRAIN: ENABLE: True DATASET: kinetics BATCH_SIZE: 8 # 根据你的GPU调整单卡可能需改为 2 或 4 EVAL_PERIOD: 10 # 每10个epoch验证一次 CHECKPOINT_PERIOD: 10 # 每10个epoch保存一次模型 AUTO_RESUME: True CHECKPOINT_FILE_PATH: # 预训练模型路径可从官方下载 CHECKPOINT_TYPE: pytorch SOLVER: BASE_LR: 0.1 # 学习率当BATCH_SIZE变化时通常按线性规则调整New_LR Base_LR * (New_BS / Old_BS) LR_POLICY: cosine MAX_EPOCH: 196 MOMENTUM: 0.9 WEIGHT_DECAY: 1e-4 WARMUP_EPOCHS: 34 WARMUP_START_LR: 0.01 TEST: ENABLE: True DATASET: kinetics BATCH_SIZE: 4 # 验证时batch size可以稍大 DATA_LOADER: NUM_WORKERS: 8 # 数据加载线程数根据CPU核心数调整 PIN_MEMORY: True OUTPUT_DIR: ./output/my_slowfast_experiment # 修改为你的输出路径4.2 开始训练使用tools/run_net.py脚本进行训练指定你的配置文件。cd /path/to/SlowFast python tools/run_net.py \ --cfg configs/my_slowfast_config.yaml \ NUM_GPUS 1 \ # 指定GPU数量 TRAIN.BATCH_SIZE 2 \ # 命令行可以覆盖配置文件中的参数 SOLVER.BASE_LR 0.025 # BATCH_SIZE从8降到2学习率大致按比例调整为 0.1 * (2/8) 0.025关键参数说明--cfg: 指定配置文件路径。后续的KEY VALUE对用于覆盖配置文件中的默认值非常灵活。NUM_GPUS: 使用的 GPU 数量。如果只有 1 个 GPU务必设置为此。当BATCH_SIZE改变时学习率SOLVER.BASE_LR通常需要同步进行线性缩放这是保证训练稳定的重要经验法则。训练开始后终端会输出损失、准确率等信息模型和日志会保存在OUTPUT_DIR中。4.3 模型测试与推理训练完成后你可以使用最佳模型通常是验证集上准确率最高的那个在测试集上评估或对单个视频进行推理。评估模型python tools/run_net.py \ --cfg configs/my_slowfast_config.yaml \ TRAIN.ENABLE False \ # 关闭训练模式 TEST.ENABLE True \ # 开启测试模式 TEST.CHECKPOINT_FILE_PATH /path/to/your/best/model.pyth # 指定模型权重文件对单个视频进行推理 SlowFast 仓库提供了demo_net.py脚本。你需要准备一个标签文件如kinetics_400_labels.csv包含类别ID和名称的映射并运行python tools/demo_net.py \ --cfg configs/my_slowfast_config.yaml \ --input-video /path/to/your/video.mp4 \ --output-file /path/to/output.mp4 \ TEST.CHECKPOINT_FILE_PATH /path/to/model.pyth脚本会输出一个带有预测标签的视频文件。5. 源码核心模块解析理解源码是掌握 SlowFast 精髓的关键。我们深入到几个核心模块。5.1 数据加载器 (slowfast/datasets/)数据加载是训练的第一步也是性能瓶颈之一。SlowFast 使用PyAV库解码视频并使用torchvision进行数据增强。关键文件kinetics.py,build.py,transform.pykinetics.py中的Kinetcs类负责读取我们之前生成的列表文件并根据配置如NUM_FRAMES,SAMPLING_RATE从视频或帧文件夹中加载图像。帧采样策略这是 SlowFast 双路径输入的关键。在kinetics.py的__getitem__方法中会为 Slow 和 Fast 路径分别采样帧索引。Slow 路径采样间隔大SAMPLING_RATEFast 路径采样间隔小SAMPLING_RATE // ALPHA。数据增强transform.py中定义了丰富的增强操作如随机裁剪、水平翻转、颜色抖动等。训练和测试阶段使用不同的增强管道。5.2 模型定义 (slowfast/models/)模型构建的核心在slowfast.py和video_model_builder.py。关键文件slowfast.py,video_model_builder.py,resnet.py,stem_helper.pyvideo_model_builder.py中的build_model函数是模型创建的入口。它根据配置字典调用slowfast.py中的SlowFast类。SlowFast类这是网络的主体。它包含两个独立的 stem 层分别处理 Slow 和 Fast 路径的输入。多个 stage 的 ResNet 块每个 stage 包含多个ResStage。关键在于每个 stage 内部Slow 和 Fast 路径是并行计算的。横向连接 (Lateral Connection)在 stage 之间Fast 路径的特征会经过一个卷积层通常是 1x1x1 Conv BN ReLU后与 Slow 路径的特征进行融合通常是逐元素相加。这是两条路径信息交换的桥梁。头部 (Head)两个路径的特征在最后的 stage 被聚合例如通过 concatenation然后经过全局平均池化和全连接层输出分类分数。代码片段示例简化版 SlowFast 构建逻辑# 位于 slowfast/models/slowfast.py class SlowFast(nn.Module): def __init__(self, cfg): super(SlowFast, self).__init__() self.cfg cfg # 构建两条路径的 stem self.slow_path ResNetBasicStem(...) self.fast_path ResNetBasicStem(...) # 构建多个 stage self.stages nn.ModuleList() for stage_idx in range(num_stages): stage ResStage(...) self.stages.append(stage) # 构建头部 self.head ResNetBasicHead(...) def forward(self, x): # x 是一个列表 [slow_input, fast_input] slow, fast x[0], x[1] slow self.slow_path(slow) fast self.fast_path(fast) for stage in self.stages: slow, fast stage((slow, fast)) # stage 内部处理融合 # 融合两条路径的特征并输入头部 x self.head((slow, fast)) return x5.3 训练循环与损失函数 (slowfast/utils/)训练逻辑主要在meters.py,checkpoint.py, 以及tools/train_net.py中。train_net.py定义了完整的训练 epoch 循环包括前向传播、损失计算、反向传播、参数更新。损失计算对于分类任务默认使用交叉熵损失 (nn.CrossEntropyLoss)。损失值在meters中被记录和平均。学习率调度使用余弦退火 (cosine) 学习率策略并带有线性 warmup这在训练深度网络时非常有效有助于模型稳定收敛。6. 常见问题与排查思路在复现过程中你几乎一定会遇到一些问题。以下是高频问题及解决方案。问题现象可能原因排查与解决思路ImportError: cannot import name ‘PILLOW_VERSION’ from ‘PIL’pillow版本过高10.0.0与torchvision旧版本不兼容。pip install pillow9.5.0降级 Pillow。RuntimeError: CUDA out of memoryGPU 显存不足。Batch size 过大或模型太大。1. 减小TRAIN.BATCH_SIZE和TEST.BATCH_SIZE。2. 使用梯度累积 (SOLVER.GRADIENT_ACCUMULATION_STEPS)。3. 尝试更小的模型变体如SLOWFAST_4x16_R50。4. 使用torch.cuda.empty_cache()清理缓存。KeyError: ‘Unable to open object (object ‘data’ doesn’t exist)’数据路径或列表文件格式错误。列表文件中的路径无法找到对应帧。1. 检查DATA.PATH_TO_DATA_DIR和DATA.PATH_PREFIX配置。2. 检查列表文件每行的路径是否存在帧数是否正确。3. 使用绝对路径可以避免相对路径的歧义。训练 Loss 为 NaN 或不下降学习率过高、数据预处理有问题、损失函数输入异常。1. 大幅降低学习率 (SOLVER.BASE_LR)例如从 0.1 降到 0.01。2. 检查数据标签是否在有效范围内0 到 NUM_CLASSES-1。3. 在数据加载部分添加调试检查图像像素值是否正常0-255 或 0-1。4. 使用梯度裁剪 (SOLVER.CLIP_GRADIENT)。验证准确率远低于预期过拟合、数据泄露、模型未收敛、评估代码有误。1. 确保训练和验证集是严格分开的。2. 增加数据增强使用 Dropout。3. 训练更多 epoch观察 loss 是否还在下降。4. 在验证集上手动推理几个样本看预测是否合理。detectron2相关导入错误detectron2版本与 PyTorch/CUDA 不匹配。严格按照 PyTorch 和 CUDA 版本安装对应的detectron2wheel 包。参考官方安装指南。视频解码速度极慢使用decoding.py的pyav解码器且视频编码复杂。1. 如果可能使用预提取的帧frame格式数据跳过解码。2. 增加DATA_LOADER.NUM_WORKERS以并行加载数据。7. 最佳实践与工程建议掌握了基础操作后以下建议能帮助你在毕设或实际项目中做得更好。7.1 实验管理与复现性版本控制将你的配置文件、数据列表生成脚本、环境依赖文件 (requirements.txt或environment.yml) 纳入 Git 管理。实验记录为每次实验创建独立的输出目录 (OUTPUT_DIR)并保存对应的配置文件副本。可以使用 TensorBoard 或 WandB 来可视化训练曲线。随机种子在代码开头固定所有随机种子确保实验可复现。import random import numpy as np import torch def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic True torch.backends.cudnn.benchmark False7.2 性能优化数据加载这是训练的主要瓶颈。务必使用DATA_LOADER.NUM_WORKERS通常设为 CPU 核心数进行多进程数据加载。如果数据存储在机械硬盘上考虑使用更快的存储或先将数据缓存到内存。混合精度训练如果 GPU 支持如 Volta 架构及以后的 NVIDIA GPU可以启用混合精度训练以加速并减少显存占用。SlowFast 代码库可能原生支持或需手动集成torch.cuda.amp。梯度累积当 GPU 显存不足以支撑大的 batch size 时可以使用梯度累积来模拟大 batch 的训练效果。设置SOLVER.GRADIENT_ACCUMULATION_STEPS并在优化器 step 之前累积多个小 batch 的梯度。7.3 模型调试与调参从小开始先用极小的数据集如 1-2 个类别几十个样本跑通整个训练流程确保代码、数据流、损失计算无误。学习率搜索学习率是最重要的超参数。可以尝试循环学习率或简单的学习率扫描如[0.01, 0.03, 0.1, 0.3]。监控过拟合密切关注训练损失和验证损失的差距。如果验证损失很早就停止下降或开始上升说明过拟合。可以尝试更强的数据增强、权重衰减、或降低模型复杂度。7.4 扩展到自己的任务如果你的毕设不是简单的 Kinetics-400 分类而是其他行为识别任务如时序动作定位、多标签分类你需要修改数据加载器继承并重写slowfast/datasets下的类使其能读取你的标注格式如 JSON, XML。修改模型头部根据任务修改ResNetBasicHead。例如对于多标签分类将最后的全连接层输出改为NUM_CLASSES并将损失函数改为BCEWithLogitsLoss。修改评估指标在slowfast/utils/metrics.py中添加或修改评估函数以计算任务特定的指标如 mAP, IoU。从环境搭建到源码解析我们走完了 SlowFast 行为识别项目的完整流程。这套方案不仅适用于 Kinetics其双路径设计思想和 PyTorch 工程实践对于你理解其他视频模型如 X3D, TimeSformer也大有裨益。动手实践是学习深度学习的最佳途径希望这份教程能成为你攻克行为识别课题的坚实起点。如果在复现中遇到新的问题不妨回头仔细检查数据路径、版本兼容性和配置文件大部分错误都源于细节的疏忽。