1 분 소요

머신 러닝은 기존의 모델을 사용하되, 구조는 고정되어있는 반면, 딥러닝의 경우 하이퍼파라미터가 많아서 직접 모델의 구조를 조정하면서 만든다라는 느낌이 강하다.

🔮 손실 곡선

📍 데이터 불러오기

from tensorflow import keras
from sklearn.model_selection import train_test_split

(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

-> 모델을 만들어주는 함수 생성

def model_fn(a_layer=None):
  model = keras.Sequential()
  model.add(keras.layers.Flatten(input_shape=(28, 28)))
  model.add(keras.layers.Dense(100, activation='relu'))
  if a_layer:
    model.add(a_layer)
  model.add(keras.layers.Dense(10, activation='softmax'))
  return model

📍 손실 함수 그리기

fit() 메소드를 사용하면 History 클래스 객체를 반환 -> 여기에는 훈련 과정에서 계산한 손실과 정확도 값이 저장되어 있다.

model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=5, verbose=0)
print(history.history.keys())

>>> dict_keys(['loss', 'accuracy'])

hitstory라는 객체의 history 딕셔너리가 있는데 여기의 key 값은 손실과 정확도가 있다.

  1. epoch = 5

    import matplotlib.pyplot as plt
    plt.plot(history.history['loss'])
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.show()
    

    download1

    plt.plot(history.history['accuracy'])
     plt.xlabel('epoch')
     plt.ylabel('accuracy')
     plt.show()
    

    download2

  2. epoch = 20

    model = model_fn()
    model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
    history = model.fit(train_scaled, train_target, epochs=20, verbose=0)
    plt.plot(history.history['loss'])
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.show()
    

    download1

     plt.plot(history.history['accuracy'])
     plt.xlabel('epoch')
     plt.ylabel('accuracy')
     plt.show()
    

    download2

🔮 검증 손실

과대 적합, 과소 적합을 알기 위해서는 훈련 세트의 손실 + 검증 세트의 손실까지 그려야 된다.

model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))

이런식으로 fit() 메소드에서 validation_data 매개변수에 검증에 사용할 입력과 타깃값을 튜플로 전달해주면 history 객체의 key 값으로 추가가 된다.

  1. 기본 RMSprop 옵티마이저 사용

    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.legend(['train', 'val'])
    plt.show()
    

    download1

  2. adam 사용

    model = model_fn()
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
    history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))
    

    download2


과대 적합을 막기 위해서는 옵티마이저를 수정하는 방식으로 진행할 수 있다.

🔮 드롭 아웃

훈련 과정에서 층에 있는 일부 뉴런을 랜덤하게 꺼서 과대적합을 막는다.

왜 과대적합을 막을 수 있을까?

  1. 이전 층의 일부 뉴런이 랜덤하게 꺼지면 특정 뉴런에 과대하게 의존하는 것을 줄일 수 있고, 모든 입력에 주의를 기울여야 한다.

  2. 2개의 신경망을 앙상블 하는 것 처럼 상상 가능

model = model_fn(keras.layers.Dropout(0.3))

-> 30% 정도 드롭 아웃

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

download1

->어느 정도 과대 적합 해결된 것을 확인할 수 있음.

댓글남기기