티스토리 뷰

▶딥러닝 CNN 모델 구현

CNN 모델을 Sequential하게 layer를 쌓아 만들려고 합니다.

참고하면 좋은 도큐먼트를 링크해 놓겠습니다.

 

Sequential 모델  |  TensorFlow Core

Sequential 모델 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 설정 import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers Sequential 모델을 사용하

www.tensorflow.org

이 중에서 다음 부분을 참고하여 모델을 만들어주는 함수를 정의하려고 합니다.

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를 정의했었습니다.

이 부분을 가져와 사용하겠습니다.

 

[머신러닝] ⑲ 딥러닝 Oxford Pets Dataset 실습🎯

▶Oxford Pets Dataset 실습 - https://www.robots.ox.ac.uk/~vgg/data/pets/ Visual Geometry Group - University of Oxford www.robots.ox.ac.uk Oxford Pets Dataset은 강아지와 고양이를 분류하기 위한 데이..

doeunn.tistory.com

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로 모델을 학습시키는 데에 시간이 굉장히 많이 걸린 기억이 납니다 ..

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함