반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

블로그

[CV] 시각지능 딥러닝 #2 Image Data Augmentation 이미지 데이터 증강 본문

공부/DL

[CV] 시각지능 딥러닝 #2 Image Data Augmentation 이미지 데이터 증강

beenu 2024. 4. 2. 16:51
반응형
Review
  • DNN : 이미지 데이터의 형태 훼손(= 공간/위치 정보를 감안하지 않음)
  • CNN : 공간/위치 정보를 살려보자 !
    • Conv Layer filter
    • Feature map
    • Pooling Layer (max) : 연산량을 줄이기 위함 (하드웨어 제약)
    • feature map 크기에 영향을 미치는 요소들
      • filter 개수
      • filter의 크기
      • filter의 이동 보폭 (strides)
      • pooling : feature map의 가로 세로 사이즈에 영향 (depth와는 상관없음)
  • Keras 3.x 사용
  • Sequential API
  • Funtional API
  •  DNN
    • Dense
    • Input
    • Flatten
    • Batch Normalization
    • Dropout
  •   CNN
    • Conv2D
      • filter : 새롭게 제작하려는 feature map의 수
      • kernel_size : Conv filter의 가로세로 사이즈 (이전 feature map의 depth는 keras에서 자동 보정)
      • strides : Conv filter의 이동 보폭
      • padding : 이전 feature map크기 유지, 외곽 정보 반영
      • activation
    • Maxpool2D
      • pool_size : maxpool filter의 가로세로 사이즈
      • strides : maxpool filter의 이동 보폭
      • 오로지 가로세로 사이즈를 줄이는게 목적이므로 activation 사용하지 않음
    • 문제의 큰 틀만 알고 있어도 일단 모델링까지는 할 수 있어야 하기 때문에 shape를 계속 확인해야 함
    • One Hot Encoding
      • One vs all / One vs rest를 위해 y(클래스)를 인코딩해줌
  • CIFAR10 데이터를 활용한 모델링
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
import keras

(train_x, train_y), (test_x, test_y) = keras.datasets.cifar10.load_data()
print(train_x.shape, train_y.shape, test_x.shape, test_y.shape)

labels = {0 : 'Airplane',
          1 : 'Automobile',
          2 : 'Bird',
          3 : 'Cat',
          4 : 'Deer',
          5 : 'Dog',
          6 : 'Frog',
          7 : 'Horse',
          8 : 'Ship',
          9 : 'Truck' }

print(labels)
# X : 표준화 Scaling (standardization)

# 1. 한꺼번에 Standardization 적용
mean_n, std_n = train_x.mean(), train_x.std()

train_x_1 = (train_x - mean_n) / std_n
test_x_1 = (test_x - mean_n) / std_n


# 2. 채널별로 Standardization 적용
tr_r_mean, tr_r_std = train_x[:, :, :, 0].mean(), train_x[:, :, :, 0].std()
tr_g_mean, tr_g_std = train_x[:, :, :, 1].mean(), train_x[:, :, :, 1].std()
tr_b_mean, tr_b_std = train_x[:, :, :, 2].mean(), train_x[:, :, :, 2].std()

train_x_r = (train_x[:,:,:,0] - tr_r_mean) / tr_r_std
train_x_g = (train_x[:,:,:,1] - tr_g_mean) / tr_r_std
train_x_b = (train_x[:,:,:,2] - tr_b_mean) / tr_r_std

test_x_r = (test_x[:,:,:,0] - tr_r_mean) / tr_r_std
test_x_g = (test_x[:,:,:,1] - tr_g_mean) / tr_r_std
test_x_b = (test_x[:,:,:,2] - tr_b_mean) / tr_r_std

train_x_2 = np.stack((train_x_r, train_x_g, train_x_b), axis=3)
test_x_2 = np.stack((test_x_r, test_x_g, test_x_b), axis=3)
from keras.utils import to_categorical

class_n = len(np.unique(train_y))
train_y = to_categorical(train_y, class_n)
test_y = to_categorical(test_y, class_n)
from keras.utils import clear_session
from keras.models import Sequential, Model
from keras.layers import Input, Conv2D, MaxPool2D, BatchNormalization, Dropout, Dense, Flatten
from keras.callbacks import EarlyStopping
## 1. session clear
clear_session()

## 2. 모델 생성
model = Sequential()

## 3. 레이어 블록 조합
model.add(Input(shape=(32, 32, 3))
model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu'))
model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2))
# Dropout 25% 비활성화
model.add(Dropout(0.25))

model.add(Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu'))
model.add(Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2))
# Dropout 25% 비활성화
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(1024, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.35))

model.add(Dense(10, activation='softmax'))

## 4. 컴파일
model.compile(optimizer='adam', loss=keras.losses.categorical_crossentropy, metrics=['accuracy'])

Image Data Augmentation
  • 데이터 양이 부족할 경우 증강이 필요함
import keras

aug_layers = [keras.layers.RandomRotation(factor=(-0.3,0.3)),
              keras.layers.RandomTranslation(height_factor=(-0.3,0.3), width_factor=(-0.3,0.3)),
              keras.layers.RandomZoom(height_factor=(-0.2,0.2), width_factor=(-0.2,0.2)),
              keras.layers.RandomFlip(mode='horizontal_and_vertical')
              ]
              
def image_augmentation(images):
    for layer in aug_layers:
        images = layer(images)
    return images
    
aug_imgs = image_augmentation(image)
## Functional API
# 1. 세션 클리어
clear_session()

# 2. 레이어 엮기
il = Input(shape=(28,28,1))

## 최신 버전에서는 hidden layer에서 augmentation 하도록 권장함
###############################################################################################
## augmentation layer
al = keras.layers.RandomRotation(factor=(-0.1,0.1))(il)
al = keras.layers.RandomTranslation(height_factor=(-0.1,0.1), width_factor=(-0.1,0.1))(al)
al = keras.layers.RandomZoom(height_factor=(-0.1,0.1), width_factor=(-0.1,0.1))(al)
# al = keras.layers.RandomFlip(mode='horizontal_and_vertical')(al)
###############################################################################################

hl = Conv2D(filters=64,        # 새롭게 제작하려는 feature map의 수! 서로 다른 filter의 수!
            kernel_size=(3,3), # Conv 필터의 가로세로
            strides=(1,1),     # Conv 필터의 이동 보폭
            padding='same',    # 1. 사이즈 유지 | 2. 외곽 정보 더 반영
            activation='relu'  # 주의!
            )(al)

# 이후 생략

 

  • Augmentation 실습 중 train보다 test set에서 성능이 더 좋은 현상이 발생했다
    • 학습 데이터에만 augmentation을 적용함 (이상하게 생긴 글자들이 많음) => 증강기법이 학습을 방해함
    • 증강이 학습에 도움이 되는지 잘 판단해서 사용해야 함

 

728x90
반응형