HF - DatasetDict and Image
- Image 를 HF DatasetDict 로 다루기.
- 사전 개념 정리
- 실습 0. 환경 점검과 공통 준비
- 실습 1. imagefolder로 DatasetDict 만들기
- 실습 2. Trainer 학습을 위한 최소 구성 이해
- 실습 3. map 사용 방식 실습
- 실습 4. set_transform 사용 방식 실습
- 실습 5. collate_fn 사용 방식 실습 (배치 전처리)
- 5-3. 주의 사항
- 실습 6. Trainer로 classification 학습 실행 실습
- 실습 7. 선택 기준 정리 연습
- 실습 8. Object Detection 테스크 간단 실습 (작성중)
- 실습 9. segmentation 테스크 간단 실습 (작성 중…)
- 참고:
"image"열이 필요한 경우
Image 를 HF DatasetDict 로 다루기.
DatasetDict기반 학습 파이프라인 구성"image"(이미지 원본 컬럼)와"pixel_values"(모델 입력 텐서 컬럼) 구분map기반 고정 전처리 구성 능력 확보set_transform기반 random data augmentation(torchvision사용) 이해.collate_fn기반 배치 전처리 구성 능력 확보- Trainer (트레이너)로 end-to-end 학습 실행해 보기
이 문서에서 dataset은 PyTorch의 Dataset이 아닌 HF의 Dataset 을 지칭함.
- PyTorch의 Dataset and DataLoader 은 다음을 참고: [PyTorch] Dataset and DataLoader
사전 개념 정리
"image"와 "pixel_values"의 차이 정리
image:Dataset계층의 원본 입력 표현(PIL.Image) 의미pixel_values: Transformers 모델이 받는 입력 텐서(torch.Tensor) 의미"pixel_values"는 보통AutoImageProcessor(ImageProcessor)가 생성- Trainer는
image를 직접 사용하지 않고,model(**batch)형태로"pixel_values"키를 요구.
실습 0. 환경 점검과 공통 준비
0-1. 패키지 버전 점검 단계
import datasets
import transformers
print("datasets:", datasets.__version__)
print("transformers:", transformers.__version__)
0-2. 실습용 더미 이미지 데이터 생성 단계
실제 데이터가 이미 있다면 이 절 생략 가능함.
- 다음의
torchvision.datasets.ImageFolder예제의 데이터를 이용해되 됨: test.zip
이 절은 imagefolder로더를 위한 최소 폴더 구조 생성 절(classifcation에서 많이 사용됨)임.
from pathlib import Path
from PIL import Image
import numpy as np
def make_dummy_image(path: Path, seed: int, size=(256, 256)):
rng = np.random.default_rng(seed)
arr = rng.integers(0, 256, size=(size[1], size[0], 3), dtype=np.uint8)
img = Image.fromarray(arr, mode="RGB")
path.parent.mkdir(parents=True, exist_ok=True)
img.save(path)
dataset_root = Path("dataset_root")
for split in ["train", "validation"]:
for cls in ["class0", "class1"]:
n = 24 if split == "train" else 8
for i in range(n):
make_dummy_image(
dataset_root / split / cls / f"{i:04d}.png",
seed=hash((split, cls, i)) % (2**32)
)
print("dataset_root ready")
실습 1. imagefolder로 DatasetDict 만들기
1-1. DatasetDict 로딩 단계
from datasets import load_dataset
dd_raw = load_dataset("imagefolder", data_dir="dataset_root")
print(dd_raw)
print(dd_raw["train"].features)
1-2. 샘플 접근과 타입 확인 단계
ex = dd_raw["train"][0]
print(ex.keys())
print(type(ex["image"])) # PIL.Image.Image 기대
print(ex["label"]) # int 기대
1-3. ClassLabel(names) 확인 단계
label_feature = dd_raw["train"].features["label"]
print(label_feature)
print("names:", label_feature.names)
실습 2. Trainer 학습을 위한 최소 구성 이해
2-1. 핵심 규칙 확인 단계
Trainer는 모델 입력을 model(**batch) 형태로 전달하는 구조임.
Vision 모델은 보통 pixel_values 키를 요구하므로
따라서 학습 batch에는 최소한 다음이 필요함.
"pixel_values"키의 데이터 :torch.Tensor"labels" 키의 데이터 :torch.LongTensor` 또는 label 컬럼에서 유도되는 값
여기서 labels 키 이름은 일반적으로 labels가 사용됨.
Dataset컬럼명은label인 경우,collate_fn에서labels로 만들어 전달하는 구조가 애용됨.
실습 3. map 사용 방식 실습
고정 전처리 에는 map 을 사용.
- 데이터셋 사전 변환
- 캐싱 가능
- 대량 처리
이 절에서는
- image를
pixel_values로 미리 변환하여 DatasetDict를 학습용 텐서로 고정 전처리.
map으로 적용되는 callable객체는 인자를 두가지 방식으로 선택가능함:
batched=False인 경우 : sample을 인자로 받음 (dict).batched=True인 경우 : batch를 인자로 받음 (dictorlist).- 기본적으로
batched=False임.
3-1. AutoImageProcessor 준비 단계
from transformers import AutoImageProcessor
ckpt = "google/vit-base-patch16-224-in21k"
processor = AutoImageProcessor.from_pretrained(ckpt)
print("processor ready")
3-2. map 전처리 함수 작성 단계
def preprocess(batch):
out = processor(batch["image"], return_tensors="pt")
batch["pixel_values"] = out["pixel_values"]
return batch
3-3. DatasetDict 전체에 map 적용 단계
map은 split별 Dataset 객체에 따로 적용하는 것도 가능하나,
일반적으론 DatasetDict 객체에 같이 적용함.
dd_map = dd_raw.map(
preprocess,
batched=True,
batch_size=8,
remove_columns=["image"], # 고정 전처리형에서 권장
)
print(dd_map)
print(dd_map["train"].features)
3-4. Trainer 입력을 위한 torch 포맷 설정 단계
dd_map.set_format(type="torch", columns=["pixel_values", "label"])
item = dd_map["train"][0]
print(item["pixel_values"].shape)
print(item["label"])
3-5. 주의할 점
remove_columns=["image"]이후set_transform을 사용할 경우image를 참조하기 때문에 문제가 발생함.batched=False로 두고 processor를 호출할 경우 성능 저하가 발생하니 주의할 것.load_from_cache_file=True동작이 기본이므로 디버그 단계에서 함수 수정이 반영되지 않을 수 있으니 주의 해야함.
디버깅 시 캐시 무시 옵션 (load_from_cache_file=False)을 사용할 것.
dd_map = dd_raw.map(
preprocess,
batched=True,
load_from_cache_file=False,
remove_columns=["image"],
)
실습 4. set_transform 사용 방식 실습
set_transform은 Dataset(HF의 Dataset)의 __getitem__을 살짝 감싸는 것" 으로 이해할 것.
Dataset의__getitem__시점 처리- epoch마다 반복 호출
PyTorch의DataLoader와 결합- 주로
torchvision.transforms와 연동됨:torchvision.transforms에 대한 참고자료torchvision.transforms.v2사용 권장.
Random Data Augmentation 에 주로 사용.
- epoch마다 달라지는 랜덤 증강을 image 기준으로 적용하여
pixel_values를 on-the-fly 생성 하는 방식. - 이를 위해서
"image"키의 column을 유지해야 함.
주의할 점은
set_transform에 넘겨지는 callable 객체는 반드시 하나의 sample로 넘겨짐- batch 전체가 넘겨지지 않음.
다음은 넘겨지는 하나의 sample example의 일반적인 형태:
example = {
"image": PIL.Image,
"label": int
}
4-1. torchvision transform (v2) 준비 단계
from torchvision.transforms import v2 as T
train_tfms = T.Compose([
T.RandomResizedCrop(224),
T.RandomHorizontalFlip(),
])
4-2. train용 transform 함수 작성 단계
def train_transform(example):
img = train_tfms(example["image"])
example["pixel_values"] = processor(img, return_tensors="pt")["pixel_values"][0]
return example
4-3. validation용 transform 함수 작성 단계
validation에는 랜덤 증강을 보통 적용하지 않는 것이 권장됨.
def val_transform(example):
example["pixel_values"] = processor(
example["image"],
return_tensors="pt")["pixel_values"][0]
return example
4-4. split별 set_transform 적용 단계
dd_aug = dd_raw
dd_aug["train"].set_transform(train_transform)
dd_aug["validation"].set_transform(val_transform)
x = dd_aug["train"][0]
y = dd_aug["validation"][0]
print(x["pixel_values"].shape, x["label"])
print(y["pixel_values"].shape, y["label"])
4-5. 주의 사항
"image"컬럼이map등에서 제거된 경우set_transform을 적용시 문제가 발생.train과validation에 동일한 랜덤 증강을 적용하는 것은 피할 것.transform함수에서 batch 입력이 아님을 기억.
실습 5. collate_fn 사용 방식 실습 (배치 전처리)
Dataset은 원본 image를 유지하면서- batch 구성 시점에 processor를 적용하여
pixel_values와labels를 생성하는 방식
이 방식은 segmentation, detection으로 확장에 많이 사용됨.
5-1. collate_fn 정의 단계
import torch
def collate_fn(batch):
images = [b["image"] for b in batch]
labels = torch.tensor([b["label"] for b in batch], dtype=torch.long)
out = processor(images, return_tensors="pt")
out["labels"] = labels
return out
5-2. DataLoader로 동작 검증 단계
PyTorch의 DataLoader 객체 와 함께 사용됨.
from torch.utils.data import DataLoader
loader = DataLoader(dd_raw["train"], batch_size=4, shuffle=True, collate_fn=collate_fn)
batch = next(iter(loader))
print(batch["pixel_values"].shape)
print(batch["labels"].shape)
5-3. 주의 사항
collate_fn에서"label"키를"labels"로 만들지 않을 경우 HT의 모델 입력 불일치 발생 가능성- ViT 등의 경우,
pixel_values를 입력텐서로labels는 라벨텐서로 기대. DatasetDict객체의 경우"label"을 키로 사용하는 경우가 일반적임.- 이는 키의 불일치로 문제가 일어남: 일반적으로 기본 collator 가 이를 처리해주는데 커스텀
collate_fn을 쓰면 문제가 일어나기 쉬움.
- ViT 등의 경우,
- 이미지 크기 가변 상태에서 모델이 기대하는 크기 불일치 발생 가능성
DataLoader단계에서 처리되므로 CPU 에서 연산 병목이 커질 수 있음.
실습 6. Trainer로 classification 학습 실행 실습
앞의 방식으로 구성된 DatasetDict를 Trainer에 연결하여 학습이 되는지를 확인하는 실습.
(연습 목적임.)
6-1. 모델 준비 단계
from transformers import AutoModelForImageClassification
# clf 의 경우
ckpt = "microsoft/swin-tiny-patch4-window7-224"
# ckpt = "facebook/convnext-tiny-224"
num_labels = len(dd_raw["train"].features["label"].names)
model = AutoModelForImageClassification.from_pretrained(
ckpt,
num_labels=num_labels
)
print("model ready")
6-2. TrainingArguments 설정 단계
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir = "./out_test",
per_device_train_batch_size = 8,
per_device_eval_batch_size = 8,
num_train_epochs = 1,
eval_strategy = "epoch",
save_strategy = "no",
logging_strategy = "steps",
logging_steps = 5,
report_to = "none",
)
6-3. Trainer 실행 방식 3가지 연결 패턴
패턴 A: map 기반 dd_map 사용 방식
from transformers import Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dd_map["train"],
eval_dataset=dd_map["validation"],
)
trainer.train()
패턴 B: set_transform 기반 dd_aug 사용 방식
dataset항목이 이미pixel_values를 포함하므로 그대로 사용 가능함.- 다만 Trainer가
"labels"키를 기대하므로,"label"을"labels"로 맞추는data_collator사용이 권장됨. - 즉,
collate_fn을 같이 쓰는게 좋음.
from transformers import Trainer
def collate_from_pixel_values(batch):
import torch
pixel_values = torch.stack([b["pixel_values"] for b in batch], dim=0)
labels = torch.tensor([b["label"] for b in batch], dtype=torch.long)
return {"pixel_values": pixel_values, "labels": labels}
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dd_aug["train"],
eval_dataset=dd_aug["validation"],
data_collator=collate_from_pixel_values,
)
trainer.train()
패턴 C: collate_fn 기반 dd_raw 사용 방식
from transformers import Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dd_raw["train"],
eval_dataset=dd_raw["validation"],
data_collator=collate_fn,
)
trainer.train()
실습 7. 선택 기준 정리 연습
7-1. 선택 기준 표기 연습
map: 전처리 결과 고정, 캐싱 활용, 실험 재현성 이 필요한 경우.set_transform: data augmentation이 필요한 경우, epoch마다 다른 입력이 필요한 경우.collate_fn: 배치 시점 처리, 가변 구조 태스크 확장 용도
7-2. 자가 점검 질문 3개
- “image 컬럼을 제거해도 되는 상황” 판별 연습
- “validation에 랜덤 증강을 적용하면 안 되는 이유” 설명 연습
- “Trainer가 pixel_values 키를 요구하는 이유” 설명 연습
실습 8. Object Detection 테스크 간단 실습 (작성중)
DatasetDict+collate_fn기반 구성-
object detection은
- image와 bbox의 동시 변환이 핵심
- bbox는 좌표 체계(format)와 canvas_size 관리가 핵심
- v2에서는
tv_tensors.BoundingBoxes를 사용하면 변환 동기화가 정석
이 예제는 이해를 돕기 위한 간단한 더미 annotation 기반 예제임.
8-0. detection 실습용 ckpt 준비 단계
Detection은 분류/segmentation과 processor 규칙이 다르므로 detection용 ckpt를 사용해야 함.
from transformers import AutoImageProcessor, AutoModelForObjectDetection
ckpt = "facebook/detr-resnet-50"
processor = AutoImageProcessor.from_pretrained(ckpt)
model = AutoModelForObjectDetection.from_pretrained(ckpt)
8-1. 더미 bbox annotation 생성 단계
- 각 이미지마다 박스 1개를 랜덤 생성하는 예시
- bbox는 transform 전에 일단 XYXY로 만들고, transform 후 processor에 줄 때 XYWH(COCO)로 변환하는 구성이 안정적임
import numpy as np
from PIL import Image
def make_dummy_boxes_for_image(img_pil: Image.Image, seed: int):
rng = np.random.default_rng(seed)
w, h = img_pil.size
# 1개 박스 생성: (x1, y1, x2, y2)
x1 = int(rng.integers(0, max(1, w // 2)))
y1 = int(rng.integers(0, max(1, h // 2)))
x2 = int(rng.integers(max(x1 + 1, w // 2), w))
y2 = int(rng.integers(max(y1 + 1, h // 2), h))
boxes_xyxy = [[x1, y1, x2, y2]]
class_ids = [0] # 단일 클래스 예시 (0)
return boxes_xyxy, class_ids
8-2. detection DatasetDict 생성 단계
"image"는datasets.Image()로 캐스팅하여 PIL.Image로 로딩"objects"컬럼에 bbox와 category를 저장- 여기서는 bbox를 XYXY로 저장하고, collate_fn에서
BoundingBoxes로 감싸 v2 변환 적용
from pathlib import Path
from datasets import Dataset, DatasetDict, Image as HFImage
def list_rows_for_detection(img_dir: Path):
rows = []
for ip in sorted(img_dir.glob("**/*.png")):
rows.append({"image": str(ip)})
return rows
train_rows = list_rows_for_detection(dataset_root / "train")
val_rows = list_rows_for_detection(dataset_root / "validation")
train_ds = Dataset.from_list(train_rows).cast_column("image", HFImage())
val_ds = Dataset.from_list(val_rows).cast_column("image", HFImage())
dd_det = DatasetDict({"train": train_ds, "validation": val_ds})
print(dd_det["train"].features)
- 이 단계에서는 일단 image만 구성함
- bbox는 “이미지를 실제로 열어 크기를 알아야” 만들기 쉬우므로, 더미 bbox는 collate_fn에서 생성하는 방식으로 단순화함
- 실제 데이터에서는 bbox를 dataset 컬럼으로 보관하는 것이 정석임
8-3. v2 + tvtensor 기반 detection collate_fn 검증
- v2 변환은
tv_tensors.Image와tv_tensors.BoundingBoxes를 함께 전달해야 동일 랜덤 파라미터가 공유됨 - bbox는 반드시
canvas_size=(H, W)가 필요함 - 변환 후 HF processor에는 COCO 형식(XYWH) annotations를 제공하는 방식이 DETR 계열에서 정석적임
import torch
from torch.utils.data import DataLoader
from torchvision.transforms import v2 as T
from torchvision import tv_tensors
# train용 기하 변환 예시 (간단 버전)
train_geo = T.Compose([
T.Resize((512, 512)),
T.RandomHorizontalFlip(p=0.5),
])
# tvtensor -> PIL 변환용 (processor에 PIL로 주는 구성이 안전)
to_pil = T.ToPILImage()
def xyxy_to_xywh(box_xyxy):
x1, y1, x2, y2 = box_xyxy
return [float(x1), float(y1), float(x2 - x1), float(y2 - y1)]
def collate_det(batch):
images_pil = []
annotations = []
for i, b in enumerate(batch):
img_pil = b["image"] # PIL.Image
boxes_xyxy, class_ids = make_dummy_boxes_for_image(img_pil, seed=hash(("det", i)) % (2**32))
# tvtensor wrapping
img_tv = T.ToImage()(img_pil) # tv_tensors.Image, shape (C,H,W)
H, W = img_tv.shape[-2], img_tv.shape[-1]
boxes_tv = tv_tensors.BoundingBoxes(
torch.tensor(boxes_xyxy, dtype=torch.float32),
format="XYXY",
canvas_size=(H, W),
)
# v2 transform 동기 적용
img_tv, boxes_tv = train_geo(img_tv, boxes_tv)
# processor 입력 준비: PIL 이미지로 변환
img_pil2 = to_pil(img_tv)
images_pil.append(img_pil2)
# processor annotations(COCO) 준비: XYWH + category_id
ann_list = []
for box, cid in zip(boxes_tv.tolist(), class_ids):
x, y, w, h = xyxy_to_xywh(box)
area = float(max(w, 0.0) * max(h, 0.0))
ann_list.append({
"bbox": [x, y, w, h],
"category_id": int(cid),
"area": area,
"iscrowd": 0,
})
annotations.append({
"image_id": i,
"annotations": ann_list,
})
# HF processor가 detection 학습 배치를 생성
# DETR 계열에서는 processor가 pixel_values와 labels(타깃 dict 리스트)를 만들어 줌
enc = processor(images=images_pil, annotations=annotations, return_tensors="pt")
# enc.keys() 예: pixel_values, pixel_mask, labels 등
return enc
det_loader = DataLoader(dd_det["train"], batch_size=2, shuffle=True, collate_fn=collate_det)
det_batch = next(iter(det_loader))
print(det_batch.keys())
print(det_batch["pixel_values"].shape)
print(type(det_batch["labels"]), len(det_batch["labels"]))
print(det_batch["labels"][0].keys())
-
tv_tensors.BoundingBoxes를 쓰는 이유- v2 transform이 bbox를 “의미 있는 객체”로 인식
- resize/flip 등에서 bbox가 자동으로 올바르게 갱신됨
- image와 bbox에 동일 랜덤 파라미터가 적용됨
-
processor에 annotations를 주는 이유
- DETR 계열은
labels가 단순 정수 텐서가 아니라, bbox/클래스 정보를 포함한 구조체(dict) 리스트 형태임 processor(images, annotations=...)가 학습 입력(pixel_values)과 타깃(labels)을 함께 구성하는 것이 정석임
- DETR 계열은
실습 9. segmentation 테스크 간단 실습 (작성 중…)
아래는 “HF 모델(Transformers) + DatasetDict + Trainer” 조합에서 정석적으로 쓰는 형태에 가깝게,
torchvision.transforms.v2와tvtensor를 이용해- image와 mask에 동일한 랜덤 기하 변환을 동기 적용하도록 작성한 예제임.
- 핵심은
Mask를 tvtensor로 만들면 보간(NEAREST)과 변환 동기화가 자연스럽게 보장 됨을 확인하는 것.
핵심 개념
- v2 변환은 입력이
tvtensor일 때 task-aware 동작이 가장 안정적임 tv_tensors.Image와tv_tensors.Mask를 함께 변환 함수에 넣으면 같은 랜덤 파라미터(crop 위치, flip 여부 등)가 image와 mask에 동일 적용됨Mask는 라벨 맵이므로 변환 시 최근접 보간(NEAREST)이 유지되어야 함 tvtensor를 쓰면 이 규칙이 자연스럽게 지켜지도록 설계됨
0) 준비: processor와 (선택) 모델
from transformers import AutoImageProcessor, AutoModelForSemanticSegmentation
ckpt = "nvidia/segformer-b0-finetuned-ade-512-512" # 예시
processor = AutoImageProcessor.from_pretrained(ckpt)
model = AutoModelForSemanticSegmentation.from_pretrained(ckpt)
1) v2 transform 정의: train과 validation 분리
- train: resize + random crop + random flip 같은 “기하 증강” 중심 구성 권장
- validation: resize 같은 “결정적(deterministic) 변환”만 적용 권장
from torchvision.transforms import v2 as T
# 입력 크기 정책(예시)
RESIZE_TO = (512, 512)
CROP_TO = (448, 448)
train_geo = T.Compose([
T.Resize(RESIZE_TO), # image/mask 모두 동일 resize
T.RandomCrop(CROP_TO), # 동일 crop 파라미터 공유
T.RandomHorizontalFlip(p=0.5) # 동일 flip 파라미터 공유
])
val_geo = T.Compose([
T.Resize(RESIZE_TO)
])
2) tvtensor 변환 + collate_fn (train용 / val용)
- HF Dataset의
"image","mask"는 보통 PIL.Image로 들어옴 - v2 변환을 제대로 쓰려면
Image/Mask를 tvtensor로 감싸는 편이 정석임 - 변환 후 HF
processor로pixel_values를 만들고, mask는(H, W)의int64텐서로 유지함
import numpy as np
import torch
from torchvision import tv_tensors
from torchvision.transforms import v2 as T
to_pil = T.ToPILImage() # tvtensor(Image) -> PIL 변환용
def _wrap_as_tvtensors(img_pil, mask_pil):
# Image: v2 ToImage()로 tv_tensors.Image로 변환
img_tv = T.ToImage()(img_pil) # tv_tensors.Image
# Mask: 클래스 id 라벨 맵이므로 정수 텐서로 tv_tensors.Mask로 변환
mask_np = np.array(mask_pil, dtype=np.int64) # (H, W)
mask_tv = tv_tensors.Mask(torch.from_numpy(mask_np)) # tv_tensors.Mask
return img_tv, mask_tv
def make_collate_seg(geo_transform, processor):
def collate_seg(batch):
images = []
masks = []
for b in batch:
img_pil = b["image"]
msk_pil = b["mask"]
img_tv, msk_tv = _wrap_as_tvtensors(img_pil, msk_pil)
# v2 transform에 (img, mask)를 같이 넣으면 동일 랜덤 파라미터가 공유됨
img_tv, msk_tv = geo_transform(img_tv, msk_tv)
# processor는 PIL 입력이 가장 안전하므로 PIL로 변환 후 전달
img_pil2 = to_pil(img_tv)
images.append(img_pil2)
# labels는 (H, W) int64 유지
masks.append(msk_tv.to(torch.int64))
out = processor(images, return_tensors="pt") # pixel_values 생성
labels = torch.stack(masks, dim=0) # (B, H, W)
return {
"pixel_values": out["pixel_values"],
"labels": labels
}
return collate_seg
collate_seg_train = make_collate_seg(train_geo, processor)
collate_seg_val = make_collate_seg(val_geo, processor)
3) DataLoader로 검증
from torch.utils.data import DataLoader
seg_loader = DataLoader(
dd_seg["train"],
batch_size=2,
shuffle=True,
collate_fn=collate_seg_train
)
seg_batch = next(iter(seg_loader))
print(seg_batch["pixel_values"].shape) # (B, 3, H, W) - processor 설정에 따름
print(seg_batch["labels"].shape) # (B, CROP_H, CROP_W) 예: (2, 448, 448)
print(seg_batch["labels"].dtype) # torch.int64
Trainer에 연결할 때의 정석 포인트
- segmentation은 보통 train/eval에 서로 다른 collate를 쓰고 싶지만,
Trainer는data_collator를 하나만 받음 -
초보자 연습에서는 다음 중 하나를 선택하는 방식이 안전함
- eval도 train과 동일한 크기 변환을 사용(증강만 빼고 크기만 동일)
- eval은
trainer.evaluate()전에 임시로 collator를 바꾸는 실험(초보자에겐 비권장)
연습용으로는
"train용 collate를 eval에도 동일하게 사용하되, geo_transform만 deterministic으로 구성"이 가장 단순. 즉Random*를 제외한Resize만 쓰는val_geo대신, 아예 train에서도Resize만 쓰는 버전을 권장.
요약
- v2를 “정석적으로” 쓰려면 tvtensor(
tv_tensors.Image/Mask) 기반이 가장 안정적임 (image, mask)를 함께 transform에 전달하여 랜덤 파라미터 동기화 확보가 핵심임- mask는 라벨 맵이므로 dtype과 보간 규칙(NEAREST)이 깨지지 않도록 설계하는 것이 핵심임
- HF 모델 입력은
pixel_values, 타깃은labels키로 맞추는 것이 가장 안전한 습관임
참고: "image" 열이 필요한 경우
- 랜덤 증강을 적용할 때
set_transform사용 시- epoch마다 다른 변형이 필요할 때
- 배치 시점 전처리를 할 때
collate_fn에서 processor를 적용할 때- detection, segmentation, multimodal로 확장할 때
- Segmentation / Detection 태스크
- image와 mask, box를 같이 변형해야 할 때
- resize, crop을 동기화해야 할 때
- 다른 모델로 재학습 가능성을 남길 때
- processor가 바뀔 수 있을 때
- 해상도나 정규화 규칙이 달라질 때
- 디버깅·시각화가 필요할 때
- 원본 이미지를 직접 확인해야 할 때
참고로 image 컬럼이 필요 없는 경우
- map으로 pixel_values를 고정 생성하고 나서
- 추가 증강이나 재전처리 계획이 없을 때
- 주로 단순 분류 학습만 할 때