티스토리 뷰
▶딥러닝 CNN 모델 구현
CNN 모델을 Sequential하게 layer를 쌓아 만들려고 합니다.
참고하면 좋은 도큐먼트를 링크해 놓겠습니다.
이 중에서 다음 부분을 참고하여 모델을 만들어주는 함수를 정의하려고 합니다.
1) 필요한 라이브러리 import
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
2) 함수 정의해서 모델 만들기
def get_sequencial_model(input_shape):
model = keras.Sequential(
[
layers.Input(input_shape), # 입력층 만듦 -> 은닉층으로 데이터를 보낼 예정
# 1st
# 64개의 데이터 받음(필터64개 사용). 3x3 필터 크기, 패딩을 자동으로 생성
layers.Conv2D(64, 3, strides=1, activation='relu', padding='same'),
layers.Conv2D(64, 3, strides=1, activation='relu', padding='same'),
# 가중치 2번 업데이트. 좀 더 세밀해짐
layers.MaxPool2D(), # maxPooling
layers.BatchNormalization(), # 픽셀값을 정규화
layers.Dropout(0.5), # 과대적합 방지
# 2nd
layers.Conv2D(128, 3, strides=1,m activation='relu', padding='same'),
layers.Conv2D(128, 3, strides=1,m activation='relu', padding='same'),
layers.MaxPool2D(),
layers.BatchNormalization(),
layers.Dropout(0.3),
# FC
layers.GlobalMaxPool2D(), # 다합쳐서 맥스풀링
layers.Dense(128, activaiton='relu'), # Dense: 일반 레이어
layers.Dense(1, activation='sigmoid')
]
)
return model
이제 model의 input_shape를 입력하여 모델을 만들어 보겠습니다.
input_shape = (256,256,3)
model = get_sequential_model(input_shape)
CNN 모델이 어떻게 이뤄져 있는지 summary를 확인 가능합니다.
model.summary()
out:
3) class로 keras.Model을 상속받아서 모델 만들기
class SimpleCNN(keras.Model): # keras.Model을 상속받아옴
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv_block_1 = keras.Sequential(
[
layers.Conv2D(64, 3, strides=1, activation='relu', padding='same'),
layers.Conv2D(64, 3, strides=1, activation='relu', padding='same'),
layers.MaxPool2D(),
layers.BatchNormalization(),
layers.Dropout(0.5)
], name='conv_block_1'
)
self.conv_block_2 = keras.Sequential(
[
layers.Conv2D(128, 3, strides=1, activation='relu', padding='same'),
layers.Conv2D(128, 3, strides=1, activation='relu', padding='same'),
layers.MaxPool2D(),
layers.BatchNormalization(),
layers.Dropout(0.3)
], name='conv_block_2'
)
self.classifier = keras.Sequential(
[
layers.GlobalMaxPool2D(),
layers.Dense(128, activation='relu'),
layers.Dense(1, activation='sigmoid')
], name='classifier'
)
def call(self, input_tensor, training=False):
x = self.conv_block_1(input_tensor)
x = self.conv_bolock_2(x)
x = self.classifier(x)
return x
이제 방금 정의한 class를 이용하여 모델을 만들어 보겠습니다.
input_shape = (None, 256, 256, 3) # batch_size = None
model = SimpleCNN()
model.build(input_shape) # call() 함수가 실행됨
모델을 확인해 봅시다.
model.summary()
out:
4) 모델 설정값 setting
방금까지 모델 객체를 만드는 것까지 했습니다.
이제 모델을 학습시키고 테스트 하기 위해서는 기본 설정값이 필요합니다.
이때 중요하게 설정해야 하는 요소들은 어떤 optimizer를 사용할 건지, 어떤 loss 함수를 사용할 건지, 어떤 검증 방법을 가질 건지 등 입니다.
model.compile(
optimizer = 'adam',
loss = 'binary_crossentropy',
metrics = 'accuracy'
)
5) 학습과 테스트를 위한 generator 만들기
아래 글에서 모델에서 데이터를 효율적으로 전달하기 위한 DataGenerator라는 class를 정의했었습니다.
이 부분을 가져와 사용하겠습니다.
class DataGenerator(keras.utils.Sequence):
def __init__(self, batch_size, csv_path, fold, image_size, mode='train', shuffle=True):
self.batch_size = batch_size
self.csv_path = csv_path
self.fold = fold
self.image_size = image_size
self.mode = mode
self.shuffle = shuffle
self.df = pd.read_csv(csv_path)
df = pd.read_csv(csv_path)
if self.mode == 'train':
self.df = self.df[self.df['fold'] != self.fold]
elif self.mode == 'val':
self.df = self.df[self.df['fold'] == self.fold]
self.on_epoch_end()
def on_epoch_end(self):
if self.shuffle:
self.df = self.df.sample(frac=1).reset_index(drop=True)
def __len__(self):
return math.ceil(len(self.df) / self.batch_size)
def __getitem__(self, idx):
start = idx * self.batch_size
end = (idx+1) * self.batch_size
data = self.df.iloc[start:end]
batch_x, batch_y = self.get_data(data)
return np.array(batch_x), np.array(batch_y)
def get_data(self, data):
batch_x = []
batch_y = []
for _, r in data.iterrows():
file_name = r['file_name']
image = cv2.imread(f'data/images/{file_name}.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (self.image_size, self.image_size))
image = image / 255.
label = int(r['species']) - 1
batch_x.append(image)
batch_y.append(label)
return batch_x, batch_y
이제 위 class를 이용하여 train_generator와 valid_generator를 생성할 겁니다.
csv_path = 'data/kfolds.csv'
train_generator = DataGenerator(
batch_size = 128,
csv_path = csv_path,
fold = 1,
image_size = 256,
mode = 'train',
shuffle = True
)
valid_generator = DataGenerator(
batch_size = 128,
csv_path = csv_path,
fold = 1,
image_size = 256,
mode = 'val',
shuffle = True
)
6) Callback 함수 작성하기
① EarlyStopping
모델을 더 이상 학습을 못할 경우(loss, metric 등의 개선이 없을 경우), 학습 도중 미리 학습을 종료시키는 콜백함수입니다.
인자는 다음과 같습니다.
인자 | 설명 |
monitor | - EarlyStopping의 기준이 되는 값을 입력합니다. - 만약 'val_loss'를 입력하면 val_loss가 더 이상 감소되지 않을 경우 EarlyStopping을 적용합니다. - 이외에도 다양한 값을 입력할 수 있습니다. |
min_delta | - 개선된 것으로 간주하기 위한 최소한의 변화량입니다. |
patience | - Training이 진행됨에도 더 이상 monitor되는 값의 개선이 없을 경우, 최적의 monitor 값을 기준으로 몇번의 epoch을 진행할 지 정하는 값입니다. |
verbose | - 0 또는 1 - 1일 경우, EarlyStopping이 적용될 때, 화면에 적용되었다고 나타냅니다. - 0일 경우, 화면에 나타냄 없이 종료합니다. |
mode | - "auto" 또는 "min" 또는 "max" - monitor되는 값이 최소가 되어야 하는지, 최대가 되어야 하는지 알려주는 인자입니다. |
baseline | - 모델이 달성해야 하는 최소한의 기준값을 선정합니다. - patience 이내에 모델이 baseline보다 개선됨이 보이지 않으면 Training을 중단시킵니다. |
restore_best_weights | - True 또는 False - True라면 training이 끝난 후, model의 weight를 monitor하고 있던 값이 가장 좋았을 때의 weight를 복원합니다. - False라면 마지막 training이 끝난 후의 weight로 놔둡니다. |
early_stopping = tf.keras.callbacks.EarlyStopping(
monitor = 'val_loss',
patience = 3,
mode = 'min',
restore_best_weights = False
)
② ReduceLROnPlateau
모델의 개선이 없을 경우, learning rate를 조절해 모델의 개선을 유도하는 콜백함수입니다.
인자는 다음과 같습니다.
인자 | 설명 |
monitor | - ReduceLROnPlateau의 기준이 되는 값을 입력합니다. - 만약 'val_loss' 를 입력하면 val_loss가 더이상 감소되지 않을 경우 ReduceLROnPlateau을 적용합니다. |
factor | - Learning rate를 얼마나 감소시킬 지 정하는 인자값입니다. - 새로운 learning rate는 기존 learning rate * factor입니다. |
patience | - Training이 진행됨에도 더이상 monitor되는 값의 개선이 없을 경우, 최적의 monitor 값을 기준으로 몇 번의 epoch을 진행하고, learning rate를 조절할 지의 값입니다. |
verbose | - 0 또는 1 - 1일 경우, EarlyStopping이 적용될 때, 화면에 적용되었다고 나타냅니다. - 0일 경우, 화면에 나타냄 없이 종료합니다. |
mode | - "auto" 또는 "min" 또는 "max" - monitor되는 값이 최소가 되어야 하는지, 최대가 되어야 하는지 알려주는 인자입니다. |
min_delta | - 개선된 것으로 간주하기 위한 최소한의 변화량입니다. |
cooldown | - Learning rate가 감소한 후, ReduceLROnPlateau 콜백함수를 다시 실행하기 전에 대기 할 Epoch 수입니다. |
min_lr | - Learning rate의 하한선을 지정합니다. |
reduce_on_plateau = tf.keras.callbacks.ReduceLROnPlateau(
monitor = 'val_loss',
factor = 0.1, # 수정할 때 얼마를 더 곱해줄지를 설정
patience = 10, # 10번 좋아지지 않으면 적용하겠다.
mode = 'min',
min_lr = 0.0001 # 계속 값이 작아지기 때문에 제한을 둠
)
③ ModelCheckpoint
모델을 저장할 때 사용되는 콜백함수입니다.
인자는 다음과 같습니다.
인자 | 설명 |
filepath | - 모델을 저장할 경로를 입력합니다. - 참고로 모델 경로를 '{epoch:02d}-{val_loss:5f}.h5'라고 입력하면, 에폭-해당에폭에서의 val_loss.h5로 모델이 저장됩니다. |
monitor | - 모델을 저장할 때 기준이 되는 값입니다. |
verbose | - 0 또는 1 - 1일 경우, EarlyStopping이 적용될 때, 화면에 적용되었다고 나타냅니다. - 0일 경우, 화면에 나타냄 없이 종료합니다. |
save_best_only | - True 또는 False - True인 경우, monitor 되고 있는 값을 기준으로 가장 좋은 값으로 모델이 저장됩니다. - False인 경우, 매 에폭마다 모델이 filepath{epoch}으로 저장됩니다.(model1, model1, model2,...) |
save_weights_only | - True 또는 False - True인 경우, 모델의 weights만 저장됩니다. - False인 경우, 모델 레이어 및 weights 모두 저장됩니다. |
mode | - "auto" 또는 "min" 또는 "max" - auto로 할 경우, 모델이 알아서 min, max를 판단하여 모델을 저장합니다. |
save_freq | - 'epoch' 또는 'integer' - epoch를 사용할 경우, 매 에폭마다 모델이 저장됩니다. - integer를 사용할 경우, 숫자만큼의 배치를 진행하면 모델이 저장됩니다. |
options | - tf.train.CheckpointOptions를 옵션으로 줄 수 있습니다. 분산환경에서 다른 디렉토리에 모델을 저장하고 싶을 경우 사용합니다. - 자세한 내용은 아래 링크를 참조해주세요.www.tensorflow.org/api_docs/python/tf/train/CheckpointOptions |
7) 모델 학습
history = model.fit(
train_generator,
validation_data = valid_generator,
epochs=10,
callbacks = [
early_stopping,
reduce_on_plateau,
model_checkpoint
]
)
out:
여기까지 CNN 모델 구현을 해보았습니다 :)
cpu로 모델을 학습시키는 데에 시간이 굉장히 많이 걸린 기억이 납니다 ..
'빅데이터 인공지능 > 딥러닝' 카테고리의 다른 글
[딥러닝] CNN(Convolutional Neural Network)과 MLP(Multi Layer Perceptron) 의 차이 (0) | 2022.11.19 |
---|---|
[딥러닝] 딥러닝(ANN, DNN, CNN, RNN, SLP, MLP) 비교 (0) | 2022.11.19 |
[딥러닝] CNN(Convolutional Neural Network) 알아보기 (0) | 2022.09.18 |
[딥러닝] Oxford Pets Dataset 실습🎯 (0) | 2022.09.18 |
[딥러닝] 역전파(Backpropagation) - 경사하강법 & 활성화 함수 (0) | 2022.09.12 |
- Total
- Today
- Yesterday
- rtl
- frontend
- 자바스크립트 기초
- 리액트 훅
- react-query
- HTML
- next.js
- TypeScript
- 타입스크립트
- 디프만
- 데이터분석
- 자바스크립트
- CSS
- testing
- 프로젝트 회고
- Python
- 인프런
- 머신러닝
- 자바
- 프론트엔드
- styled-components
- 프론트엔드 기초
- 프론트엔드 공부
- 리액트
- JSP
- 딥러닝
- jest
- react
- 파이썬
- 스타일 컴포넌트 styled-components
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |