DeepLabCut 完全入门指南:从零开始实现小鼠行为追踪

在这里插入图片描述

本文将带你从零开始,使用 DeepLabCut 实现动物行为的无标记姿态追踪。无论你是神经科学研究者、行为学家,还是对计算机视觉感兴趣的开发者,这篇教程都将帮助你快速上手这一强大的开源工具。


一、引言:为什么我们需要 DeepLabCut?

1.1 传统动物行为分析的困境

在神经科学和行为学研究中,精确追踪动物的运动和姿态是理解大脑功能、研究疾病模型的关键。然而,传统的行为追踪方法面临诸多挑战:

物理标记的侵入性:传统方法需要在动物身上粘贴反光标记点或植入传感器。这不仅会影响动物的自然行为,还可能引起应激反应,导致实验数据失真。对于小型动物(如小鼠、果蝇),标记点的大小和重量更是严重的限制因素。

人工标注的低效率:在没有自动化工具的情况下,研究人员需要逐帧手动标注视频中动物的关键点位置。一段几分钟的视频可能包含数千帧画面,手动标注耗时数天甚至数周,这严重制约了研究的规模和效率。

标记点的不稳定性:物理标记点容易脱落、遮挡或移位,尤其是在动物进行剧烈运动、社交互动或长时间实验时。这些问题会导致数据缺失和分析困难。

1.2 DeepLabCut 是什么?

DeepLabCut(简称 DLC)是一个基于深度学习的开源工具包,用于实现动物和人类的无标记姿态估计(Markerless Pose Estimation)。它由哈佛大学 Mathis Lab 开发,于 2018 年发表在 Nature Neuroscience 上,迅速成为神经科学和行为学领域最受欢迎的追踪工具之一。

DeepLabCut 的核心优势在于:

  • 无需物理标记:仅通过普通视频即可追踪动物的身体部位
  • 迁移学习:利用在 ImageNet 上预训练的神经网络,只需少量标注数据(通常 100-200 帧)即可训练出高精度模型
  • 物种无关:可用于任何动物——从果蝇、斑马鱼到小鼠、灵长类,甚至人类
  • 高精度:追踪精度可达到人工标注水平,像素级误差通常在 2-5 像素以内
  • 开源免费:基于 Python 开发,社区活跃,持续更新

1.3 DeepLabCut 能做什么?

DeepLabCut 不仅仅是一个简单的追踪工具,它已经发展成为一个完整的行为分析生态系统:

功能 描述 应用场景
单动物追踪 追踪单个动物的多个身体部位 行为学实验、运动分析
多动物追踪 (maDLC) 同时追踪多个动物并保持身份识别 社交行为、群体互动研究
3D 姿态重建 通过多相机系统重建三维姿态 复杂运动分析、生物力学
实时追踪 (DLC-Live) 低延迟实时追踪,支持闭环实验 神经反馈、行为干预实验

在神经科学领域,DeepLabCut 已被广泛应用于:

  • 帕金森病模型小鼠的运动障碍分析
  • 焦虑和抑郁模型的行为学评估
  • 学习和记忆相关的行为范式追踪
  • 社交互动和攻击行为的量化分析

二、环境搭建:从零开始安装 DeepLabCut

在开始使用 DeepLabCut 之前,我们需要搭建好运行环境。本章将详细介绍安装步骤和常见问题的解决方案。

2.1 硬件要求

DeepLabCut 的运行效率与硬件配置密切相关:

GPU(强烈推荐)

  • NVIDIA GPU,显存 ≥ 8GB(推荐 RTX 3060 及以上)
  • 已安装 CUDA 11.x 和 cuDNN
  • GPU 可将训练时间从数天缩短到数小时

CPU 模式

  • 可用于推理(分析视频),但训练速度极慢
  • 适合小规模测试或演示

无 GPU 的替代方案

  • Google Colab:免费提供 GPU,适合入门学习
  • 云服务器:AWS、阿里云等提供 GPU 实例

内存和存储

  • RAM ≥ 16GB(处理高分辨率视频时推荐 32GB)
  • SSD 存储,用于加速视频读取

