✅ 정리
- 드롭아웃: 은닉층에 있는 뉴런의 출력을 랜덤하게 꺼서 과대적합 막는기법
- 콜백: 케라스 모델을 훈련하는 도중에 어떤 작업을 수행할 수 있도록 도와주는 도구
- 조기종료(early stopping): 검증 점수가 더 이상 감소하지 않고 상승하여 과대적합이 일어남녀 훈련을 계속 진행하지 않고 멈추는 기법
머신러닝 알고리즘들은 좋은 성능을 내기 위해 매개변수를 조정하고 훈련하는 과정 반복 -> 모델의 구조가 어느 정도 고정
딥러닝에서는 모델의 구조를 직접 만드는 느낌이 강함(층을 추가하고 층에 있는 뉴런의 개수와 활성화 함수를 결정하는 과정)
케라스의 fit()메서드는 History 클래스 객체를 반환 -> History 객체에는 훈련과정에서 계산한 지표, 즉 손실과 정확도 값이 저장되어 있음
데이터 불러오기
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
-> if 구문의 역할은 model_fn() 함수에 케라스 층을 추가하면 은닉층 뒤에 또 하나의 층을 추가하는 것
model = model_fn()
model.summary()
history()
model.compile(loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')
history = model.fit(train_scaled, train_target, epochs = 5, verbose = 0)
# verbose: 훈련 과정 출력을 조절
print(history.history.keys())
-> history딕셔너리 안에는 손실과 정확도 포함
import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
-> 에포크마다 손실이 감소하고 정확도가 향상 => 에포크 횟수를 늘려서 더 훈련
model.compile(loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')
history = model.fit(train_scaled, train_target, epochs = 20, verbose = 0)
import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
-> 손실 감소 but 훈련 세트 점수뿐만 아니라 검증 세트에 대한 점수도 필요
검증 손실
손실과 정확도 중 어떤 것을 확인해야 하나?
: 인공 신경망 모델이 최적화 하는 대상은 정확도가 아닌 손실 함수 어떤 경우에는 손실 감소에 비례하여 정확도가 높아지지 않는 경우도 있음 -> 모델이 잘 훈련되었는지 판단하려면 정확도 보다는 손실 함수의 값을 확인하는 것이 더 낫다
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() 메서드에 검증 데이터 전달할 수 있음
print(history.history.keys())
-> 훈련 세트와 검증 세트의 손실과 정확도 들어있음
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
-> 초기에 검증 손실이 감소하다가 다시 상승, 훈련 손실은 꾸준히 감소하기 때문에 과대적합 모델이 만들어짐 -> 검증 손실이 상승하는 시점을 가능한 뒤로 늦추면 검증 세트에 대한 손실이 줄어들 뿐만 아니라 검증 세트에 대한 정확도도 증가
=> 어떻게 과대적합 막을 수 있을까? 옵티마이저 조정, 드롭아웃
옵티마이저 하이퍼파라미터 조정
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))
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
-> 과대적합 줄어듦
드롭아웃
훈련 과정에서 층에 있는 일부 뉴련을 랜덤하게 꺼서(출력을 0으로) 과대적합을 막음
뉴런은 랜덤하게 드롭아웃 되고 얼마나 많은 뉴런을 드롭할지는 우리가 결정해야 함
model = model_fn(keras.layers.Dropout(0.3))
model.summary()
-> 어떤 층 뒤에 드롭아웃을 두어 이 층의 출력을 랜덤하게 0으로 만듦 -> 드롭아웃이 층처럼 사용되지만 훈련되는 모델 파라미터는 없음
출력결고에서 볼 수 있듯이 은닉층 뒤에 추가된 드롭아웃 층(Dropout)은 훈련되는 모델 파라미터가 없음. 또한 입력과 출력의 크기가 같음. 일부 뉴런의 출력을 0으로 만들지만 전체 출력 배열의 크기를 바꾸지는 않음
model = model_fn(keras.layers.Dropout(0.3))
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()
-> 과대적합 줄었음 epoch를 20번 동안 훈련했기 때문에 과대적합 되었음. 10회로 조정
콜백 - Early Stopping
콜백은 훈련 과정 중간에 어떤 작업을 수행할 수 있게 하는 객체로 keras.callbacks 패키지 아래에 있는 클래스
20번에 에포크를 설정해주는 경우 검증 점수가 상승하기 시작하면 그 이후에는 과대적합이 커지기 때문에 훈련을 계속할 필요가 없음 -> 이때 훈련을 미리 중지하는 것을 early stopping이라고 부름
early stopping은 훈련 에포크 횟수를 제한하는 역할이지만 모델이 과대적합 되는 것을 막아주기 때문에 규제 방법 중 하나로 생각할 수 있음
patience 매개변수는 검증 점수가 향상되지 않더라도 참을 에포크 횟수로 지정
restore_best_weights 매개변수를 True로 지정하면 가장 낮은 검증 손실을 낸 모델 파라미터로 되돌림
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy',
metrics = 'accuracy')
early_stopping_cb = keras.callbacks.EarlyStopping(patience = 2,
restore_best_weights = True)
history = model.fit(train_scaled, train_target, epochs = 10, verbose = 0,
validation_data = (val_scaled, val_target),
callbacks = early_stopping_cb)
print(early_stopping_cb.stopped_epoch)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
평가
model.evaluate(val_scaled, val_target)
참고: