티스토리 뷰

20201103

 

Image Data Generation

  • 개/ 고양이 예제 전체 data를 대상으로 CNN 학습 및 평가를 진행하면 정확도가 85% 정도 나온다.
    • 전체 25,000장 이미지
  • 만약 데이터가 적다면 당연히학습이 잘 안될 것. 정확도 75%
    • Dog - 2000장, Cat 2000장
    • 해결하려면
      • Augumentation (증식)
      • Transfer Learning (전이학습)

Image Augmentation (증식)

  • overfitting을 피하려는 주요한 방법 중 하나.
  • 이미지에 noise를 추가해서 새로운 이미지를 생성한다.
    • Rotation -> 20~30 ˚
    • Scaling -> 10~20%
  • ImageDatatGeneration을 이용해서 noise를 줄 수 있는지 확인한다.
    • 그림이 변형된다.
  • CNN 학습을 Augmentation 포함해서 다시 실행, 그래프를 확인하면 Overfitting이 많이 줄었다. 85%
  • 더 줄이려면 Transfer Learning (전이학습)
    • Pretrained Network 이용

 

Transfer Learning (전이학습) 

  • Pretrained Network를 사용하는 방법
    • MNIST 99% 
      • 3개의 Convolution Layer / Pooling Layer
      • 1개의 FC Layer
      • CPU 1~2시간 정도 소요
    • 실무에서는 고해상도 컬러 이미지를 사용하여 학습한다. CPU X GPU에서 학습하면 오래 걸린다.
    • 다른 방법 고안
  • Pretrained Network
    • 이미 학습되어 있는 CNN model을 다양한 parameter를 이용하고 수정한다.
    • 처음부터 학습을 진행하지 않고 빠르게 결과를 얻을 수 있다.
    • Pretrained Network에 나의 데이터를 전달 (Transfer)한다.
    • Pretrained Network 종류들
      • Google - (30층) -> Inception
      • MS
        • 152층 (x5)층으로 구성된 Resnet
        • 16 / 19층 VGG
      • CNN Model의 Convolution Layer에서 Feature 추출 후 재활용 한다.
        • 사전 훈련된 네트워크는 2가지 방법으로 이용한다.
          • Feature Extraction - 특성 추출
            • 사전에 학습된 네트워크의 표현을 사용하여, 새로운 샘플에서 흥미로운 특성을 뽑아낸다.
            • 새로운 분류기를 처음부터 훈련한다.
          • Fine Tuning - 미세 조정
            • 특성 추출에 사용했던 동결 모델의 상위 층 몇 개를 동결에서 해제하고, 모델에 새로 추가한 층과 함께 훈련하는 것
            • 주어진 문제에 조금 더 밀접하게 재사용 모델의 일부를 조정하기 때문에 미세 조정이라고 부른다.

 

1103_cat_dog_augmentation_example

# 1103_cat_dog_augmentation_example
%reset
%matplotlib inline

# data augmentation

from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing import image
import matplotlib.pyplot as plt

datagen = ImageDataGenerator(rotation_range=20,
                             width_shift_range=0.1,
                             height_shift_range=0.1,
                             zoom_range=0.1,
                             horizontal_flip=True,
                             vertical_flip=True)

img = image.load_img('./data/cat_dog_small/train/cats/cat.3.jpg',
                    target_size=(150,150))
plt.imshow(img)
plt.show()

x = image.img_to_array(img)
print(x.shape)  # (150,150,3)
x = x.reshape((1,) + x.shape)
print(x.shape)

fig = plt.figure(figsize=(10,10))
axs = []

for i in range(20):
    axs.append(fig.add_subplot(4,5,i+1))
    
idx = 0
for batch in datagen.flow(x,
                          batch_size=1):
    axs[idx].imshow(image.array_to_img(batch[0]))
    idx += 1
    if idx % 20 == 0:
        break;

fig.tight_layout()
plt.show()

 

1103_cat_dog_small_cnn

# 1103_cat_dog_small_cnn
%reset

import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.optimizers import Adam

train_dir = './data/cat_dog_small/train'
validation_dir = './data/cat_dog_small/validation'

# ImageDataGenerator
# 이미지 데이터의 값을 1/225로 scaling
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)

# train : 2000개
# validation : 1000개

# train data를 가져오면 => x_data(독립변수,픽셀데이터), t_data(종속변수,label)
train_generator = train_datagen.flow_from_directory(
    train_dir,                # taget directory : 데이터를 어디에서 가져올건가요!
    classes=['cats', 'dogs'], # label적용을 어떻게 할건가요? 순서대로 레이블이 적용
                              # cats : 0, dogs : 1  (cats와 dogs는 폴더명!!)
                              # 만약 classes를 명시하지 않으면 폴더명 순서로 label이 잡혀요!   
    target_size=(150,150),    # 이미지 size scaling(크기를 150x150으로 변경해서 들고와!!)
    batch_size=20,            # 한번에 20개의 이미지를 가져와!!  
                              # label에 상관없이 가져와요!!
    class_mode='binary'       # 이진분류이기 때문에 'binary'
                              # 만약 MNIST처럼 다중분류면 'categorical'
                              # 기본값은 'categorical'
    )

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,           # taget directory : 데이터를 어디에서 가져올건가요!
    classes=['cats', 'dogs'], # label적용을 어떻게 할건가요? 순서대로 레이블이 적용
                              # cats : 0, dogs : 1  (cats와 dogs는 폴더명!!)
                              # 만약 classes를 명시하지 않으면 폴더명 순서로 label이 잡혀요!   
    target_size=(150,150),    # 이미지 size scaling(크기를 150x150으로 변경해서 들고와!!)
    batch_size=20,            # 한번에 20개의 이미지를 가져와!!  
                              # label에 상관없이 가져와요!!
    class_mode='binary'       # 이진분류이기 때문에 'binary'
                              # 만약 MNIST처럼 다중분류면 'categorical'
                              # 기본값은 'categorical'
    )

# 데이터 준비가 끝났어요!!
# 이제 모델을 만들어 보아요!!

with tf.device('/device:GPU:1'):
    
    model = Sequential()
    
    model.add(Conv2D(filters=32,
                     kernel_size=(3,3),
                     activation='relu',
                     input_shape=(150,150,3)))
    model.add(MaxPooling2D(pool_size=(2,2)))
    
    model.add(Conv2D(filters=64,
                     kernel_size=(3,3),
                     activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    
    model.add(Conv2D(filters=128,
                     kernel_size=(3,3),
                     activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    
    model.add(Conv2D(filters=128,
                     kernel_size=(3,3),
                     activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    
    model.add(Flatten())
    model.add(Dropout(0.5))
    model.add(Dense(units=512,
                    activation='relu'))
    
    model.add(Dense(units=1,
                    activation='sigmoid'))
       
    model.compile(optimizer=Adam(learning_rate=1e-4),
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    
    history = model.fit(train_generator,
                        steps_per_epoch=100,    # bach_size * steps_per_epoch > data의 양  XXX
                        epochs=30,
                        validation_data=validation_generator,
                        validation_steps=50)

model.save('./cat_dog_small_cnn_model.h5')    

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
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
글 보관함