Boostcamp AI Tech

[Boostcamp Day-16] Image Classification - Dataset

ju_young 2021. 8. 25. 02:27
728x90

Preprocessing

1. Bounding box

가끔 필요 이상으로 많은 정보를 가지고 있기 때문에 target 객체만을 crop할 수 있어야한다.

2. Resize

계산의 효율을 위해 적당한 크기로 사이즈 변경이 필요하다. 너무 큰 사이즈를 사용하면 계산량이 많이지기 때문

Generalization

1. Bias & Variance

Underfitting, Overffiting이 일어나지 않게 일반화가 필요

2. Train / Validation

훈련 셋 중 일정 부분을 따로 분리, 검증 셋으로 활용 (cross-validation)

3. Data Augmentation

주어진 데이터가 가질 수 있는 Case(경우), State(상태)의 다양성

  • torchvision.transforms : Randomcrop, Filp
  • Albumentations

Data Generation

1. Data Feeding

  • 모델에 data(먹이)를 준다는 의미이다. data를 너무 많이 주어서도 안되고 너무 적게 주어서도 안된다.
  • prepocessing에 따라 처리되는 속도가 달라진다.

torch.utils.data

Dataset

Vanilla data를 dataset으로 변환해야한다.

# Dataset 구조
from torch.utils.data import Dataset

class MyDataset(Dataset):
    def __init__(self):
        pass

    def __getitem__(self, index):
        return None

    def __len__(self):
        return None

DataLoader

dataset을 효율적으로 사용할 수 있도록 관련 기능들을 추가할 수 있다.

train_loader = torch.utils.data.DataLoader(
    train_set,
    batch_size=batch_size,
    num_workers=num_workers,
    drop_last=True,
)

Dataset 구현

class TrainDataset(Dataset):
    def __init__(self, data, transform):
        self.img_paths = data['image_path']
        self.label = data['label']
        self.transform = transform
    
    def __getitem__(self, index):
        image = Image.open(self.img_paths[index])
        if self.transform:
            image = self.transform(image)
        return image, self.label[index]
    
    def __len__(self):
        return len(self.label)

1. Albumentations

다양한 augmentation을 시도해보기위해 albumentations를 수행해보았다.

https://albumentations.ai/docs/api_reference/augmentations/transforms/

 

Albumentations Documentation - Transforms (augmentations.transforms)

Albumentations: fast and flexible image augmentations

albumentations.ai

 

  • pytorch의 transforms보다 더 다양한 augmentation을 수행할 수 있다.
  • pytorch와 달리 tranform을 했을 때 dictionary가 반환되어 "['image']"라고 따로 지정해주어야한다.

2. OpenCV

불필요한 정보를 없애는 방법으로 opencv를 사용하여 bounding box를 그리거나 crop하는 시도를 해보았다.

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

imgs = []
# data -> DataFrame
# image_path = 이미지 위치에 대한 경로
img_ids = data.sample(30).image_path

for img_id in img_ids:
    img = np.array(Image.open(img_id))
    bbox = face_cascade.detectMultiScale(img)
    
    if len(bbox):
        bbox = max([(sum([w,h]), (x,y,w,h)) for (x,y,w,h) in bbox], key=lambda x: x[0])[1]
        (x,y,w,h) = bbox
        img = img[y: y + h, x: x + w] #bbox만큼 crop
        # 224,224로 resize하여 size를 통일
        img = cv2.resize(img, dsize=(224, 224), interpolation=cv2.INTER_LINEAR) 
    imgs.append(img)

imgs = np.array(imgs)

fig, axes = plt.subplots(3, 10, figsize=(12, 6))

idx = 0
for i in range(3):
    for j in range(10):
        axes[i][j].imshow(imgs[idx])
        idx += 1
plt.show()
  • 몇몇의 이미지에서는 얼굴을 잘 인식하여 bounding box가 잘 나오지만 반대로 인식을 아예하지 못하는 경우나 잘 못 인식하는 경우가 생긴다.
  • cv를 사용하여 crop한 이미지는 사용할 수 없다고 판단

3. 밝기 Random 적용

몇 장 이미지를 확인했을 때 어두운 이미지, 밝은 이미지 등 밝기가 제각각이어서 transforms.ColorJitter를 사용하여 brightness=0.5를 추가해주었다. 밝기 적용 후 성능 향상이 얼마나 되었는가는 아직 결과가 나오지 않았다.

728x90