1. Something-Something V2数据集概述

Something-Something V2是由20个实验室联合收集的大规模视频理解数据集,专注于日常物品交互行为的细粒度分类。该数据集包含174类人类与物体的基础交互动作,每个类别平均有1,000个以上视频样本,总视频数量超过220,000个。与常规动作识别数据集不同,Something-Something的独特价值在于其强调"物体如何被操作"而非"谁在做什么"。

关键特性:所有视频均以第一人称视角拍摄,背景统一为纯色,确保模型学习重点是动作本身而非场景信息。每个视频时长2-3秒,分辨率320×240,帧率12fps,文件大小约200-500KB。

数据集中的动作标签设计具有以下特点:

  • 语义粒度极细(如"推物体使其几乎掉落但未掉" vs "推物体使其从桌子掉落")
  • 包含真实操作与假装操作对比(如"拿起物体" vs "假装拿起物体")
  • 涵盖物体状态变化(如"弯曲物体直至断裂")
  • 包含失败操作场景(如"尝试插入但未成功")

2. 数据集获取与预处理

2.1 官方获取渠道

原始数据集需通过 官网申请 ,但处理流程较复杂。推荐使用以下替代方案:

  1. 飞桨AI Studio备份
    访问 something-something-V1数据集 获取已预处理版本,包含:

    • 视频文件(MP4格式)
    • 预提取的RGB帧(JPEG格式)
    • 光流数据(NPY格式)
    • 标签文件(JSON格式)
  2. 学术镜像源
    部分高校实验室提供镜像下载,如:

    wget http://mirror.example.edu/something_v2.tar.gz
    tar -xzf something_v2.tar.gz
    

2.2 本地预处理流程

推荐使用以下Python脚本进行标准化处理:

import decord
from pathlib import Path

def preprocess_video(video_path, output_dir, clip_len=8):
    """视频预处理函数"""
    vr = decord.VideoReader(str(video_path))
    frames = vr.get_batch(np.linspace(0, len(vr)-1, clip_len)).asnumpy()
    
    for i, frame in enumerate(frames):
        save_path = output_dir / f"frame_{i:04d}.jpg"
        cv2.imwrite(str(save_path), cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))

关键参数说明:

  • clip_len=8 :TSM模型的标准输入帧数
  • 采样策略:线性时间采样(非均匀采样更适合长视频)

2.3 标签处理技巧

数据集提供两种标签格式:

# 英文标签
cls_text = ["Pushing something so that it almost falls off but doesn't", ...]

# 中文标签 
cls_chinese_text = ["推某物使其几乎掉落但未掉", ...]

推荐使用pandas构建标签映射表:

import pandas as pd

label_df = pd.DataFrame({
    'class_id': range(174),
    'en': cls_text,
    'zh': cls_chinese_text
})
label_df.to_csv('label_mapping.csv', index=False)

3. TSM模型实战应用

3.1 模型下载与加载

使用预训练的TSM模型(ResNet50 backbone):

import torch
from models import TSN

# 加载配置
num_class = 174
modality = 'RGB'
arch = 'resnet50'
pretrain = 'TSM_something_RGB_resnet50_shift8_blockres_avg_segment8_e45.pth'

# 构建模型
model = TSN(num_class, 8, modality,
            base_model=arch,
            consensus_type='avg',
            dropout=0.5)

# 加载预训练权重
checkpoint = torch.load(pretrain)
state_dict = {k.replace('module.', ''): v for k,v in checkpoint['state_dict'].items()}
model.load_state_dict(state_dict)

避坑提示:官方模型使用DataParallel训练,需去除键名中的'module.'前缀

3.2 训练技巧与参数配置

针对Something-Something数据集的优化策略:

  1. 数据增强组合 :

    train_transform = transforms.Compose([
        transforms.Resize(256),
        transforms.RandomCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ColorJitter(brightness=0.2, contrast=0.2),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    ])
    
  2. 关键训练参数 :

    batch_size: 32
    lr: 0.01
    lr_steps: [20, 40]
    epochs: 50
    shift_div: 8  # 时序移位比例
    
  3. 样本均衡策略 :

    from torch.utils.data import WeightedRandomSampler
    
    class_counts = np.bincount(labels)
    weights = 1. / class_counts[labels]
    sampler = WeightedRandomSampler(weights, len(weights))
    

