Open njs03332 opened 1 year ago
optimizer = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999)
종류
거듭제곱 기반 스케줄링: 학습률을 반복 횟수 t에 대한 아래 함수로 정의. 초기 학습률 𝜂0, 거듭제곱 수 c (일반적으로 1), 스텝 횟수 s (하이퍼파라미터). s번 스텝마다 학습률이 감소되며, 점점 느리게 감소됨. 𝜂0 과 s 튜닝 필요
지수 기반 스케줄링: 학습률을 반복 횟수 t에 대한 아래 함수로 정의. s 스텝마다 학습률이 10배씩 감소
구간별 고정 스케줄링: 일정 횟수의 에포크 동안 일정한 학습률을 사용하고, 또 다른 횟수의 에포크 동안 작은 학습률을 사용. 적절한 학습률과 에포크 횟수의 조합을 찾기 위해 이리저리 바꿔봐야 함
성능 기반 스케줄링: N 스텝마다 검증 오차를 측정하고, 오차가 줄어들지 않으면 λ배만큼 학습률을 감소
1사이클 스케줄링: 훈련 절반 동안 초기 학습률 𝜂0을 선형적으로 𝜂1까지 증가시킴. 나머지 절반 동안 선형적으로 𝜂0까지 다시 감소시킴. 마지막 몇 번의 포크는 소수점 몇 째 자리까지 줄임
𝜂1은 최적의 학습률을 찾을 때와 같은 방식으로 선택
𝜂0은 대략 10배 정도 낮은 값 선택
모멘텀 사용시 처음에 높은 모멘텀으로 시작, 훈련 절반 동안 낮은 모멘텀으로 감소, 나머지 절반 동안 최댓값으로 다시 증가, 마지막 몇 번의 에포크는 최댓값으로 진행
레슬리 스미스 (2018)는 많은 실험을 통해 이 방식이 훈련 속도와 성능을 높여준다는 것을 보임
decay
매개변수 지정 (s의 역수)optimizer = keras.optimizers.SGD(lr=0.01, decay=1e-4)
LearningRateScheduler
콜백을 만들어 fit()
메서드에 전달def exponential_decay(lr0, s):
def exponential_decay_fn(epoch):
return lr0 * 0.1 ** (epoch / s)
return exponential_decay_fn
exponential_decay_fn = exponential_decay(lr0=0.01, s=20)
# LearningRateScheduler는 에포크를 시작할 때마다 옵티마이저의 learning_rate 속성을 업데이트함
lr_scheduler keras.callbackes.LearningRateScheduler(exponential_decay_fn)
history = model.fit(X_train_scaled, y_train, [...], callbacks=[lr_scheduler])
def exponential_decay_fn(epoch, lr):
return lr * 0.1**(1 / 20)
모델 저장시 옵티마이저와 학습률이 함께 저장됨
epoch
매개변수를 사용하는 경우 에포크는 저장되지 않고 fit()
메서드 호출시마다 0으로 초기화됨 -> epoch
에서 시작하도록 fit()
메서드의 initial_epoch
매개변수를 수동으로 지정하는 방법이 있음구간별 고정 스케줄링: 다음과 같은 스케줄 함수를 만들어 똑같이 LearningRateScheduler
콜백을 만들어 fit()
메서드에 전달
def piecewise_constant_fn(epoch):
if epoch < 5:
return 0.01
elif epoch < 15:
return 0.005
else:
return 0.001
성능 기반 스케줄링: ReduceLROnPlateau
콜백 정의하여 fit()
메서드에 전달
# 최상의 검증 손실이 다섯 번의 연속적인 에포크 동안 향상되지 않을 때마다 학습률에 0.5를 곱함
lr_scheduler = keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=5)
tf.keras
를 이용한 학습률 스케줄링
keras.optimizers.schedules
에 있는 스케줄 중 하나를 사용해 학습률 정의하여 옵티마이저에 전달
에포크가 아닌 매 스텝마다 학습률을 업데이트함
s = 20 * len(X_train) // 32 # 배치 크기 = 32
learning_rate = keras.optimizers.schedules.ExponentialDecay(0.01, s, 0.1)
optimizer = keras.optimizers.SGD(learning_rate)
모델 저장시 학습률과 스케줄도 함께 저장됨
표준 Keras API는 아님
1사이클 스케줄링: 매 반복마다 학습률을 조정하는 사용자 정의 콜백 만들기 (self.model.optimizer.lr
을 바꾸어 옵티마이저의 학습률 업데이트
최근 구글 브레인팀의 논문(2017)에서는 SGD, 모멘텀, 네스테로프 가속 경사 등에서 학습률 감소 대신 배치 크기를 늘려서 같은 성능을 얻었다고 함
layer = keras.layers.Dense(100, activation="elu", kernel_initializer="he_normal", kernel_regularizer=keras.regularizer.l2(0.01))
from functools import partial RegularizedDense = partial(keras.layers.Dense, activation="elu", kernel_initializer="he_normal", kernel_regularizer=keras.regularizer.l2(0.01))
model = keras.models.Sequential([ keras.layers.Flatten(input_shape=[28, 28]), RegularizedDense(300), RegularizedDense(100), RegularizedDense(10, activation="softmax", kernel_intializer="glorot_uniform") ])
### 11.4.2 드롭아웃
- 매 훈련 스텝에서 각 뉴런(입력 뉴런 포함. 출력 뉴런은 제외)은 임시적으로 드롭아웃될 확률 p를 가짐
- 이번 훈련 스텝에는 완전히 무시되지만 다음 스텝에서는 활성화될 수 있음
![image](https://user-images.githubusercontent.com/26505830/216330148-f63e1530-4e7f-4355-b436-4eb502cd8977.png)
- 하이퍼파라미터 p를 드롭아웃 비율이라고 하고 보통 10%-50% 사이 지정
- 순환 신경망에서는 20%-30%에 가까움
- 합성곱 신경망에서는 40%-50%에 가까움
- 훈련이 끝난 후에는 뉴런에 더는 드롭아웃을 적용하지 않음
- 드롭아웃으로 훈련된 뉴런은 이웃한 뉴런에 맞추어 적응될 수 없으므로 가능한 한 자기 자신이 유용해져야 함
- 그래서 입력값의 작은 변화에 덜 민감해지고, 더 안정적인 네트워크가 되어 일반화 성능이 좋아짐
- TIP) 일반적으로 출력층을 제외한 맨 위의 층부터 세 번째 층까지 있는 뉴런에만 드롭아웃을 적용함
- p=50%로 하면 테스트하는 동안에는 하나의 뉴런이 훈련 때보다 평균적으로 두 배 많은 입력 뉴런과 연결됨
- 훈련이 끝난 후 각 입력의 연결 가중치에 보존 확률(1-p)를 곱하거나
- 훈련하는 동안 각 뉴런의 출력을 보존 확률로 나눌 수도 있음 (위의 방법과 동일하진 않지만 잘 동작함)
- 케라스에서는 `keras.layers.Dropout` 층을 사용하여 드롭아웃을 구현
- 주의) 드롭아웃은 훈련하는 동안에만 활성화되므로 훈련 손실과 검증 손실을 비교하면 안됨
비슷한 손실이더라도 훈련 세트에 과대적합될 수 있으므로 훈련이 끝난 후 드롭아웃을 빼고 훈련 손실을 평가해야함
- 모델이 과대적합되었다면 드롭아웃 비율을 늘리고, 반대로 과소적합되면 드롭아웃 비율을 낮춰야 함
- 층이 클 때는 드롭아웃 비율을 늘리고 작으 ㄴ층에는 드롭아웃 비율을 낮추는 것이 도움이 됨
- 많은 최신 신경망 구조는 마지막 은닉층 뒤에만 드롭아웃을 사용함
- 드롭아웃은 수렴을 상당히 느리게 만드는 경향이 있지만 적절히 튜닝하면 훨씬 좋은 모델을 만들 수 있음
- TIP) 자기 정규화하는 네트워크를 규제하고 싶다면 알파 드롭아웃을 사용해야 함. 일반 드롭아웃은 자기 정규화하는 기능을 망가뜨릴 수 있음