2.2 安装步骤(Conda 方式,推荐)

我们推荐使用 Conda 来管理 Python 环境,这可以避免依赖冲突问题。

第一步:安装 Miniconda

如果你还没有安装 Conda,请先从 Miniconda 官网 下载并安装。

第二步:创建虚拟环境

打开终端(Windows 用户打开 Anaconda Prompt),执行以下命令:

# 创建名为 dlc 的虚拟环境,指定 Python 3.10
conda create -n dlc python=3.10 -y

# 激活环境
conda activate dlc

第三步:安装 DeepLabCut

# 安装 DeepLabCut(包含 GUI 和 TensorFlow)
pip install "deeplabcut[gui]"

# 如果需要 GPU 支持(推荐)
pip install "deeplabcut[gui,tf]"

第四步:验证安装

# 在 Python 中验证
import deeplabcut
print(f"DeepLabCut 版本: {deeplabcut.__version__}")

# 启动图形界面(可选)
deeplabcut.launch_dlc()

如果看到版本号输出且没有报错,说明安装成功。

2.3 常见安装问题排查

问题 1:CUDA 版本不兼容

错误信息:Could not load dynamic library 'libcudart.so.11.0'

解决方案:确保 CUDA 版本与 TensorFlow 版本匹配。DeepLabCut 当前推荐 CUDA 11.x。

问题 2:GUI 无法启动

错误信息:No module named 'wx'

解决方案:

pip install wxPython

问题 3:内存不足
训练时出现 OOM(Out of Memory)错误,可尝试:

  • 减小 batch_size
  • 降低输入图像分辨率
  • 使用更轻量的网络(如 MobileNetV2)

2.4 使用 Google Colab(无需本地 GPU)

如果你没有 NVIDIA GPU,可以使用 Google Colab 免费获取 GPU 资源:

  1. 访问 Google Colab
  2. 新建笔记本,选择「运行时」→「更改运行时类型」→ 选择「GPU」
  3. 安装 DeepLabCut:
!pip install deeplabcut[tf]
import deeplabcut

DeepLabCut 官方提供了完整的 Colab 教程笔记本,可以从 GitHub 仓库 获取。


三、创建你的第一个项目:以小鼠行为追踪为例

现在环境已经准备好,让我们创建第一个 DeepLabCut 项目。本章将以追踪小鼠行为为例,带你完成项目创建和配置。

3.1 视频准备建议

在开始之前,确保你的视频符合以下要求:

要素 建议 说明
分辨率 720p - 1080p 过高会增加计算负担
帧率 30-60 fps 根据动物运动速度调整
格式 .mp4, .avi 常见格式均支持
光照 均匀、稳定 避免阴影和反光
背景 简洁、对比度高 有助于提高追踪精度
时长 建议 < 30 分钟 长视频可分段处理

拍摄建议

  • 相机固定,避免抖动
  • 动物活动区域应完整在画面内
  • 避免遮挡(如水瓶、食物盒)

3.2 创建新项目

使用以下 Python 代码创建新项目:

import deeplabcut

# 定义项目参数
project_name = 'MouseTracking'      # 项目名称
experimenter = 'YourName'           # 实验者名称
video_path = '/path/to/your/video.mp4'  # 视频路径

# 创建项目
config_path = deeplabcut.create_new_project(
    project=project_name,
    experimenter=experimenter,
    videos=[video_path],
    working_directory='/your/project/directory',  # 项目保存路径
    copy_videos=True,   # 将视频复制到项目目录
    multianimal=False   # 单动物项目
)

print(f"配置文件路径: {config_path}")
# 输出示例: /your/project/directory/MouseTracking-YourName-2025-01-07/config.yaml

3.3 理解项目结构

创建项目后,会生成以下目录结构:

MouseTracking-YourName-2025-01-07/
├── config.yaml              # 核心配置文件(最重要!)
├── videos/                  # 存放训练视频
│   └── video.mp4
├── labeled-data/            # 存放标注数据
│   └── video/
├── training-datasets/       # 训练数据集
│   └── iteration-0/
└── dlc-models/              # 训练好的模型
    └── iteration-0/