3.3 模型推理示例

实现视频动作分类的完整流程:

def classify_video(model, video_path):
    # 视频读取
    vr = decord.VideoReader(video_path)
    frames = vr.get_batch(np.linspace(0, len(vr)-1, 8)).asnumpy()
    
    # 预处理
    inputs = torch.stack([train_transform(Image.fromarray(f)) for f in frames])
    inputs = inputs.unsqueeze(0)
    
    # 推理
    with torch.no_grad():
        outputs = model(inputs)
        probs = torch.softmax(outputs, dim=1)
    
    # 结果解析
    top5_prob, top5_class = torch.topk(probs, 5)
    return [(label_df.iloc[i.item()]['zh'], p.item()) 
            for i, p in zip(top5_class[0], top5_prob[0])]

4. 常见问题与解决方案

4.1 数据加载问题

问题1 :视频长度不一致
解决方案:使用循环填充或动态采样

def adjust_clip_length(frames, target_len=8):
    if len(frames) < target_len:
        frames += [frames[-1]] * (target_len - len(frames))
    return frames[:target_len]

问题2 :中文标签乱码
解决方案:指定编码格式

with open('labels.json', 'r', encoding='utf-8-sig') as f:
    labels = json.load(f)

4.2 模型训练问题

问题1 :GPU内存不足
优化策略:

  • 减小 batch_size (不低于8)
  • 使用梯度累积
optimizer.zero_grad()
for i, (inputs, targets) in enumerate(train_loader):
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss = loss / 4  # 假设累积4次
    loss.backward()
    
    if (i+1) % 4 == 0:
        optimizer.step()
        optimizer.zero_grad()

问题2 :过拟合严重
应对方法:

  • 增加时序dropout(TSM特有)
model = TSN(..., temporal_dropout=0.2)

4.3 性能提升技巧

  1. 时序增强 :
    对视频进行随机时间翻转(需同步调整光流)

    if random.random() > 0.5:
        frames = frames[::-1]
    
  2. 模型融合 :
    结合RGB和光流分支预测

    rgb_pred = model_rgb(rgb_input)
    flow_pred = model_flow(flow_input)
    final_pred = (rgb_pred + flow_pred) / 2
    
  3. 标签平滑 :
    缓解样本不均衡影响

    criterion = CrossEntropyLoss(label_smoothing=0.1)
    

5. 扩展应用与改进方向

5.1 领域自适应改进

当应用于新场景时,建议:

  1. 部分冻结策略 :

    for name, param in model.named_parameters():
        if 'base_model.conv1' in name or 'base_model.layer1' in name:
            param.requires_grad = False
    
  2. 原型网络适应 :

    # 计算类别原型
    class_prototypes = []
    for class_id in range(174):
        samples = extract_features(class_samples[class_id])
        class_prototypes.append(samples.mean(dim=0))
    

5.2 实时应用优化

部署时的加速方案:

  1. 模型轻量化 :

    python -m onnxruntime.tools.convert_onnx_models_to_ort \
        --input tsm.onnx --output tsm.ort
    
  2. 帧缓存策略 :

    from collections import deque
    
    frame_buffer = deque(maxlen=8)
    while True:
        frame = get_new_frame()
        frame_buffer.append(preprocess(frame))
        
        if len(frame_buffer) == 8:
            inputs = torch.stack(list(frame_buffer))
            pred = model(inputs.unsqueeze(0))
            show_result(pred)
    

### 5.3 多模态扩展
结合其他传感器数据:
```python
class MultimodalTSM(nn.Module):
    def __init__(self):
        super().__init__()
        self.visual_branch = TSN(174, 8, 'RGB')
        self.audio_branch = AudioNetwork()
        
    def forward(self, video, audio):
        vis_feat = self.visual_branch(video)
        aud_feat = self.audio_branch(audio)
        return self.fc(torch.cat([vis_feat, aud_feat], dim=1))

在实际项目中,我们发现将TSM的时序移位模块与音频频谱图特征结合,可使准确率提升3-5个百分点。

Logo

邀请您加入社区

更多推荐