개발 환경: Colab
Drive Mount
from google.colab import drive
drive.mount('/content/drive')
Import Module
import torch
import torchvision
from torchvision import transforms # 이미지 데이터 augmentation
import os
import glob
Pytorch 데이터셋 클래스
1. 파이토치 데이터셋 클래스 만들기
- 파이토치 데이터셋 클래스는 init, getitem,len 이렇게 특수 메소드 3개를 요구한다.
- 항상 같은 포맷을 만드는 습관이 중요하다.
- 따라서 root_path, mode(train/val/test), transform(전처리&Augmentation) 3개의 입력을 받아 data와 label을 출력하는 클래스를 만들도록 하자.
from torch.utils.data import Dataset, DataLoader
import cv2
import os
class Custom_dataset(Dataset):
def __init__(self, root_path, mode, transforms):
self.all_data = sorted( glob.glob( os.path.join(root_path, mode, '*', '*') ) ) # 전체 경로
self.transforms = transforms
def __getitem__(self, index):
if torch.is_tensor(index): # 인덱스가 tensor형태일 수 있는 것을 방지
index = index.tolist()
data_path = self.all_data[index] # 인덱스가 부여된 데이터 1개
image = cv2.imread(data_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # cv2 라이브러리의 BGR 형식을 RGB로 permute
# transfrom 적용
if self.transforms is not None:
augmentation = self.transforms(image = image)
image = augmentation['image']
# 이미지의 이름을 이용하여, label 부여하기
if 'dolphin' in data_path:
label = 0
elif 'shark' in data_path:
label = 1
else:
label = 2
return image, label
def __len__(self):
length = len(self.all_data)
return length
2. 전처리와 Augmentation을 적용
- Normalize
- 픽셀 값에 대해 (X-mean)/std를 진행하며, 이때 통계값은 ImageNet 데이터셋의 RGB 통계값을 이용할 예정이다.
- 텐서화
- 파이토치는 tensor 자료형을 이용하므로 totensor를 해준다.
- Augmentation
- trainset에만 적용한다.
import albumentations as A
from albumentations.pytorch.transforms import ToTensorV2 # albumentations 텐서화 함수
train_transforms = A.Compose([
A.Resize(224,224),
A.Transpose(p=0.5),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.ShiftScaleRotate(p=0.5),
A.HueSaturationValue(hue_shift_limit=20, sat_shift_limit=20, val_shift_limit=20, p=0.5),
A.RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),
A.ChannelShuffle(),
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), max_pixel_value=255.0, always_apply=False, p=1.0), # 이미지넷 데이터셋 통계값으로 Normalize
A.CoarseDropout(p=0.5),
ToTensorV2()
])
test_transforms = A.Compose([
A.Resize(224,224),
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), max_pixel_value=255.0, always_apply=False, p=1.0), # 텐서타입은 안해줌
ToTensorV2() # Normalize를 먼저하고 tensor화를 진행해야한다.
])
### Pytorch 데이터 클래스 생성
train_class = Custom_dataset(root_path=root_path, mode='train', transforms=train_transforms)
valid_class = Custom_dataset(root_path=root_path, mode='valid', transforms=test_transforms)
test_class = Custom_dataset(root_path=root_path, mode='test', transforms=test_transforms)
### Pytorch BatchLoader 생성 (학습에 이용할 최종 dataloader)
from torch.utils.data import DataLoader as DataLoader
train_loader = DataLoader(train_class, batch_size=8, shuffle = True, num_workers=0)
valid_loader = DataLoader(valid_class, batch_size=8, shuffle = False, num_workers=0)
test_loader = DataLoader(test_class, batch_size=8, shuffle = False, num_workers=0)
응용
- 원래 0~255 픽셀 값을 가진 돌고래 이미지는 Augmentation이 적용되어 (train_class[0][0]) 이미지가 변형되었다.
- train_class[0][0] 데이터를 시각화할 수 있도록 시각화 라이브러리가 요구하는 numpy 타입의 올바른 이미지 데이터로 되돌리는 역함수를 만들어 시각화해보자.
train_class.all_data[0] # train 전체에서 첫번째 이미지 경로
-----------------------
'/Your_path/train/dolphin/dolphin_000.jpg'
from PIL import Image as PILImage
PILImage.open(train_class.all_data[0])