config.yaml 是整个项目的核心配置文件,包含了所有重要参数。

3.4 配置 config.yaml

打开 config.yaml 文件,我们需要配置两个关键部分:

3.4.1 定义身体部位(bodyparts)

根据你要追踪的目标,定义需要追踪的关键点。以小鼠为例:

bodyparts:
  - snout          # 鼻尖
  - leftear        # 左耳
  - rightear       # 右耳
  - neck           # 颈部
  - spine1         # 脊柱点1
  - spine2         # 脊柱点2
  - spine3         # 脊柱点3
  - tailbase       # 尾根
  - tail1          # 尾部中点
  - tailtip        # 尾尖

命名建议

  • 使用简洁、有意义的英文名称
  • 避免使用空格和特殊字符
  • 保持命名一致性
3.4.2 定义骨架连接(skeleton)

骨架定义了身体部位之间的连接关系,用于可视化:

skeleton:
  - - snout
    - neck
  - - leftear
    - neck
  - - rightear
    - neck
  - - neck
    - spine1
  - - spine1
    - spine2
  - - spine2
    - spine3
  - - spine3
    - tailbase
  - - tailbase
    - tail1
  - - tail1
    - tailtip

3.5 提取训练帧

接下来,从视频中提取用于标注的帧。DeepLabCut 提供了智能提取算法,确保选取的帧具有多样性:

# 自动提取帧(推荐)
deeplabcut.extract_frames(
    config_path,
    mode='automatic',     # 自动模式
    algo='kmeans',        # 使用 K-means 聚类确保多样性
    userfeedback=False,   # 无需用户确认
    crop=False            # 是否裁剪(可选)
)

提取模式说明

  • automatic + kmeans:智能选取差异化的帧(推荐)
  • automatic + uniform:均匀间隔提取
  • manual:手动选择帧

提取数量:默认每个视频提取 20 帧。可通过 config.yaml 中的 numframes2pick 参数调整。对于简单场景,50-100 帧通常足够;复杂场景可能需要 200+ 帧。


四、数据标注:高质量标注的艺术

标注质量直接决定了模型的追踪精度。本章将介绍如何高效、准确地标注数据。

4.1 启动标注界面

DeepLabCut 提供了两种标注方式:

方式一:使用内置 GUI(推荐初学者)

deeplabcut.label_frames(config_path)

这将启动一个图形界面,你可以:

  • 使用鼠标点击标注各个身体部位
  • 使用键盘快捷键切换标注点
  • 缩放和平移图像以精确定位

方式二:使用 napari 插件(高级用户)

deeplabcut.label_frames(config_path, use_napari=True)

napari 提供更强大的可视化功能,适合处理复杂场景。

4.2 标注最佳实践

遵循以下原则可以显著提高模型质量:

质量优先于数量

  • 100 个高质量标注 > 500 个粗糙标注
  • 每个点都应精确标注到像素级别
  • 宁可少标,也不要乱标

保持一致性

  • 对同一身体部位,始终标注相同的解剖位置
  • 例如:"耳朵"应始终标注耳尖,而非耳根
  • 制定标注规范,确保多人标注时的一致性

处理遮挡情况

当身体部位被遮挡时:

  • 部分可见:标注可见部分的中心
  • 完全不可见:跳过该点(不标注)
  • DeepLabCut 会自动处理缺失标注

选择多样性帧

确保标注的帧覆盖:

  • 不同姿态(站立、行走、转向等)
  • 不同位置(画面各区域)
  • 不同光照条件(如有变化)

4.3 检查标注质量

标注完成后,使用以下命令可视化检查:

deeplabcut.check_labels(
    config_path,
    visualizeindividuals=True
)

这将生成带有标注点的图像,方便你检查:

  • 标注点位置是否正确
  • 骨架连接是否合理
  • 是否有明显错误

如发现错误,可重新运行 label_frames 进行修正。

4.4 标注示例:正确 vs 错误

