컴퓨터비전(Computer Vision)

데이터 부족 완화[1] - Data Augmentation

zzoming 2023. 10. 19. 20:55

들어가며

CNN과 같은 딥러닝 모델을 학습시키기 위해서는 굉장히 많은 양의 데이터가 필요하다. 하지만 실무에서 대용량의 레이블링된(labeled) 데이터 셋을 확보하는 것은 결코 쉬운일이 아니다. 이번 포스팅은 computer vision 분야에서 이러한 데이터 부족 문제를 어떻게 완화하고 있는지에 대한 표준 방법들에 대해 공부할 것이다. 


Learning Representations of Dataset

모델은 데이터를 기반으로 학습하기 때문에 데이터의 퀄리티에 따라 성능이 좌우된다. 가령 인터넷 상에 존재하는 수많은 이미지 데이터를 활용한다고 할 때, 사람이 촬영한 이미지는 대부분 사람이 보기 좋은 구도로 촬영되었기 때문에 bias가 존재한다고 볼 수 있다.  또한 이 세상의 모든 데이터를 확보하는 것은 불가능하기 때문에, 실제로 사용하게 되는 데이터는  real data distribution에서 샘플링된 일부라고 할 수 있다. 

 

🤔 그렇다면 데이터에 bias가 존재하는 것이 왜 문제일까 ? 

 

밝은 이미지로만 구성된 학습 데이터 셋을 가정할 때, test time에서 한번도 보지 못했던 어두운 고양이 사진이 입력될 경우 올바른 분류를 수행하기 어려울 것이다. 이는 데이터 셋이 충분히 real data distribution을 표현하지 못했기 때문에 발생하는 문제이다. 

물론 충분히 많은, 양질의 데이터를 확보하지면 되지만, 데이터 수를 늘리는 것은 비용과 시간이 필요하며, 어떤 경우에는 데이터를 수집하거나 가공하는 것 조차 어려운 경우도 많다.

 

1) 수집이 어려운 경우 

  • 자율주행 인공지능 개선을 위해 눈/비/황사/사고 등 특수 상황에 대한 데이터가 필요한 경우
  • 보안지역 감시 영상 데이터가 필요한 경우 
  • 신체 주요 부위 혹은 개인 사생활을 침해할 수 있는 데이터 수집이 필요한 경우 

2) 가공이 어려운 경우

  • 의료,법률 데이터와 같이 전문적인 지식이 없으면 가공이 어려운 경우
  • 평가자의 주관에 따라 판단 정도가 다를 수 있는 경우 (ex. 인물 표정)
  • 작업자가 가공 중 혐오감을 느낄 수 있는 경우 (ex, 음란물, 폭력적 장면)

Real data distribution과의 차이를 완화할 수 있는 방안 중 하나가 바로 Data Augmentation이다. 


Data Augmentaion이란?

학습 데이터의 이미지를 기반으로 이미지 크롭, 회전 ,밝기 조절 등과 같은 동작을 수행하여 학습 데이터의 사이즈를 증가시키는 방법이다. 이는 Open CV 등의 라이브러리에 사용하기 쉽게 구현되어 있다.

 

밝기 조절 

이미지 픽셀의 RGB 값에 특정한 상수를 더하거나 곱하여 이미지의 밝기를 조절할 수 있다.이때 RGB 값이 0~255 사이의 값을 가지고, 이점에 유의하여 값을 제한해야한다.

 

밝기 조절의 경우, 위와 같이 이미지 픽셀의 RGB 값에 특정한 상수를 더하거나 곱하여 이미지의 밝기를 조절할 수 있다. 이때 RGB값이 0~255 값을 가지므로 이 점에 유의하여 값을 제한(clipping)해야한다

def brightness_augmentation(img) :
    #numpy array img has RGB value (0~255) for each pixel
    img[:,:,0] = img[:,:,0] + 100 #add 100 for R value
    img[:,:,0] = img[:,:,1] + 50 #add 100 for G value
    img[:,:,0] = img[:,:,2] + 20 #add 100 for B value
    
    img[:,:,0][img[:,:,0]  > 255 ] = 255 #clip R values over 255
    img[:,:,0][img[:,:,1]  > 255 ] = 255 #clip G values over 255
    img[:,:,0][img[:,:,2]  > 255 ] = 255 #clip B values over 255
    return img

이미지에서 각 픽셀의 색상정보는 RGB(빨강, 녹색, 파랑) 채널을 사용하여 나타낸다.

이때 각 채널은 숫자로 표현되며, 일반적으로 0은 빨강(R), 1은 녹색(G), 2는 파랑(B)에 대응한다.

import cv2
import numpy as np
img = cv2.imread('santa.png')

brightness_augmentation(img)

cv2.imshow('img' , img)
cv2.waitKey(0)
cv2.destroyAllWindows() #모든 창 닫기

 


회전 및 반전 

import cv2
img = cv2.imread('santa.png') #해당경로 이미지 읽어오기

img_rotate = cv2.rotate(img , cv2.ROTATE_90_CLOCKWISE) #시계방향으로 90도 회전
img_flipped = cv2.rotate(img , cv2.ROTATE_180) #시계방향으로 180도 회전 
flip_horizontal = cv2.flip(img,1) #flipcode > 0  : 좌우대칭 Horizontal
flip_vertical = cv2.flip(img ,0) #flipcode == 0 : 상하대칭 vertical

cv2.imshow('img' , img) 
cv2.imshow('img_rotate' , img_rotate)
cv2.imshow('img_flipped' , img_flipped)
cv2.imshow('flip_horizontal' , flip_horizontal)
cv2.imshow('flip_vertical' , flip_vertical)