train_class[0][0] # augmentation이 적용된 이미지(C,H,W)
-----------------
tensor([[[ 0.8104, 0.8104, 0.7077, ..., -0.5767, -0.6965, -0.7993],
[ 0.7077, 0.7077, 0.7762, ..., -0.3027, -0.4568, -0.5424],
[ 0.7419, 0.7419, 0.8104, ..., -0.3541, -0.5082, -0.5938],
...,
[-0.9192, -0.9363, -0.9705, ..., -1.3815, -1.3644, -1.3644],
[-0.9192, -0.9192, -0.9363, ..., -1.3302, -1.3130, -1.2788],
[-0.9020, -0.9020, -0.9363, ..., -1.3302, -1.3130, -1.2788]],
[[ 1.8333, 1.8333, 1.7633, ..., 0.9755, 0.8704, 0.7479],
[ 1.7458, 1.7633, 1.8333, ..., 1.2731, 1.1331, 1.0105],
[ 1.8158, 1.8333, 1.9209, ..., 1.2556, 1.1331, 1.0105],
...,
[ 1.0105, 1.0105, 0.9930, ..., 0.8179, 0.8179, 0.8179],
[ 0.9755, 0.9580, 0.9930, ..., 0.8179, 0.8354, 0.8354],
[ 0.9755, 0.9580, 0.9930, ..., 0.8179, 0.8354, 0.8354]],
[[ 2.4831, 2.4657, 2.3437, ..., 2.0300, 1.8905, 1.7860],
[ 2.4483, 2.4134, 2.4657, ..., 2.3088, 2.1694, 2.0823],
[ 2.5703, 2.5529, 2.5877, ..., 2.3437, 2.1868, 2.0997],
...,
[ 2.2043, 2.2217, 2.2391, ..., 2.1694, 2.1868, 2.1868],
[ 2.1694, 2.2043, 2.2217, ..., 2.2043, 2.2217, 2.2217],
[ 2.1694, 2.1868, 2.2217, ..., 2.2043, 2.2217, 2.2217]]])
- 시각화 라이브러리로는 matplot을 사용할 것이다.
- format을 (c,h,w)에서 (h,w,c)로 바꿔준다.
- tensort에서 array 형태로 바꿔준다.
image = train_class[0][0].permute(1, 2, 0).numpy()
image
--------------------------------------------------
array([[[-0.6280504 , 2.3060224 , 0.44392157],
[-0.6622999 , 2.3060224 , 0.4264924 ],
[-0.6622999 , 2.3410363 , 0.44392157],
...,
[ 1.1186745 , 2.4285712 , 1.8556863 ],
[ 1.1015497 , 2.4285712 , 1.8208278 ],
[ 1.2042983 , 2.4285712 , 1.9602615 ]],
[[-1.0561693 , 2.3585434 , 0.16505449],
[-1.0561693 , 2.3585434 , 0.16505449],
[-1.141793 , 2.3235292 , 0.09533771],
...,
[-0.31980482, 2.2359943 , 0.6705011 ],
[-0.25130582, 2.2184873 , 0.70535946],
[-0.54242665, 1.9033612 , 0.4090632 ]]], dtype=float32)
- 위의 image를 unnormalize해준다.
- normalize의 역순으로 계산하면 된다.
# unnormalize
mean=(0.485, 0.456, 0.406)
std=(0.229, 0.224, 0.225)
augmentation_img=(((image * std)+mean)*255).astype(int)
augmentation_img
-------------------------------------------------------
array([[[ 23, 148, 221],
[ 29, 141, 220],
[ 26, 141, 217],
...,
[ 77, 156, 217],
[ 91, 169, 232],
[106, 183, 245]],
[[ 29, 55, 74],
[ 30, 57, 77],
[ 31, 59, 80],
...,
[119, 191, 233],
[137, 207, 247],
[143, 213, 253]]])

역함수 로직
- 1. (C,H,W) → (H,W,C)
- 2. Tensor → Array
- 3. Unnormalize
- $ ((\text{Image} \times \text{std}) + \text{mean}) \times 255 $
- 4. Float → Int
def converter(augmentationed_image):
mean=(0.485, 0.456, 0.406)
std=(0.229, 0.224, 0.225)
### 역함수 로직을 짜주세요. ###
augmentationed_image = augmentationed_image.permute(1,2,0) # 채널축 정상적으로 맨뒤로 보내기
augmentationed_image = augmentationed_image.numpy() # numpy 타입으로 변환
augmentationed_image = (augmentationed_image * std) + mean # unnormalize
converted_image = augmentationed_image * 255
converted_image = converted_image.astype(int)
return converted_image
'Study' 카테고리의 다른 글
| [SQL] Chapter 2. (3~5강) (4) | 2025.07.07 |
|---|---|
| [Computer Vision] Dolphin, Shark, Whale을 분류하는 ResNet50 파이프라인 구축 (0) | 2024.08.29 |
| [Computer Vision] 이미지 픽셀 값 조정 (0) | 2024.08.29 |
| [Computer Vision] 학습 데이터 디렉토리 클래스 구축 (0) | 2024.08.28 |
| [NLP] 10. Named Entity Recognition (0) | 2024.08.25 |