情况 正确做法 错误做法
鼻尖定位 标注鼻子最前端 标注整个鼻子中心
耳朵定位 固定标注耳尖或耳根 有时标耳尖,有时标耳根
尾巴弯曲 沿尾巴曲线等距标注 随意标注
部分遮挡 估计位置并标注 随意标注可见区域
完全遮挡 跳过不标 强行猜测标注

五、模型训练与评估

有了标注数据,现在可以训练神经网络模型了。本章将介绍训练流程、参数调优和模型评估。

5.1 创建训练数据集

首先,将标注数据转换为训练格式:

deeplabcut.create_training_dataset(
    config_path,
    num_shuffles=1,           # 数据集随机划分次数
    net_type='resnet_50',     # 网络架构
    augmenter_type='imgaug'   # 数据增强方式
)

这一步会:

  • 将标注数据分为训练集和测试集(默认 95%/5%)
  • 生成网络配置文件
  • 准备数据增强管道

5.2 网络架构选择

DeepLabCut 支持多种预训练网络:

架构 精度 速度 显存占用 推荐场景
ResNet-50 ~6GB 默认首选,平衡精度与速度
ResNet-101 最高 ~8GB 追求极致精度
ResNet-152 最高 最慢 ~10GB 复杂场景
MobileNetV2-1.0 ~4GB 实时应用、低配置设备
MobileNetV2-0.35 较低 最快 ~2GB 嵌入式部署
EfficientNet-B0 ~4GB 新一代高效网络

选择建议

  • 初学者首选 ResNet-50
  • 追求实时性选 MobileNetV2
  • 追踪困难场景选 ResNet-101

5.3 开始训练

deeplabcut.train_network(
    config_path,
    shuffle=1,                    # 使用第 1 个数据划分
    trainingsetindex=0,           # 训练集索引
    max_snapshots_to_keep=5,      # 保留最近 5 个模型快照
    maxiters=50000,               # 最大迭代次数
    displayiters=1000,            # 每 1000 次显示进度
    saveiters=5000,               # 每 5000 次保存模型
    allow_growth=True             # 按需分配 GPU 内存
)

训练参数说明

  • maxiters:总迭代次数

    • 小数据集(<100帧):20000-50000
    • 中等数据集:50000-100000
    • 大数据集:100000-200000
  • displayiters:日志输出间隔,用于监控训练进度

  • saveiters:模型保存间隔,建议设置为 5000-10000

5.4 训练过程监控

训练过程中,关注以下指标:

Loss(损失值)

  • 应随训练持续下降
  • 初始值通常在 0.01-0.1
  • 收敛后应降至 0.001-0.005

典型训练日志

iteration: 1000  loss: 0.0156  lr: 0.005
iteration: 2000  loss: 0.0089  lr: 0.005
iteration: 3000  loss: 0.0052  lr: 0.0025
...
iteration: 50000 loss: 0.0018  lr: 0.00001

何时停止训练

  • Loss 不再明显下降
  • 验证集精度不再提升
  • 达到预设迭代次数

5.5 模型评估

训练完成后,评估模型性能:

deeplabcut.evaluate_network(
    config_path,
    Shuffles=[1],           # 评估第 1 个 shuffle
    plotting=True,          # 生成可视化图表
    show_errors=True        # 显示误差统计
)

评估指标解读

指标 含义 良好范围
Train error (px) 训练集平均像素误差 < 3 px
Test error (px) 测试集平均像素误差 < 5 px
p-cutoff 置信度阈值 0.6-0.9
PCK@5 5像素内的正确率 > 90%

评估结果可视化

  • 误差分布直方图
  • 各身体部位的误差对比
  • 预测 vs 真实位置散点图

5.6 常见问题与解决

问题 1:过拟合(Train error 远小于 Test error)

  • 增加训练数据量
  • 启用更强的数据增强
  • 减少网络复杂度(使用更小的 ResNet)

问题 2:训练不收敛(Loss 不下降)

  • 检查标注质量
  • 降低学习率
  • 增加训练数据

