feat(actpred): 训练时安全图像增强(ColorJitter),支持任意 frame_len
训练集启用 --augment 后对每帧施加亮度/对比度/饱和度/色调变换, 同一样本内所有帧共享参数(模拟连续帧光照不变),验证集不增强。 仅颜色空间变换,无空间变换,动作标签不受影响。 删除 t1.mt(@TEST 块无对应插件,录制时报错)。
This commit is contained in:
1 parent
85133868f3
commit
5af863a2c5
5 files changed
+136
-23
No files matched your search
@@ -40,6 +40,7 @@ class TrainConfig:
|
||||
num_workers: int = 2
|
||||
seed: int = 42
|
||||
max_grad_norm: float = 1.0
|
||||
augment: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -87,6 +88,8 @@ def build_argparser(description: str = "") -> argparse.ArgumentParser:
|
||||
parser.add_argument("--num-workers", type=int, default=None)
|
||||
parser.add_argument("--seed", type=int, default=None)
|
||||
parser.add_argument("--max-grad-norm", type=float, default=None)
|
||||
parser.add_argument("--augment", action=argparse.BooleanOptionalAction, default=None,
|
||||
help="训练时启用安全图像增强(ColorJitter:亮度/对比度/饱和度/色调)")
|
||||
parser.add_argument("--init-from", type=str, default=None,
|
||||
help="预训练 checkpoint 路径,作为微调起点(strict=False 加载兼容权重)")
|
||||
parser.add_argument("--resume", type=str, default=None,
|
||||
@@ -232,6 +235,7 @@ def apply_overrides(cfg: Config, args: argparse.Namespace) -> Config:
|
||||
"num_workers": ("train", "num_workers"),
|
||||
"seed": ("train", "seed"),
|
||||
"max_grad_norm": ("train", "max_grad_norm"),
|
||||
"augment": ("train", "augment"),
|
||||
}
|
||||
args_dict = vars(args)
|
||||
for arg_name, (section, field) in mapping.items():
|
||||
|
||||
+14
-1
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import numpy as np
|
||||
from pathlib import Path
|
||||
@@ -7,6 +8,7 @@ from PIL import Image
|
||||
import torch
|
||||
from torch.utils.data import Dataset
|
||||
from torchvision import transforms
|
||||
from torchvision.transforms import functional as TF
|
||||
|
||||
|
||||
def _natural_key(p):
|
||||
@@ -19,12 +21,13 @@ class ActionDataset(Dataset):
|
||||
image_width: int = 640, image_height: int = 480,
|
||||
normalize_actions: bool = False,
|
||||
action_stats_path: str = None, episode_indices: list = None,
|
||||
frame_len: int = 3):
|
||||
frame_len: int = 3, augment: bool = False):
|
||||
self.history_len = history_len
|
||||
self.action_dim = action_dim
|
||||
self.image_width = image_width
|
||||
self.image_height = image_height
|
||||
self.frame_len = frame_len
|
||||
self.augment = augment
|
||||
|
||||
self.transform = transforms.Compose([
|
||||
transforms.Resize((image_height, image_width)),
|
||||
@@ -92,8 +95,18 @@ class ActionDataset(Dataset):
|
||||
def __getitem__(self, idx):
|
||||
image_paths, action_history, target = self.samples[idx]
|
||||
frames = []
|
||||
if self.augment:
|
||||
bf = random.uniform(0.8, 1.2)
|
||||
cf = random.uniform(0.8, 1.2)
|
||||
sf = random.uniform(0.8, 1.2)
|
||||
hf = random.uniform(-0.05, 0.05)
|
||||
for p in image_paths:
|
||||
image = Image.open(p).convert("RGB")
|
||||
if self.augment:
|
||||
image = TF.adjust_brightness(image, bf)
|
||||
image = TF.adjust_contrast(image, cf)
|
||||
image = TF.adjust_saturation(image, sf)
|
||||
image = TF.adjust_hue(image, hf)
|
||||
frames.append(self.transform(image))
|
||||
images = torch.stack(frames) # (F, 3, S, S)
|
||||
action_history = torch.tensor(action_history, dtype=torch.float32)
|
||||
|
||||
+2
-1
@@ -84,7 +84,8 @@ def main():
|
||||
train_ds = ActionDataset(
|
||||
cfg.data.data_dir, cfg.data.history_len, cfg.data.action_dim,
|
||||
cfg.data.image_width, cfg.data.image_height, cfg.data.normalize_actions,
|
||||
cfg.data.action_stats_path, train_indices, cfg.data.frame_len)
|
||||
cfg.data.action_stats_path, train_indices, cfg.data.frame_len,
|
||||
augment=cfg.train.augment)
|
||||
if cfg.data.normalize_actions and not cfg.data.action_stats_path:
|
||||
# 归一化统计量必须只用训练集计算,再供验证集复用,否则 val loss 不可信
|
||||
stats_path = os.path.join(cfg.train.checkpoint_dir, "action_stats.npy")
|
||||
|
||||
Reference in new issue
Block a user