如何通过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
相关产品推荐
相关产品推荐

