우리가 학습에 사용하는 데이터는 모두 사람이 보기 좋게 찍은 사진들이지만, 실제 데이터들은 어떻게 들어올지 모르는 데이터들이다.
우리의 데이터셋이 real data를 충분하게 표현하지 못한다면 여러 문제가 발생한다.
eg ) 밝은 영상으로만 이루어진 데이터로 모델을 학습시켰을때 이 모델이 어두운 배경의 고양이가 들어왔을 때 제대로 인식하지 못한다.
이러한 경우 Data Augmentation을 활용하여 이 세상에 찍힐 수 있는 여러 데이터를 표현할 수 있게 가능성을 높일 수 있다.
Brightness adjustment
이미지 밝기를 높이기 위해서는 단순히 숫자를 더하는 것으로 할 수 있다.
여기서 주의해야 할 점은 이미지가 0 ~ 255 를 넘지 않게 조절해 줘야 한다.
def brightness_augmentation(img):
img[:,:,0] = img[:,:,0] + 100
img[:,:,1] = img[:,:,1] + 100
img[:,:,2] = img[:,:,2] + 100
img[:,:,0][img[:,:,0]>255] = 255
img[:,:,1][img[:,:,1]>255] = 255
img[:,:,2][img[:,:,2]>255] = 255
Rotate, flip using OpenCV
opencv를 통해 상하좌우 변환은 쉽게 구현할 수 있다.
img_rotated = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
img_flipped = cv2.rotate(image, cv2.ROTATE_180)
Crop
다음과 같이 인덱싱을 통해 구현할 수 있다
y_start = 500
crop_y_size = 400
x_start = 300
crop_x_size = 800
img_cropped = image[y_start : y_start + crop_y_size, x_start : x_start + crop_x_size, :]
변환 전과 후에도 선은 선대로 유지가 되고, 길이의 비율과 평행관계가 유지되는 변환을 말한다.
변환된 사진의 3개의 점을 변환 후에도 형태를 그대로 유지할 수 있게 대응하는 쌍을 지정하여 변환할 수 있다.
rows, cols, ch = image.shape
pts1 = np.float32([[50,50],[200,50],[50,200]]) # 변환 전
pts2 = np.float32([[10,100],[200,50],[100,250]]) # 변환 후
M = cv2.getAffineTransform(pts1,pts2)
shear_img = cv2.wrapAffine(image, M, (cols,rows))
다른 두 영상을 합치는 방법인데, 이 때 라벨도 같은 비율에 따라 합성해 주는 것이 중요하다.
이 방법을 사용하면 의미있는 수준의 성능향상과 물체의 위치를 정교하게 캐치할 수 있게 할 수 있다.
데이터를 적게 쓰고도 좋은 성능을 내기 위해서 다른 데이터 셋에서 학습된 정보를 활용하는 방법
Transfer learning
standard Knowledge distillation
이 과정은 결국 student 모델이 teacher 모델의 행동을 따라하게 만드는 학습법이라고 이해할 수 있다.
또한, label을 전혀 사용하지 않았으므로 unsupervised learning에 해당하며, 임의의 데이터를 사용할 수 있다.
레이블이 존재할 때의 Knowledge distillation
Soft Prediction
Distillation Loss
Student Loss
결국에는 Distillation Loss와 Student Loss의 weighted sum을 통해 Soft prediction 부분으로만 역전파가 이루어져 학습이 진행된다.