You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Data Augmentation扩充Charades Dataset中c137类样本实例?

解决方案:离线生成增强孪生文件夹 + 类别映射加载

针对你的需求,核心问题是你需要物理上的孪生文件夹(增强后的实际文件),而torchvision.transforms在DataLoader中是在线实时变换,不会生成实体文件。下面是具体的实现步骤和代码:

1. 离线生成c137的增强孪生文件夹

编写脚本对c137的每个视频帧文件夹生成多个增强版本,每个版本对应一个独立的孪生文件夹,同时保证同一视频的所有帧使用相同的变换参数(维护动作时序连贯性)。

代码示例

import os
import shutil
import torch
from PIL import Image
from torchvision import transforms

# 定义3种不同的增强变换组合(可根据需求增减)
aug_configs = {
    "rot_flip": {
        "desc": "随机旋转±15度+随机水平翻转+亮度调整",
        "get_transform": lambda: transforms.Compose([
            transforms.Lambda(lambda img: img.rotate(transforms.RandomRotation.get_params((-15, 15)))),
            transforms.Lambda(lambda img: img.transpose(Image.FLIP_LEFT_RIGHT) if torch.rand(1).item() < 0.5 else img),
            transforms.Lambda(lambda img: transforms.functional.adjust_brightness(img, transforms.ColorJitter.get_params((0.8, 1.2), None, None, None))),
            transforms.ToTensor(),
            transforms.ToPILImage()
        ])
    },
    "gray_crop": {
        "desc": "灰度化+随机裁剪(保持原尺寸)",
        "get_transform": lambda: transforms.Compose([
            transforms.Grayscale(num_output_channels=3),
            transforms.Lambda(lambda img: transforms.functional.resized_crop(
                img, *transforms.RandomResizedCrop.get_params(img, scale=(0.8, 1.0), ratio=(1.0, 1.0)),
                size=(img.size[1], img.size[0])
            )),
            transforms.ToTensor(),
            transforms.ToPILImage()
        ])
    },
    "affine_equalize": {
        "desc": "随机平移+直方图均衡化",
        "get_transform": lambda: transforms.Compose([
            transforms.Lambda(lambda img: transforms.functional.affine(
                img, angle=0, translate=transforms.RandomAffine.get_params((0,0), translate=(0.1,0.1), img_size=img.size),
                scale=1.0, shear=0
            )),
            transforms.RandomEqualize(p=1.0),
            transforms.ToTensor(),
            transforms.ToPILImage()
        ])
    }
}

# 数据集根路径(替换为你的实际路径)
base_dir = "your_charades_dataset_path"
c137_src_dir = os.path.join(base_dir, "c137")
c137_aug_root = os.path.join(base_dir, "c137_augmented")
os.makedirs(c137_aug_root, exist_ok=True)

# 遍历c137下的每个视频文件夹
for video_folder in os.listdir(c137_src_dir):
    video_src_path = os.path.join(c137_src_dir, video_folder)
    if not os.path.isdir(video_src_path):
        continue

    # 为每个增强组合生成孪生文件夹
    for aug_suffix, config in aug_configs.items():
        aug_video_dir = os.path.join(c137_aug_root, f"{video_folder}_{aug_suffix}")
        os.makedirs(aug_video_dir, exist_ok=True)
        
        # 生成当前视频的固定变换(保证时序连贯)
        transform = config["get_transform"]()
        
        # 按顺序处理视频帧
        for frame_file in sorted(os.listdir(video_src_path)):
            frame_src_path = os.path.join(video_src_path, frame_file)
            if not frame_file.lower().endswith(('.png', '.jpg', '.jpeg')):
                continue
            
            img = Image.open(frame_src_path).convert("RGB")
            aug_img = transform(img)
            aug_img.save(os.path.join(aug_video_dir, frame_file))

# 可选:将原c137和增强后的文件夹合并为一个逻辑类别文件夹
c137_total_dir = os.path.join(base_dir, "c137_total")
os.makedirs(c137_total_dir, exist_ok=True)
# 复制原c137内容
for video_folder in os.listdir(c137_src_dir):
    shutil.copytree(os.path.join(c137_src_dir, video_folder), os.path.join(c137_total_dir, video_folder), dirs_exist_ok=True)
# 复制增强后的内容
for video_folder in os.listdir(c137_aug_root):
    shutil.copytree(os.path.join(c137_aug_root, video_folder), os.path.join(c137_total_dir, video_folder), dirs_exist_ok=True)

2. 修改数据集加载逻辑

将合并后的c137_total文件夹与c025、c142视为同一层级的类别文件夹,通过类别映射让模型将其识别为原c137类别。

代码示例

from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader

# 数据集根路径
base_dir = "your_charades_dataset_path"

# 自定义类别映射:将c137_total映射为原c137的标签
class_mapping = {
    "c025": 0,
    "c137_total": 1,
    "c142": 2
}

# 定义训练时的在线增强(进一步提升泛化)
train_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 加载数据集并修改类别映射
train_dataset = ImageFolder(root=base_dir, transform=train_transform)
train_dataset.class_to_idx = class_mapping
train_dataset.idx_to_class = {v: k for k, v in class_mapping.items()}

# 创建DataLoader(无需下采样,直接加载所有样本)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4, pin_memory=True)

关键说明

  • 离线生成孪生文件夹:完全满足你需要实体增强文件的需求,原c137有40个视频,每个生成3个增强版本后,总样本量变为160,可通过增加增强组合进一步扩充。
  • 时序连贯性:同一视频的所有帧使用相同的变换参数,避免破坏动作的时序逻辑,适合动作检测任务。
  • 无下采样:保持c025和c142的全部样本,保证模型能充分学习这两类的特征。

内容的提问来源于stack exchange,提问作者Paloma Jimeno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:45:43