전처리 Preprocessing
Resize
보간법 사용
- 줄일 때: 하나의 값으로 할당
- 늘릴 때: 근사 값으로 채움
사이즈가 정사각형이 아닌 경우
- 정사각으로 만들고 여백을 검정색 패딩으로 채움
Zero-centering
평균이 0인 데이터로 변경
- 픽셀의 숫자 형태는 0~255
- 양수보다는 양수와 음수와 공존하는 것이 좋다.
- Zero-centering: 양수와 음수가 공존하도록 변경
- 숫자의 평균을 구하고 평균이 0일 때의 값을 구하자.
- 평균으로부터의 편차를 구하자.
- X -= np.mean(X, axis=0)
- 예시) X.shape = (2, 3, 224, 224)
- (batch, channel, width, height)
- 결과) X.shape = (1, 3, 224, 224)
색상
Grayscaling 변환
- 3채널 -> 1채널로
- RGB를 3:6:1로 하여 합친다.
- 데이터 양을 줄인다. (텐서의 숫자 줄어듬)
- 변환시 데이터 복잡도가 올라간다.
- overfit일 때, Grayscaling으로 바꾸면 효과가 있다.
이진화 작업
- 0과 1로만 표현
- 데이터 양을 줄인다. (텐서의 크기 동일)
노이싱
디노이징
- 노이즈 제거
- underfit의 경우, 문제를 쉽게 한다.
- 블러: 이미지를 부드럽게 또는 흐릿하게
- 필터링: 데이터를 걸러냄
- 모폴로지: 픽셀값 대체
- 팽창: 최대픽셀 대체 밝게, 끊어진 부분을 연결
- 침식: 최소픽셀 대체 어둡게, 흰점 노이즈 제거
- 혼합:
- 열림(오프닝): 침식 > 팽창
- 닫힘(클로징): 팽창 > 침식
애드노이
- 노이즈 추가
- overfit의 경우, 문제를 어렵게 한다.
- 학습데이터가 너무 쉬운 경우, 애드노이싱을 사용한다.
증강 Augmentation
- 데이터 수집에 한계가 놓인 상태에서, 기존 데이터셋을 변형하여 재생산한다.
- 직접 수집 데이터만큼은 아니지만 미세한 효과를 준다.
증강과 학습난이도
- 증강 데이터는 변형 과정에서 난도를 높인다.
증강의 기획적 판단
- 테스트데이터의 선을 넘지 않는다.
- 테스트 데이터에 존재하지 않는 것을 만들지 않는다.
- 학습데이터보다 쉽지 않게 한다.
- 증강의 범위: 학습 ~ 테스트 데이터
Albumentations
- 이미지 증강 파이썬 라이브러리
- 지원기법
- 픽셀 수준: 흐리게 밝기, 대비, 노이즈, RGB 변경
- 공간 수준: 이미지 회전, 반전, 대칭
- 크기 변환: 사이즈조정, 잘라내기
- 혼합 : 비, 그림자, 눈, 안개
레이블 혼합
두 이미지의 투명도를 조정해서 혼합
두 이미지의 특정 영역을 혼합
이미지 처리시, 메모리 부족
- 메모리 요구사항이 낮은 모델 사용
- 배치 크기 줄이기
- 이미지 크기 줄이기
- 증강 데이터를 미리 만들지 않는다. (훈련 중에 조금씩 만들면서, 훈련 과정에서 증강데이터 훈련을 추가한다.)
- 더이상 필요하지 않는 변수는 del로 지운다.
- 메모리 프로파일링 도구 사용
Python 실습
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt
!pip install gdown==v4.6.3
# 구글 드라이브에 올린 이미지 링크에서 뒷 부분만 발췌
# https://drive.google.com/file/d/1EVDm6wR2E2ukbW3u17VKaGWk5XkDedX6/view?usp=drive_link
!gdown 1EVDm6wR2E2ukbW3u17VKaGWk5XkDedX6
!unzip imgset_mini.zip
Resize
target_size = 500
# img_path 순회하면서 코드 반복
# 불러오기 -> resize -> 저장하기
for filename in ['airplane', 'car', 'dog']:
img_path = '/content/'+filename+'.jpg'
img = cv2.imread(img_path)
# RGB로 변경
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 이미지의 width와 height 중 긴 쪽을 img_size에 맞추기
# 둘 중 큰 값을 target_size와 ratio 계산
if(img.shape[1] > img.shape[0]) : # 세로 > 가로
ratio = target_size/img.shape[1] # 비율 = target_size/세로
else :
ratio = target_size/img.shape[0] # 비율 = target_size/가로
# cv2.resize함수를 활용하면 ratio를 입력하여 원하는 사이즈로 resize 가능
# fx와 fy의 비율을 유지한다. INTER_LINEAR을 선형보간법
img = cv2.resize(img, dsize=(0, 0), fx=ratio, fy=ratio, interpolation=cv2.INTER_LINEAR)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 가로, 세로
w, h = img.shape[1], img.shape[0]
# 패딩 길이 계산 = (긴 변 길이 - 짧은 변 길이) / 2
# * 어차피 긴변은 target size 와 동일하기 때문에
# * 둘 다 target_size와의 차이를 계산한다.
dw = (target_size - w)/2 # target_size와 w(=가로)의 차이
dh = (target_size - h)/2 # target_size와 h(=세로)의 차이
M = np.float32([[1,0,dw], [0,1,dh]]) #(2*3 이차원 행렬)
img_re = cv2.warpAffine(img, M, (target_size, target_size)) #이동변환: 좌측상단정렬을 (좌측)중앙정렬로
cv2.imwrite(f'/content/resized/{filename}_img.jpg' , img_re)
Resize + Agumentation(증강)
def augmentation(target_size):
answer1 = input('grayscaling은 1, 이진화는 2: ')
answer2 = input('zero-centering은 1, 안하려면 0을 입력하세요.: ')
list_img =[]
# 불러오기 -> resize -> 저장하기
for filename in ['airplane', 'car', 'dog']:
img_path = '/content/'+filename+'.jpg'
img = cv2.imread(img_path)
# 이미지의 width와 height 중 긴 쪽을 img_size에 맞추기
if(img.shape[1] > img.shape[0]) : # 세로 > 가로
ratio = target_size/img.shape[1] # 비율 = target_size/세로
else :
ratio = target_size/img.shape[0] # 비율 = target_size/가로
# cv2.resize함수를 활용하면 ratio를 입력하여 원하는 사이즈로 resize 가능
img = cv2.resize(img, dsize=(0, 0), fx=ratio, fy=ratio, interpolation=cv2.INTER_LINEAR)
# 패딩 길이 계산 = (긴 변 길이 - 짧은 변 길이) / 2
w, h = img.shape[1], img.shape[0]
dw = (target_size - w)/2 # target_size와 w(=가로)의 차이
dh = (target_size - h)/2 # target_size와 h(=세로)의 차이
#이동
M = np.float32([[1,0,dw], [0,1,dh]]) #(2*3 이차원 행렬)
img_re = cv2.warpAffine(img, M, (target_size, target_size)) #이동변환: 좌측상단정렬을 (좌측)중앙정렬로
#BGR을 그레이스케일로 변경
img_aug = cv2.cvtColor(img_re, cv2.COLOR_BGR2GRAY)
# 이진화 (이녀석만 주석처리 하면됨.)
if answer1 == '2':
thresh = 127.5
binarization = lambda img : cv2.threshold(img, thresh, target_size, cv2.THRESH_BINARY)
img_aug = [binarization(img)[1] for img in img_aug]
#zero-centering
mean_img = np.mean(img_aug, axis=0)
zero_centered_images = img_aug - mean_img
#리스트 저장
if answer2 == '1':
list_img.append(zero_centered_images)
else:
list_img.append(img_aug)
#출력
plt.figure(figsize=(15,5))
for idx, img in enumerate(list_img):
plt.subplot(1,3,idx+1)
# plt.imshow(img) # 색상 맵(color map)을 자동으로 적용하기 때문에 제대로 출력x
plt.imshow(img, cmap='gray')
Tags:
AI개발_교육
