Annotation data efficient learning¶
✅ Data augmentation¶
1️⃣ Learning representation of dataset¶
우리가 얻어지는 Dataset은 거의 대부분 편향된 데이터이다.
왜냐하면 우리가 얻는 이미지는 카메라로 찍은 이미지가 될 것이고 이것은 사람들이 이쁘게 찍기위한 구도로 거의 비슷한 각도로 많이 존재하기 때문이다. 따라서 traing data와 real data와는 차이가 존재한다.
📌 훈련 데이터 세트는 실제 데이터의 일부만 포함한다.¶
우리는 이러한 차이를 메워서 모델의 정확도를 높일수 있다.
2️⃣ Data augmentation¶
- 데이터 셋에 다야한 이미지 변환을 적용한다.
- Crop, Shear, Brightness, Perspctive, Rotate ...
- OpenCV 및 NumPy에 data augmentation의 다양한 방법들이 존재한다.
- 목표는 실제 데이터의 분포와 유사한 학습용 데이터를 만드는 것이다.
3️⃣ Various data augmentation methods¶
코드 한줄로 이미지 데이터 augmentation 얻기
📌 Brightness adjustment¶
- 데이터 셋의 밝기를 조정한다.
In [1]:
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
image_pil = Image.open('./data/Angkko.png')
In [2]:
image_pil
Out[2]:
🔎 이미지 numpy array로 받는 방법¶
In [3]:
# 방법 1
arr = np.array(image_pil)
arr.shape, arr.dtype
Out[3]:
- 여기서
arr
의 값은 0 ~ 255값의 RGB값이 가진다.
In [4]:
plt.title('Origin')
plt.xticks([]) # x축 눈금 안보이게
plt.yticks([]) # y축 눈금 안보이게
plt.imshow(arr)
Out[4]:
In [5]:
def brightness_augmentation(img_origin,val):
# 원본 보존
img = img_origin.copy()
# numpy array img has RGB value(0~255) for each pixel
img[:,:,0] += val # R 값에 val 추가
img[:,:,1] += val # R 값에 val 추가
img[:,:,2] += val # R 값에 val 추가
# 255가 넘는 값에 대한 처리
img[:,:,0][img[:,:,0]>255] = 255
img[:,:,1][img[:,:,1]>255] = 255
img[:,:,2][img[:,:,2]>255] = 255
return img
In [6]:
new_arr=brightness_augmentation(arr,50)
plt.title('Origin')
plt.xticks([]) # x축 눈금 안보이게
plt.yticks([]) # y축 눈금 안보이게
plt.imshow(new_arr)
Out[6]:
- 위 코드대로 돌리게 되면 명암이 조정 되지 않는다.
In [7]:
def brightness_augmentation2(img_origin,val):
# 원본 보존
img = img_origin.copy()
# numpy array img has RGB value(0~255) for each pixel
img[:,:,3] += val # R 값에 val 추가
# 255가 넘는 값에 대한 처리
img[:,:,3][img[:,:,0]>255] = 255
return img
In [8]:
new_arr=brightness_augmentation2(arr,50)
plt.title('Origin')
plt.xticks([]) # x축 눈금 안보이게
plt.yticks([]) # y축 눈금 안보이게
plt.imshow(new_arr)
Out[8]:
- 위 코드는 투명도를 조절하여 augmentation을 진행하였다.
RGB to HSV 공식
In [9]:
import numpy as np
import cv2
import matplotlib.pyplot as plt
In [10]:
def brightness_augment(img_origin, factor=0.5):
img=img_origin.copy()
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) #convert to hsv
hsv = np.array(hsv, dtype=np.float64)
hsv[:, :, 2] = hsv[:, :, 2] * (factor) #scale channel V uniformly
hsv[:, :, 2][hsv[:, :, 2] > 255] = 255 #reset out of range values
rgb = cv2.cvtColor(np.array(hsv, dtype=np.uint8), cv2.COLOR_HSV2RGB)
return rgb
In [11]:
img=cv2.imread('./data/Angkko.png',-1)
# 이 부분은 밑에서 설명
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
In [12]:
new_img=brightness_augment(img,0.5)
In [13]:
plt.figure(figsize=(8,8))
plt.subplot(121)
plt.xticks([]) # x축 눈금 안보이게
plt.yticks([]) # y축 눈금 안보이게
plt.title('Origin')
plt.imshow(img)
plt.subplot(122)
plt.xticks([]) # x축 눈금 안보이게
plt.yticks([]) # y축 눈금 안보이게
plt.title('Brightness')
plt.imshow(new_img)
Out[13]:
📌 Rotate, Flip¶
- 데이터 셋의 각도 조절한다.
In [14]:
import numpy as np
import cv2
import matplotlib.pyplot as plt
In [15]:
img=cv2.imread('./data/Angkko.png',-1)
In [16]:
img.shape
Out[16]:
In [17]:
# 사진 띄우기
# matplotlib에서 rgb 채널 순서가 다르다
# RGB -> red / green /blue
# opencv -> blue / red /green
plt.imshow(img)
Out[17]:
In [18]:
fix_img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(fix_img)
Out[18]:
In [19]:
img_rotated=cv2.rotate(fix_img,cv2.ROTATE_90_CLOCKWISE)
img_flipped=cv2.rotate(fix_img,cv2.ROTATE_180)
In [20]:
plt.figure(figsize=(8,8))
plt.subplot(121)
plt.title('Rotated')
plt.imshow(img_rotated)
plt.subplot(122)
plt.title('Flipped')
plt.imshow(img_flipped)
Out[20]:
📌 Crop¶
- 데이터 셋의 학습하고 싶은 부분만 자르기
In [21]:
import numpy as np
import cv2
import matplotlib.pyplot as plt
In [22]:
img=cv2.imread('./data/Angkko.png',-1)
# plt으로 그리기 위해서
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
In [23]:
y_start=60
crop_y_size=80
x_start=50
crop_x_size=80
img_cropped=img[y_start:y_start+crop_y_size,x_start:x_start+crop_x_size,:]
In [24]:
plt.figure(figsize=(8,8))
plt.subplot(121)
plt.xticks([])
plt.yticks([])
plt.title('Origin')
plt.imshow(img)
plt.subplot(122)
plt.title('Cropped')
plt.imshow(img_cropped)
Out[24]:
📌 Affine transformation¶
In [25]:
import numpy as np
import cv2
import matplotlib.pyplot as plt
In [26]:
img=cv2.imread('./data/Angkko.png',-1)
# plt으로 그리기 위해서
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
rows,cols,ch=img.shape
# 각각의 대응쌍을 지정해 준다.
pts1=np.float32([[50,200],[50,50],[150,200]])
pts2=np.float32([[100,180],[50,50],[170,180]])
# 변환 행렬을 생성
M=cv2.getAffineTransform(pts1,pts2)
shear_img=cv2.warpAffine(img,M,(cols,rows))
In [27]:
plt.figure(figsize=(8,8))
plt.subplot(121)
plt.title('Origin')
plt.imshow(img)
plt.subplot(122)
plt.title('AffineTransform')
plt.imshow(shear_img)
Out[27]:
📌 CutMix¶
- 자르고 합치기를 통해서 새로운 데이터 셋을 만든다.
- 이때, 결과의 label도 합쳐진 비율만큼 주게 된다.
- 이렇게 하면 물체의 위치를 더 정교하게 캐치하게 된다.
✅ Leveraging pre-trained information¶
1️⃣ Transfer learning¶
- Transfer learning의 이점은 사전 훈련 된 지식 (기능)을 활용하여 새로운 작업에 쉽게 적응하게 할 수 있다.
- 비슷한 데이터 셋은 비슷한 공통의 정보를 가지고 있다라는 생각
- 하나의 데이터 셋에서 배운 지식을 다른 데이터 셋에 적용 할 수 있다.
📌 접근 1: 사전 훈련 된 작업에서 새 작업으로 지식 이전¶
- 기존의 10개의 class로 분류하는 pre-trained model이 있다.
- 사전 훈련 된 모델의 최종 계층을 잘라 내고 새 FC layer을 추가하고 다시 학습을 진행
- 추출 된 기능은 사전의 모든 지식을 보존
📌 접근 2: 전체 모델에 Fine-tuning을 한다.¶
- pre-trained model을 준비한다.
- 사전 훈련 된 모델의 최종 레이어를 새 레이어로 교체하고 전체 모델을 다시 학습한다.
- 학습률을 다르게 설정하게 되는데 Convolution Layer는 낮은 learning rate을 주고 새 FC layer는 높은 learning rate를 준다.
- 조금 더 많은 데이터가 들어가고 성능도 더 좋다.
2️⃣ Knowledge distillation¶
- 훈련 된 모델의 지식을 다른 작은 모델로 'Distillate' 한다.
- 모델 압축에 사용(더 큰 모델이 알고있는 것을 모방)
- pseudo-labeling에 사용된다. (라벨이없는 데이터 세트에 대한 유사 라벨 생성).
📌 Teacher-student Network 구조¶
- Student network는 Teacher network가 알고 있는 내용을 배우게 된다.
- 이때 Student model는 일반적으로 더 작은 network를 쓴다.
- Student model과 Teacher model의 Output을 KL div. Loss를 통해 측정하고 backporb을 통해 Student model만 학습하게 된다.
- Student model는 Teacher model의 출력을 모방하게 된다.
- 레이블이 없는 데이터로만 수행 할 수 있으므로 비지도 학습
📌 Knowledge distillation¶
- 레이블이 지정된 데이터(Ground Truth Y)를 사용할 수 있는 경우 학습을 위해 레이블이 지정된 데이터를 활용할 수 있다. (Student Loss)
- Teacher model과 유사한 결과를 예측 하기위한 Distillation Loss
- distillation에서 Semantic information은 고려하지 않는다.
- 여기서 예측은 Soft Prediction을 사용한다.
🔎 Hard label vs Soft label¶
Hard label(One-hot vector)
- 일반적으로 데이터 셋에서 가져온다.
- class가 정답인지 여부를 나타낸다.
Soft label
- 모델의 일반적인 출력 (= 추론 결과)
- "지식"으로 간주한다. 모델이 어떻게 생각하는지 관찰하는데 유용하다.
📌 Softmax with temperature(T)¶
- temperature가 있는 Softmax : 작은 입력과 큰 입력 값 사이의 출력 차이 제어
- 큰 𝑇값은 큰 입력 값 차이를 부드럽게한다.
- Student & Teacher model의 출력을 동기화하는 데 유용하다.
Distillation Loss
- kLdiv(Soft label, Soft prediction)
- Loss는 Teacher와 Student Network의 추론의 차이를 의미
- 모방하여 Teacher의 Network가 아는 것을 배움
Student Loss
- CrossEntropy(Hard label, Soft prediction)
- Loss는 Student network와 실제 레이블의 차이
- "정답" 배우기
Distillation loss
와 Student loss
의 가중합을 사용한다.
✅ Leveraging unlabeled dataset for training¶
1️⃣ Semi-supervised learning¶
- label이 있는 데이터를 통해 Model을 학습한다.
- 그 다음 이 Model을 가지고 Unlabeled dataset에 대해서 Pseudo-labeled dataset을 만든다.
- 새롭게 지정된 Pseudo-labeled dataset을 추가하여 그 전의 Model을 다시 학습 시킨다.
2️⃣ Self-training¶
- 먼저 수집한 데이터 셋을 가지고 Teacher Model을 학습 시킨다.
- Teacher Model을 통해서 unlabeled data에 Pseudo-labeled data로 만든다.
- 이제 기본 데이터와 Pseudo-labeled data를 합쳐서 Student Model을 학습시킨다. 이때 학습할 때 , RandAugment를 이용하여 더 방대한 데이터를 학습한다.
- Studen Model의 학습이 끝나면 이전 Teacher Model를 날리고 최근에 학습한 Student Model를 다시 Teacher Model로 사용한다.
- 이렇게 새로 만들어진 Teacher Model로 다시 unlabeld data를 pseudo-labeled data로 만들고 반복한다.
- 위 그림은 위에서 설명한 내용을 그림으로 보여준다.
- 여기서 Model은 점점 더 커지게 된다.
'AI > 이론' 카테고리의 다른 글
torch.autograd (0) | 2021.03.10 |
---|---|
Object Detection (0) | 2021.03.10 |
Semantic segmentation (0) | 2021.03.09 |
Image classification II (0) | 2021.03.09 |
Image classification I (0) | 2021.03.08 |
그래프 신경망이란 무엇일까? (심화) (0) | 2021.02.26 |
그래프 신경망이란 무엇일까? (기본) (1) | 2021.02.26 |
그래프를 추천시스템에 어떠게 활용할까? (심화) (0) | 2021.02.25 |