[핸즈온 머신러닝] 11. 심층 신경망 훈련하기

박경민·2023년 5월 19일
0

[Hands-On Machine Learning]

목록 보기
16/23

심층 신경망은 다음과 같은 문제에 직면할 수 있다.

  • 그레디언트 소실, 그레디언트 폭주 문제
  • 데이터 불충분
  • 극단적으로 느린 훈련 속도, 과대적합

이제 다음과 같은 문제들을 알아보자.

  • 그레디언트 소실, 폭주와 해결
  • 전이학습과 비지도 사전훈련(unsupervised pretraining)
  • 최적화 방법들

11.1 그레디언트 소실과 폭주 문제

알고리즘이 하위층으로 진행될수록 그레디언트가 점점 작아지는 경우를 그레디언트 소실, 점점 커져서 가중치 갱신이 발산하는 경우를 그레디언트 폭주라고 한다.
➡️ 왜? 로지스틱 활성화함수와 가중치 초기화 방법 때문!

로지스틱 함수의 경우 0인 지점을 제외한 거의 모든 지점에서 기울기가 0에 가깝기 때문이다. 따라서 로지스틱을 미분하더라도 전파할 그레디언트가 거의 없고 가장 아래층에는 전파할 것이 거의 남아있지 않게 된다.

그레디언트 문제 해결

1 - 글로럿과 He 초기화

이렇듯 불안정한 그레디언트 문제를 다음과 같이 해결할 수 있다.

  • 신호가 폭주 혹은 소멸하지 않으려면 출력과 입력의 분산이 같아야 한다

  • 역방향에서 층을 통과하기 전과 후의 그레디언트 분산이 동일해야 한다

  • 각 층의 연결 가충치를 글로럿 초기화한다.

  • 다음은 글로럿 초기화의 방법이다. (fan 은 입력 또는 출력을 뜻한다, fan_in = fan_out 이고, 르쿤 초기화라 불리는 것의 경우 fan_in 만 포함)

  • 사용하는 활성화 함수에 따라 초기화 전략이 다르다.

2 수렴하지 않는 활성화 함수

  • ReLU 활성화 함수는 특정 양숫값에 수렴하지 않으므로 시그모이드보다 나았다

  • 그러나 ReLU는 0 출력이 많고, 그레디언트 0인 지점이 너무 많다.(모든 음수)

  • LeakyReLU는 ReLU의 변종, = max(ax, x) 정의되며 하이퍼파라미터 a가 leaky한 정도를 결정한다

  • 일반적으로 a = 0.01 로 설정하며, 함수가 절대 죽지 않게 만든다

  • RReLU는 훈련하는 동안 주어진 범위에서 a를 무작위로 선택, 테스트 시에 평균을 사용하는 방법이다.

  • 마지막으로 ELU 활성화 함수도 있다. 다른 어떤 변종보다도 성능이 좋았으며, 식은 다음과 같다.

  • 0보다 작아도 그레디언트가 0이 아니므로 죽은 뉴런을 만들지 않는다

  • 평균출력은 0 에 가까워진다 (그레디언트 소실 X)

3. 배치 정규화

위의 방법들 (연결 가중치, 활성화 함수)을 활용하여 문제를 해결할 수 있지만, 다른 한 가지 방법을 더 알아보자.

배치 정규화란 각 층에서 활성화 함수를 통과하기 전이나 후에 연산을 하나 새로 추가한다. 입력을 정규화한 다음, 두 개의 파라미터로 결과값의 스케일을 조정하는 것. 따라서 표준화할 필요가 없다. 알고리즘을 보자.

  1. 미니배치의 평균을 구하고
  2. 미니배치의 표준편차도 구하면
  3. 이를 이용해 각 샘플을 정규화할 수 있다 (-평균 / 표준편차)
  4. 정규화된 입력의 스케일을 조정하고 이동시킨다

실제로 구현을 위해선 코드에 keras.layers.BatchNormalization() 을 층마다 추가하면 된다.

  • 하이퍼파라미터 momentum 매개변수를 변경해야 할 때가 있다.

4. 그레디언트 클리핑

폭주 문제를 완화하는 한 가지 방법을 보자. 폭주가 문제일 땐 임곗값을 넘어서지 못하게 그레디언트를 잘라낼 수 있으며, 이를 그레디언트 클리핑이라고 한다.

구현은 다음과 같이 옵티마이저를 만드는 단계에서 clipvalue 매개변수를 지정하면 된다.