问题 3:GPU 内存不足

  • 减小 batch_size(在 pose_cfg.yaml 中修改)
  • 使用更小的网络(MobileNetV2)
  • 降低输入图像分辨率

六、视频分析与结果可视化

模型训练完成后,我们可以用它来分析新视频。本章介绍如何进行视频分析、理解输出结果和可视化。

6.1 分析新视频

使用训练好的模型分析新视频:

# 分析单个视频
deeplabcut.analyze_videos(
    config_path,
    videos=['/path/to/new_video.mp4'],
    videotype='mp4',
    shuffle=1,
    save_as_csv=True,      # 同时保存为 CSV 格式
    destfolder=None        # 输出目录(None 则与视频同目录)
)

# 批量分析多个视频
video_list = [
    '/path/to/video1.mp4',
    '/path/to/video2.mp4',
    '/path/to/video3.mp4'
]
deeplabcut.analyze_videos(config_path, videos=video_list)

6.2 输出文件解读

分析完成后,会生成以下文件:

1. HDF5 文件 (.h5)

video_name_DLC_resnet50_MouseTrackingJan7shuffle1_50000.h5

包含结构化数据:

  • 每帧每个身体部位的 x, y 坐标
  • 每个预测的置信度(likelihood)

2. CSV 文件 (.csv)

便于在 Excel 或其他工具中查看:

scorer,DLC_resnet50_MouseTrackingJan7shuffle1_50000,...
bodyparts,snout,snout,snout,leftear,leftear,leftear,...
coords,x,y,likelihood,x,y,likelihood,...
0,245.32,189.45,0.998,267.12,175.33,0.995,...
1,246.01,190.12,0.997,268.05,176.01,0.993,...

读取数据示例

import pandas as pd

# 读取 CSV
df = pd.read_csv('video_DLC...csv', header=[1,2], index_col=0)

# 获取鼻尖 x 坐标
snout_x = df[('snout', 'x')]

# 获取置信度
snout_likelihood = df[('snout', 'likelihood')]

# 筛选高置信度数据
high_conf = df[df[('snout', 'likelihood')] > 0.9]

6.3 生成标注视频

将追踪结果可视化为视频:

deeplabcut.create_labeled_video(
    config_path,
    videos=['/path/to/video.mp4'],
    videotype='mp4',
    shuffle=1,
    draw_skeleton=True,     # 绘制骨架连接
    trailpoints=10,         # 显示轨迹尾迹(最近10帧)
    pcutoff=0.6,            # 置信度阈值
    codec='mp4v',           # 视频编码器
    outputframerate=30      # 输出帧率
)

输出的视频将在每帧上标注:

  • 各身体部位的位置(彩色点)
  • 骨架连接线
  • 运动轨迹尾迹

6.4 轨迹可视化

生成轨迹图以分析运动模式:

deeplabcut.plot_trajectories(
    config_path,
    videos=['/path/to/video.mp4'],
    videotype='mp4',
    shuffle=1,
    filtered=False,         # 使用原始数据
    showfigures=True        # 显示图像
)

这将生成:

  • 各身体部位的 x, y 坐标随时间变化曲线
  • 运动轨迹俯视图
  • 置信度变化曲线

6.5 数据后处理

原始追踪数据可能包含噪声和缺失值,需要进行后处理:

滤波去噪

deeplabcut.filterpredictions(
    config_path,
    videos=['/path/to/video.mp4'],
    videotype='mp4',
    shuffle=1,
    filtertype='median',    # 中值滤波
    windowlength=5          # 滤波窗口
)

支持的滤波类型:

  • median:中值滤波,去除脉冲噪声
  • arima:ARIMA 模型,平滑轨迹
  • spline:样条插值,处理缺失值

插值缺失点

# 读取数据后使用 pandas 插值
df_interpolated = df.interpolate(method='linear')

6.6 与行为分析工具集成

DeepLabCut 的输出可以与多种行为分析工具集成:

SimBA(行为分类)

  • 基于机器学习的行为分类
  • 支持攻击、交配、社交等行为识别
  • https://github.com/sgoldenlab/simba

