11장. 심층 신경망 훈련하기
심층 신경망 학습 중 발생할 수 있는 문제들과 그에 대한 해결 방안
📌 훈련 속도를 높이는 방법
1. 연결 가중치에 좋은 초기화 전략 사용
2. 좋은 활성화 함수 사용
3. 배치 정규화 사용
4. 사전 훈련된 네트워크의 일부 재사용
1. 그래디언트 소실 및 폭주
1-1. 그래디언트 소실 및 폭주 문제점
- 그래디언트 소실 : 하위층으로 갈수록 그래디언트가 점점 작아지는 경우
- 그래디언트 폭주 : 하위층으로 갈수록 그래디언트가 점점 커져 비정상적으로 큰 가중치 갱신
ex) 로지스틱 활성화 함수
입력이 양수나 음수로 커지면 0 or 1로 수렴해 기울기가 0에 가까워진다.
👉🏻 신경망의 위쪽으로 갈수록 분산이 계속 커져 가장 높은 층에서는 활성화 함수가 0 or 1로 수렴해서 전파할 그래디언트가 거의 없고 실제로 아래쪽 층에는 아무것도 도달하지 않는다.
1-2. 해결방법1) 글로럿과 HE초기화
✔️fan-in : 층의 입력 연결 개수
✔️fan-out : 층의 출력 연결 개수
글로럿 초기화(=세이비어 초기화)
- 각 층의 연결 가중치를 무작위로 초기화
- 여러 층의 기울기 분산 사이에 균형을 맞춰서 특정 층이 너무 주목 받는 현상을 막는다.
- 훈련 속도 상승
- S자 형태의 활성화함수
(로지스틱, 소프트맥스)
와 함께 사용할 때 좋은 성능(RELU와 함께 사용하면 성능 안좋음)
HE 초기화
- ReLU 활성화함수에 대한 초기화
📌 글로럿 초기화 : 로지스틱, 허이퍼볼릭 탄젠트, 소프트맥스 활성화함수와 함께 사용
📌 HE 초기화 : ReLu 함수와 ReLu함수의 변종들
# 글로럿 초기화
keras.layers.Dense(10, activation='relu', kernel_initializer='he_uniform')
# He초기화
keras.layers.Dense(10, activation='relu', kernel_initializer='he_normal')
# fan_avg 기반 균등 분포 He 초기화
he_avg_init = keras.initializers.VarianceScaling(scale=2., \
mode='fan_avg', \
distribution='uniform')
keras.layers.Dense(10, activation='sigmoid',\
kernel_initializer=he_avg_init)
1-3. 해결방법2) 수렴하지 않는 활성화함수
ReLU 함수 : 특정 양숫값에 수렴하지 않는다(장점)
하지만, 죽은 ReLU 문제(훈련하는 동안 일부 뉴런이 0이외의 값을 출력 X) 발생 가능성
ReLU 함수의 변종
- LeakyReLU
일반적으로 함수의 기울기(alpha)를 0.01로 설정하여 절대 죽지 않게 만듬
model = keras,models.Sequential([
[...]
keras.layers.Dense(10, kernel_initializer='he_normal'),
keras.layers.LeakyReLU(alpha=0.2)
[...]
])
- RReLU
alpha를 무작위로 선택, 테스트 시에는 평균 사용하여 규제의 역할 - PReLU
alpha가 훈련하는 동안 학습(But, 소규모 데이터셋에서는 훈련 세트에 overfitting 위험)
model = keras,models.Sequential([
[...]
keras.layers.Dense(10, kernel_initializer='he_normal'),
keras.layers.PReLU()
[...]
])
- ELU
ReLU와 비슷한 형태로 입력이 0이하일 때, 부드럽게 깍아주면서 평균 출력이 0에 가까워짐
- SELU
ELU 활서화 함수의 변종
모든 은닉층에서 SELU를 사용하면 네트워크가 자기 정규화 된다.
이때, 네트워크는 일렬로 쌓은 층으로 구성(와이드&딥과 같은 스킵연결 사용 X)
훈련시 각 층의 출력이 평균 0, 표준편차 1을 유지
layers = keras.layers.Dense(10, activation='selu',
kernel_initializer='lecun_normal')
👉🏻일반적으로 심층 신경망의 은닉층
에서,
SELU > ELU > LeakyReLU > ReLU > tanh < Logistic
1-4. 해결방법3) 배치 정규화
배치 단위로 정규화 하는 것
✔️ 배치 : 학습을 하면서 각 layer의 활성화함수의 입력값 또는 출력값에서 정규화
👉🏻Input값이 같더라도 가중치가 달라지면 완전히 다른 값이 되기 때문에 layer에 배치 정규화 과정을 추가하여 가중치 차이를 완화해서 안정적인 학습을 할 수 있도록 한다.
배치 정규화 알고리즘
- 깊은 네트워크(은닉층이 많은 신경망)에서 주로 사용
- hidden layer에서 활성화 함수의 입력값 또는 출력값에 연산 추가
- 배치의 평균은 0, 분산은 1이 되도록 정규화
- 정규화 이후, 배치 데이터들을 gamma, beta를 통해 새로운 값으로 바꾼다
- gamma, beta는 층의 뉴런마다 하나씩 가진다
스케일 조정
-gamma & beta,이동 평균
-moving_mean, moving_variance
테스트 단계
- 평균과 분산을 계산할 미니 배치가 없으므로 전체 훈련 데이터의 평균과 분산을 사용
🖥 케라스로 배치 정규화 구현
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28,28]),
keras.layers.BatchNormalization(),
kears.layers.Dense(300, activation='elu',
kernel_initializer='he_normal'),
keras.layers.BatchNormalization(),
kears.layers.Dense(100, activation='elu',
kernel_initializer='he_normal'),
keras.layers.BatchNormalization(),
kears.layers.Dense(10, activation='softmax'
])
2. 전이학습 및 비지도 사전훈련
2-1. 전이학습
- 비슷한 유형의 문제를 처리한 신경망의 하위층을 재사용하는 학습 방법
- 훈련 속도 높이고 훈련 데이터 수도 줄일 수 있다
✔️ 케라스를 활용한 전이학습
- 모델 A : 8개의 클래스를 분류하는 패션 MNIST에서 좋은 성능의 모델
- TODO -> 샌들과 셔츠를 구분하는 이진 분류기 모델 B를 만들자
1) 모델A 로드
2) 모델A의 층을 재사용
하여 새로운 모델 생성(출력층을 제외한 모든 층은 재사용)
3) 모델 B를 훈련할 때 모델 A에 영향이 갈 수 있기 때문에 모델 A를 클론하여가중치를 복사
4) 훈련되지 않은 모델 B의 출력층은 랜덤하게 초기화 되어 있기 때문에재사용된 모델 A의 층들은 동결
하고새로운 출력층은 학습
할 시간을 준다
5) 훈련
6) 재사용된 층 동결 해제(이때, 학습률을 낮추는 것을 추천)후 훈련
🖥 keras를 활용한 전이학습
model_A = keras.models.laod_model('model_A.h5')
# 모델 B에 model_A의 layer들 재사용
new_model_B = keras.models.Sequential(model_A.layers[:-1])
# 모델 B에 출력층 생성
new_model_B.add(keras.layers.Dense(1, activation='sigmoid'))
# model_A의 가중치 복사
model_A_clone = keras.models.clone_model(model_A)
model_A_clone.set_weights(model_A.get_weights())
# 동결 후 compile
for layer in new_model_B.layers[:-1]:
layer.trainable = False
new_model_B.compile(loss='binary_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
# 학습
history = nes_model_B.fit(X_train_B, y_train_B, epochs=4,
validation_data=(X_valid_B, y_valid_B))
for layer in new_model_B.layers[:-1]:
layer.trainable = True
# 동결 해제 후 compile
optimizer = keras.optimizer.SGD(lr=1e-4) # 기본 학습률:1e-2
new_model_B.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=['accuracy'])
# 학습
history = new_model_B.fit(X_train_B, y_train_B, epochs=16,
validation_data=(X_valid_B, y_valid_B))
2-2. 비지도 사전훈련
- 레이블 된 데이터가 적을 때, 복잡한 문제를 다룰 때 사용
- 일반적으로 한 번에 비지도 학습 모델 훈련 후 오토인코더 or GAN 사용
3. 최적화 방법
대규모 모델의 훈련 속도 높임
3-1. 모멘텀 최적화
- 이전 그레디언트가 얼마였는지가 중요
- 그래디언트를 가속도로 사용
(이때, 모멘텀이 넘 커지는 것을 막기 위해 beta 하이퍼 파라미터 사용) - 일반적인 모멘텀 값은 0.9
optimizer = keras.optimizers.SGD(lr=0.001, momentum=0.9)
3-2. 네스테로프 가속 경사
- 모멘텀 최적화의 변종으로 기본 모멘텀 최적화보다 훈련 속도가 빠름
- 원래 위치보다 그 방향으로 조금 더 나아가서 측정한 그레디언트를 계산
optimizer = keras.optimizer.SGD(lr=0.001 momentum=0.9, nesterov=True)
3-3. AdaGrad
- learning rate 값을 조절
- 가장 가파른 차원을 따라 그레디언트 벡터의 스케일을 감소
- 즉, 학습률을 감소(학습률이 너무 작으면 학습 시간 오래 걸림 & 학습률이 너무 크면 발산하는 문제 해결)
- 심층 신경망에서 사용 X
3-4. Adam
- 모멘텀 최적화 + RMSProp
- (모멘텀) 지난 그레디언트 지수 감소 평균 & (RMSProp) 지난 그레디언트 제곱의 지수 감소된 평균
- 학습률 하이퍼파라미터 튜닝할 필요 X
optimizer = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999)
3-5. 학습률 스케줄링
- 일정한 학습률이 아닌 훈련하는 동안 학습률을 감소시키는 전략
- 대표적으로
성능 기반 스케줄링
(ReduceLROnPlateau 콜백)
lr_scheduler = keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=5)
- 성능 기반 스케줄링은 valid_loss가 5번의 epochs동안 줄어들지 않으면 학습률에 0.5를 곱한다
4. 규제 기법
규제를 사용하면 과대적합을 피할 수 있다.
- 조기 종료, 배치 정규화
- 신경망에서 널리 사용되는 규제 기법들(l1&l2, dropout, ...)
4-1. l1 & l2 규제
l1 규제
- 희소모델 만들기 위해 사용
l2 규제
- 신경망의 연결 가중치를 제한
🖥 partial을 사용한 l2 규제
from functools import partial
RegularizedDense = partial(keras.layers.Dense,
activation='elu',
kernel_initializer='he_normal',
kernel_regularizer=keras.regularizers.l2(0.01))
model = keras.models.Sequeuntial([
keras.layers.Flatten(input_shape=[28,28]),
RegularizedDense(300),
RegularizedDense(100),
RegularizedDense(10, activation='softmax',
kernel_initializer='glorot_uniform')
])
- partial : 모든 은닉층에 동일한 매개변수 값을 반복하는 경우가 많을 때 코드 리팩터링 방법
4-2. 드롭아웃
- 심층신경망에서 가장 인기 있는 규제 기법
- 입력값의 작은 변화에 덜 민감해져서(이웃한 뉴런에 의존할 수 없도록) 더 안정적인 네트워크가 되기 위해 사용하는 규제 기법
- 매 훈련 스텝에서 각 뉴런이
임시적
으로 드롭아웃될 확률 p를 10% ~ 50% 사이로 지정 - 훈련이 끝난 후에 뉴런에 더는 드롭아웃 적용X
- 모델이 과대적합 되었을 때 드롭아웃 비율⬆️,
모델이 과소적합 되었을 때 드롭아웃 비율⬇️
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28,28]),
keras.layers.Dropout(0.2),
keras.layers.Dense(300, activation='elu',
kernel_initializer='he_normal'),
keras.layers.Dropout(0.2),
keras.layers.Dense(100, activation='elu',
kernel_initializer='he_normal'),
keras.layers.Dropout(rate=0.2),
keras.layers.Dense(10, activation='softmax')
])
Author And Source
이 문제에 관하여(11장. 심층 신경망 훈련하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@juliy9812/11장.-심층-신경망-훈련하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)