✔️ 수만 장에 달하는 기존의 이미지에서 학습한 정보를 가져와 내 프로젝트에 활용하는 것
- 이미지 분류 기법인 CNN을 통해 진행 : 지도학습
- 데이터 : 280개 뇌 단면 사진
- train : 160
- test : 120
- 치매환자(ad 폴더에 있음) : 140
- 일반인(normal 폴더에 있음) : 140
- ImageDataGenerator() : 데이터의 수를 늘림 ➡️ 주어진 데이터를 이용해 변형된 이미지를 만들어 학습셋에 포함시킴
train_datagen = ImageDataGenerator( rescale=1./255, horizontal_flip=True, width_shift_range=0.1, height_shift_range=0.1, rotation_range=5, shear_range=0.7, zoom_range=1.2, vertical_flip=True, fill_mode='nearest')
- 이미지 생성옵션
- rescale : 주어진 이미지의 크기 변경
- 1./255 : 원본영상이 0~255의 RGB값을 가졌기 때문에 255로 나눠서 0~1사이의 값으로 변경
- horizontal_flip/vertical_flip : 주어진 이미지를 수평/수직으로 뒤집음
- zoom_range : 정해진 범위 내 축소 및 확대
- width_shift_range, height_shift_range : 정해진 범위 안에서 그림을 수평, 수직으로 랜덤하게 평행 이동
- rotation_range : 정해진 각도만큼 이미지 회전
- shear_range : 좌표 하나 고정시키고 다른 몇 개의 좌표를 이동시키는 반환
- fill_mode : 이미지를 축소, 회전, 이동 시 생기는 빈 공간을 어떻게 채울지 결정
- nearest : 가장 비슷한 색으로 채워짐
➡️ 인자 전체 적용 시 불필요한 데이터가 생성될 수 있음
✔️ 데이터 부풀리기 : 학습셋에서만 적용
test_datagen = ImageDataGenerator(rescale=1./255)
- flow_from_directory(): 폴더에 저장된 데이터 불러옴
- 실제 데이터의 위치와 이미지를 불러옴
train_generactor = train_datagen.flow_from_directory( './trian', target_size = (150,150), batch_size = 5, class_mode = 'binary' ) test_generactor = test_datagen.flow_from_directory( './test', target_size = (150,150), batch_size = 5, class_mode = 'binary' )
model.fit_generator(
train_generator, #학습 모델
steps_per_epochs=100, # 이미지 생성기에서 추출할 샘플 이미지
epochs=20,
validation_data = test_generator, validation_steps=4)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout, Flatten, Dense, Conv2D, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import optimizers, initializers, regularizers, metrics
np.random.seed(3)
tf.random.set_seed(3)
train_datagen = ImageDataGenerator(rescale = 1./255,
horizontal_flip=True, #수평 대칭 이미지를 50% 확률로 만들어 추가함
width_shift_range=0.1, #전체 크기의 10% 범위에서 좌우로 이동
height_shift_range=0.1,# 전체크기의 10% 범위에서 위아래로 이동
fill_mode='nearest')
train_generator = train_datagen.flow_from_directory('./train',
target_size=(150,150),
batch_size=5,
class_mode='binary')
test_datagen = ImageDataGenerator(rescale = 1./255)
test_generator = test_datagen.flow_from_directory('./test',
target_size=(150,150),
batch_size=5,
class_mode='binary')
#CNN 모델
model = Sequential()
model.add(Conv2D(32, (3,3), input_shape=(150,150,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(32, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('sigmoid'))
model.compile(loss='sparse_categorical_crossentropy', optimizer=optimizers.Adam(learning_rate=0.0002), metrics=['accuracy'])
model.fit_generator(train_generator, steps_per_epoch=100, epochs=20,
validation_data = test_generator,
validation_steps=10)
acc= history.history['accuracy']
val_acc= history.history['val_accuracy']
y_vloss = history.history['val_loss']
y_loss = history.history['loss']
x_len = np.arange(len(y_loss))
plt.plot(x_len, acc, marker='.', c="red", label='Trainset_acc')
plt.plot(x_len, val_acc, marker='.', c="lightcoral", label='Testset_acc')
plt.plot(x_len, y_vloss, marker='.', c="cornflowerblue", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss/acc')
plt.show()
✔️ 이미지넷 학습 정보 이용 목적 : '형태'를 구분하는 기본적인 학습이 되어 있음.
ex) 딥러닝 : 어떤 픽셀의 조합이 '선', 어떤 형태의 그룹이 '면'인지 하나씩 파악하는 등 기본적인 학습을 하는데만도 많은 시간이 걸림.
🔆 전이학습 : 방대한 대용량 데이터를 이용해 학습한 가중치 정보를 가져와 내 모델에 적용 후 사용 가능
transfer_model = VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3))
transfer_model.trianable = False
transfer_model.summary()
finetune_model = models.Sequential()
finetune_model.add(transfer_model)
finetune_model.add(Flatten())
finetune_model.add(Dense(64, activation='relu'))
finetune_model.add(Dense(2, activation='softmax'))
finetune_model.summary()
train_datagen = ImageDataGenerator(rescale = 1./255,
horizontal_flip=True, #수평 대칭 이미지를 50% 확률로 만들어 추가함
width_shift_range=0.1, #전체 크기의 10% 범위에서 좌우로 이동
height_shift_range=0.1,# 전체크기의 10% 범위에서 위아래로 이동
fill_mode='nearest')
train_generator = train_datagen.flow_from_directory('./train',
target_size=(150,150),
batch_size=5,
class_mode='binary')
test_datagen = ImageDataGenerator(rescale = 1./255)
test_generator = test_datagen.flow_from_directory('./test',
target_size=(150,150),
batch_size=5,
class_mode='binary')
transfer_model = VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3))
transfer_model.trianable = False
finetune_model = models.Sequential()
finetune_model.add(transfer_model)
finetune_model.add(Flatten())
finetune_model.add(Dense(64, activation='relu'))
finetune_model.add(Dense(2, activation='softmax'))
finetune_model.compile(loss='sparse_categorical_crossentropy', optimizer=optimizers.Adam(learning_rate=0.0002), metrics=['accuracy'])
history = finetune_model.fit_generator(train_generator, steps_per_epoch=100, epochs=20,
validation_data = test_generator,
validation_steps=10)
acc= history.history['accuracy']
val_acc= history.history['val_accuracy']
y_vloss = history.history['val_loss']
y_loss = history.history['loss']
x_len = np.arange(len(y_loss))
plt.plot(x_len, acc, marker='.', c="red", label='Trainset_acc')
plt.plot(x_len, val_acc, marker='.', c="lightcoral", label='Testset_acc')
plt.plot(x_len, y_vloss, marker='.', c="cornflowerblue", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss/acc')
plt.show()