B-SOiD(无监督行为发现)

  • 自动发现行为模式
  • 无需预定义行为类别
  • https://github.com/YttriLab/B-SOID

自定义分析脚本示例

import pandas as pd
import numpy as np

# 读取追踪数据
df = pd.read_hdf('video_DLC...h5')

# 计算运动速度
snout_x = df[('DLC_...', 'snout', 'x')].values
snout_y = df[('DLC_...', 'snout', 'y')].values

dx = np.diff(snout_x)
dy = np.diff(snout_y)
speed = np.sqrt(dx**2 + dy**2)

# 计算总运动距离
total_distance = np.sum(speed)
print(f"总运动距离: {total_distance:.2f} 像素")

# 检测静止期(速度 < 阈值)
threshold = 2  # 像素/帧
immobile = speed < threshold
immobile_time = np.sum(immobile) / 30  # 假设 30fps
print(f"静止时间: {immobile_time:.2f} 秒")

七、总结与进阶

恭喜你完成了 DeepLabCut 的入门学习!让我们回顾整个流程并展望进阶方向。

7.1 完整工作流回顾

┌─────────────────┐
│  1. 准备视频    │
└────────┬────────┘
         ▼
┌─────────────────┐
│  2. 创建项目    │  deeplabcut.create_new_project()
└────────┬────────┘
         ▼
┌─────────────────┐
│  3. 提取帧      │  deeplabcut.extract_frames()
└────────┬────────┘
         ▼
┌─────────────────┐
│  4. 标注数据    │  deeplabcut.label_frames()
└────────┬────────┘
         ▼
┌─────────────────┐
│  5. 创建数据集  │  deeplabcut.create_training_dataset()
└────────┬────────┘
         ▼
┌─────────────────┐
│  6. 训练模型    │  deeplabcut.train_network()
└────────┬────────┘
         ▼
┌─────────────────┐
│  7. 评估模型    │  deeplabcut.evaluate_network()
└────────┬────────┘
         ▼
┌─────────────────┐
│  8. 分析视频    │  deeplabcut.analyze_videos()
└────────┬────────┘
         ▼
┌─────────────────┐
│  9. 可视化结果  │  deeplabcut.create_labeled_video()
└─────────────────┘

7.2 常见问题 FAQ

Q: 需要标注多少帧?
A: 通常 100-200 帧足够。关键是标注质量和多样性,而非数量。

Q: 训练需要多长时间?
A: 使用 GPU,50000 次迭代约需 2-4 小时。CPU 可能需要数天。

Q: 如何提高追踪精度?
A: 1) 增加高质量标注;2) 检查并修正错误标注;3) 增加训练迭代次数;4) 使用更大的网络。

Q: 可以追踪多个动物吗?
A: 可以,使用 maDLC(多动物追踪)功能,创建项目时设置 multianimal=True

Q: 如何处理新场景/新相机?
A: 可以在新视频上微调(fine-tune)现有模型,只需少量新标注即可适应。

7.3 进阶方向

多动物追踪 (maDLC)

  • 同时追踪多个动物并保持身份
  • 适用于社交行为研究
  • 官方教程:maDLC Quick Start

3D 姿态重建

  • 使用多相机系统重建三维姿态
  • 需要相机标定
  • 适用于复杂运动分析

实时追踪 (DLC-Live)

  • 低延迟实时推理
  • 支持闭环实验
  • https://github.com/DeepLabCut/DeepLabCut-live

Model Zoo

  • 预训练模型库
  • 无需训练即可直接使用
  • 包括小鼠、灵长类、人手等常见目标

7.4 参考资源

  • 官方文档: https://deeplabcut.github.io/DeepLabCut
  • GitHub 仓库: https://github.com/DeepLabCut/DeepLabCut
  • 原始论文: Mathis et al., Nature Neuroscience, 2018
  • 社区论坛: https://forum.image.sc/tag/deeplabcut
  • 官方 YouTube: DeepLabCut 视频教程

本教程基于 DeepLabCut 最新版本编写。如有任何问题或建议,欢迎在评论区留言讨论!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