optimizer = keras.optimizers.SGD(clipvalue=1.0)

clipvalue=1.0 다음과 같이 주게되면 모든 편미분 값을 -1~1 사이로 클리핑한다.

11.2 사전 훈련된 층 재사용 하기

전이학습이란 해결하려는 것과 비슷한 유형의 문제를 처리한 신경망이 있는지 살펴본 다음, 신경망의 하위층을 재사용하는 방법을 말한다. 아래를 보자.

동물, 식물, 자동차, 생활용품 분류를 위해 쓰인 기존 DNN을 가지고 자동차 분류를 위한 DNN에 재사용할 수 있다.

1. 케라스를 사용한 전이 학습

  • 모델 A는 8개 클래스의 패션 MNIST 분류를 위한 모델이다
  • 작업 B는 셔츠와 샌들만 분류하는 모델이며 만들고자 하는 것이다
  • 현재 B는 전이를 사용하지 않고 만들어지 상태이나 전이를 사용하여 성능을 높인 model_B_on_A를 만들 것이다.
model_A = keras.models.load_model("my_model_A.h5")
model_B_on_A = keras.models.Sequential(model_A.layers[:-1])
model_B_on_A.add(keras.layers.Dense(1, activation="sigmoid"))

### A 영향을 가지않게 하기 위한 모델 복제 
model_A_clone = keras.models.clone_model(model_A)
model_A_clone.set_weights(model_A.get_weights())

다음은 몇 번의 에포크동안은 재사용 층을 동결하고 모델을 컴파일하는 것이다. (동결하는 이유는 데이터셋이 달라지므로 가중치를 망치게하지 않기 위함이며, 에폭을 몇 번 돈 후에 해제할 것이다.)

### 가중치 보존을 위해 재사용 층 동결 
for layer in model_B_on_A.layers[:-1]:
    layer.trainable = False

model_B_on_A.compile(loss="binary_crossentropy",
                     optimizer=keras.optimizers.SGD(learning_rate=1e-3),
                     metrics=["accuracy"])

에폭 4동안 훈련, 이후 동결을 해제하고 (이때 또다시 가중치 보존을 위해 최대한 학습률을 낮춰줘야 한다) 컴파일 한 후 다시 16에폭동안 훈련하자.

history = model_B_on_A.fit(X_train_B, y_train_B, epochs=4,
                           validation_data=(X_valid_B, y_valid_B))

for layer in model_B_on_A.layers[:-1]:
    layer.trainable = True

model_B_on_A.compile(loss="binary_crossentropy",
                     optimizer=keras.optimizers.SGD(learning_rate=1e-3),
                     metrics=["accuracy"])
history = model_B_on_A.fit(X_train_B, y_train_B, epochs=16,
                           validation_data=(X_valid_B, y_valid_B))

최종적으로 model_B_on_A.eavluate을 찍어보면 테스트 정확도가 높아진 것을 확인할 수 있다!

  • 그러나 전이학습은 완전 연결 네트워크의 경우 잘 동작하지 않는다. CNN 에서 더 잘 동작하는 전이학습은 후에 살펴보도록 하자!

2. 비지도 사전훈련

이번엔 비지도 사전훈련을 알아보자.

Unsupervised pretraining 이라는 것은 레이블된 훈련 데이터가 많지 않을 때 수행하는 것이다. 말그대로 레이블이 없는 데이터로 pretraining 한 다음, 지도학습으로 네트워크를 세밀하게 튜닝하는 것!

  • 한 층의 비지도 모델을 훈련
  • 1층은 동결, 층을 추가하고 훈련, 동결, 추가..

하는 방법을 사용했으나 최근에는 3 훈련 (입력 - 동결은닉1, 동결은닉2 - 은닉3)부터 시작한다.

3. 보조작업에서 사전 훈련

보조작업에서의 pretraining 이란 데이터를 쉽게 얻는 방법을 우선 택하고, 이 신경망의 하위층을 재사용하는 방법이다.

  • 얼굴을 인식하는 시스템을 만들 때 개인별 이미지가 없다면 무작위의 인물이미지를 수집해서 같은 사람 얼굴인지 감지 (1)
  • (1) 을 하위층으로 재사용해 적은 양의 데이터에서 얼굴을 잘 분류하는 모델 훈련 가능

자연어처리에서 많이 사용하는 기법!

profile
Mathematics, Algorithm, and IDEA for AI research🦖

0개의 댓글