cv2.waitKey(0)
cv2.destroyAllWindows()

result = cv2.imwrite('img_save.png' , img) #이미지 저장 
rotate_90 = cv2.imwrite('img_rotate.png' , img_rotate)
rotate_180 = cv2.imwrite('img_flipped.png' , img_flipped)
result_horizontal = cv2.imwrite('flip_horizontal' , flip_horizontal)
result_vertical = cv2.imwrite('flip_vertical' , flip_vertical)

기본 , 180도 회전 , 90도 회전 
좌우대칭, 상하대칭 


이미지 크롭 

리스트 인덱싱을 통해 간단하게 구현 가능 

import cv2
img = cv2.imread('santa.png')
image.shape

crop = img[100:400 , 100:4000, :]

cv2.imshow('img' , img) 
cv2.imshow('crop' , crop) 
cv2.waitKey(0)
cv2.destroyAllWindows()


Affine Transform (어파인 변환)

Affine transform (어파인 변환)은 영상의 평행이동, 확대 및 축소, 회전 등의 조합으로 만들 수 있는 기하학적 변환을 나타낸다 

영상의 기하학적 변환이란 영상을 구성하는 픽셀의 배치 구조를 변경함으로써 전체 영상의 모양을 바꾸는 작업이다.

 

✓ 어파인 변환 행렬 - cv2.getAffineTransform 

cv2.getAffineTransform(src , dst)
  • src : 3개의 원본 좌표점. numpy.ndarray.shape(3,2) 
    • np.array([[x1,y1] , [x2,y2], [x3,y3]) , np.float32)
  • dst : 3개의 결과 좌표점 numpy.ndarray.shape(3,2) 

 

✓ 어파인 변환 함수 - cv2.warpAffine

cv2.WarpAffine(src , M , dsize , dst = None, flags = None , borderMode = None, borderValue = None)
  • src : 입력 영상 
  • M : 2x3 어파인 변환 행렬. 실수형.
  • dsize : 결과 영상 크기.(w,h) tuple
  • dst: 출력영상
  • flage:보간법. 기본값은 cv2.INTER_LINEAR
  • borderMode : 가장자자리 픽셀 확장방식. 기본값은 cv2.BORDER_CONSTANT
  • borderValue : cv2.BORDER_CONSTANT 일 떄 사용할 상수 값. 기본값은 0(검정색)

borderValue는 이동 변환했을 때 생기는 빈공간을 어떤 색깔로 채울 것인지를 의미. 기본값은 0(검정색) 

 

import cv2
import numpy as np
image = cv2.imread('santa.png')

rows, cols, ch = image.shape
pts1 = np.float32([[50,50],[200,50],[50,200]]) #입력 이미지에서 이동할 포인트 위치
pts2 = np.float32([[10,80],[200,70],[100,250]]) #해당 포인트가 출력될 위치
M = cv2.getAffineTransform(pts1,pts2) # 아핀 변환 행렬 생성 
shear_img = cv2.warpAffine(image , M , (cols , rows)) # 아핀 변환

cv2.imshow('image' , image)
cv2.imshow('shear_img' , shear_img)

cv2.waitKey(0)
cv2.destroyAllWindows() #모든 창 닫기


CutMix 

서로 다른 이미지의 일부들을 잘라서 이미지로 합성하는 기법. 구현 시, 데이터 레이블도 이미지 합성 비율에 맞춰 설정해줘야 함

https://github.com/clovaai/CutMix-PyTorch

 

GitHub - clovaai/CutMix-PyTorch: Official Pytorch implementation of CutMix regularizer

Official Pytorch implementation of CutMix regularizer - GitHub - clovaai/CutMix-PyTorch: Official Pytorch implementation of CutMix regularizer

github.com

 


앞서 봤듯이 굉장히 많은 image data augmentation 기법이 존재하기 때문에, 어떤 조합의 기법이 가장 좋은 성능을 보여줄지 일일이 탐색하는 것은 매우 오랜시간을 요하는 작업일 것이다. 이러한 상황에서 RandAugment 방법을 사용하여, 자동으로 어떤 조합 (Policy)이 가장 좋은 성능을 보여줄지 탐색할 수 있다. 이것은 사용가능한 data augmentation 옵션들을 입력해 주었을 때, 그 리스트에서 랜덤으로 샘플리하여 적용하고 성능을 평가하는 방식으로 작동된다.

Autoaugment

https://github.com/kakaobrain/fast-autoaugment

 

GitHub - kakaobrain/fast-autoaugment: Official Implementation of 'Fast AutoAugment' in PyTorch.

Official Implementation of 'Fast AutoAugment' in PyTorch. - GitHub - kakaobrain/fast-autoaugment: Official Implementation of 'Fast AutoAugment' in PyTorch.

github.com


 

참고자

https://url.kr/7jgoab

 

[OpenCV] 어파인 변환

어파인 변환의 개념 어파인 변환(affine transformation)이란 영상의 평행 이동, 확대 및 축소, 회전 등의 ...

blog.naver.com

https://076923.github.io/posts/C-opencv4-21/

 

C# OpenCV 강좌 : 제 21강 - 아핀 변환

아핀 변환(Affine Transformation)

076923.github.io

https://medium.com/swlh/image-processing-using-opencv-738e61b82b9f

 

Image processing using OpenCV

Image processing is a promising field with many applications, whether it’s an image of the universe itself from a telescope or a small…

medium.com