TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 딥러닝, 신경망>

[딥러닝] 심층 신경망 훈련 - 1

by 기록자_Recordian 2024. 11. 23.
728x90
반응형
인공 신경망

[딥러닝] 인공 신경망(ANN)

머신러닝 기반 분석 모형 선정  [머신러닝] 머신러닝 기반 분석 모형 선정머신러닝 기반 분석 모형 선정   지도 학습, 비지도 학습, 강화 학습, 준지도 학습, 전이 학습 1) 지도 학습: 정답인 레

puppy-foot-it.tistory.com


퍼셉트론(perceptron), 다층 퍼셉트론 (MLP)

[딥러닝] 인공 신경망: 퍼셉트론, 다층 퍼셉트론

머신러닝 기반 분석 모형 선정 [머신러닝] 머신러닝 기반 분석 모형 선정머신러닝 기반 분석 모형 선정   지도 학습, 비지도 학습, 강화 학습, 준지도 학습, 전이 학습 1) 지도 학습: 정답인 레이

puppy-foot-it.tistory.com


이전 내용

[딥러닝] 신경망 하이퍼파라미터 튜닝하기

인공 신경망 [딥러닝] 인공 신경망(ANN)머신러닝 기반 분석 모형 선정  [머신러닝] 머신러닝 기반 분석 모형 선정머신러닝 기반 분석 모형 선정   지도 학습, 비지도 학습, 강화 학습, 준지도 학

puppy-foot-it.tistory.com


심층 신경망 훈련

 
◆ 심층 신경망(Deep Neural Network, DNN)
 
[인공 신경망 실습을 통해 알게 된 두 가지]
1. 퍼셉트론은 인간의 뉴런을 모방한 '인공신경망'이다.
2. 다층 퍼셉트론은 퍼셉트론을 직렬로, 병렬로 연결하여 1개 이상의 은닉층을 가진 구조이다.

 
XOR문제, 기울기 소실 문제 등으로 인공신경망의 인기는 빠르게 식어갔다. 그러다 2006년 인공신경망 대신 심층 신경망(Deep Neural Network, DNN)이라는 용어가 사용되기 시작했습니다. 가중치 초기화 설정, ReLU 함수, 컴퓨터 성능 발전 등 다양한 방법으로 기울기 소실의 문제를 어느정도 해결하였다고 한다.

다층 퍼셉트론에서 은닉층을 많이 늘린 구조를 심층 신경망이라고 말할 수 있는데, 일반적으로 은닉층이 3개 이상인 구조를 심층 신경망이라고 하며, 이러한 심층 신경망을 이용하여 컴퓨터가 문제를 해결하는 과정을 딥러닝(Deep learning)이라고 한다. 즉 딥러닝은 컴퓨터가 데이터를 스스로 학습하여 문제를 해결하는 머신러닝(Machine learning) 방법 중 하나이다.
 
[심층 신경망 훈련 중 마주할 수 있는 문제들]
수백 개의 뉴런으로 구성된 10개 이상의 층을 수십만 개의 가중치로 연결해 훨씬 더 깊은 인공 신경망을 훈련한다고 생각해보면, 심층 신경망을 훈련하는 것은 쉬운 일이 아니며, 훈련 중에 아래와 같은 문제를 마주할 수 있다.

  • 심층 신경망의 출력 층에서 멀어질수록 그레이디언트가 점점 더 작아지거나 커지는 문제가 나타날 수 있으며, 두 문제 모두 하위 층을 매우 훈련하기 어렵게 만든다.
  • 대규모 신경망을 위한 훈현 데이터가 충분하지 않거나 레이블을 만드는 작업에 비용이 너무 많이 들어갈 수 있다.
  • 훈련이 극단적으로 느려질 수 있다.
  • 수백만 개의 파라미터를 가진 모델은 훈련 세트에 과대적합될 위험이 매우 크며, 특히 훈련 샘플이 충분치 않거나 잡음이 많은 경우에는 과대적합 될 확률이 더 크다.

해결책1 - 그레이디언트를 안정화 시키는 방법

 
1. 그레이디언트 소실과 폭주 문제

  • 그레이디언트 소실(Gradient Vanishing): 역전파 과정에서 입력층으로 갈수록 기울기가 점차적으로 작아지는 현상. 경사 하강법이 하위 층의 연결 가중치들이 제대로 업데이트 되지 않아 최적의 값을 찾지 못하게 된다. 기울기 소실문제는 신경망의 활성화 함수의 미분 결과 값(도함수 값)이 계속 곱해지면서 가중치에 따른 결과값의 기울기가 0이 되어 경사하강법을 이용할 수 없게 된다.
  • 그레이디언트 폭주(Gradient Exploding): 기울기가 점차 커져 가중치들이 비정상적으로 큰 값이 되어 발산되어 최적의 값을 찾지 못하는 현상. 순환 신경망(RNN)에서 주로 나타난다.

일반적으로 불안정한 그레이디언트는 층마다 학습 속도가 달라질 수 있기 때문에 심층 신경망 훈련을 어렵게 만든다.
2000년 초까지 심층 신경망을 훈련할 때 그레이디언트를 불안정하게 만드는 명확한 원인을 찾지 못해 방치되다가 2010년에 그동안 많이 사용됐던 로지스틱 시그모이드 활성화 함수와 가중치 초기화 방식(평균이 0이고 표준 편차가 1인 정규 분포)의 조합을 사용했을 때 각 층에서 출력의 분산이 입력의 분산보다 더 크다는 것이 논문(글로럿과 벤지오 저)을 통해 밝혀졌다.
 
아래의 시그모이드 활성화 함수를 보면 입력이 커지면 0이나 1로 수렴해서 기울기가 0에 가까워지는 것을 알 수 있다.

그래서 역전파가 될 때 사실상 신경망으로 전파할 그레이디언트가 거의 없고, 조금 있는 그레이디언트는 최상위 층에서부터 역전파가 진행되면서 점차 약해져서 실제로 아래쪽 층에는 아무것도 도달하지 않게 된다.
 
1-1. 글로럿과 He 초기화
 
◆ 글로럿 초기화

  • 주요 목표: 입력값이 계층을 통과하면서 너무 작아지거나 커지지 않도록 함.
  • 사용 사례: Sigmoid나 Tanh, 소프트맥스 활성화 함수를 사용할 때 적합.
  • 장점: 입력값과 출력값의 분산을 유지해 학습 초기에 기울기 소실(vanishing gradient) 문제를 완화.

◆ He 초기화

  • 주요 목표: ReLU(ReLU 계열 활성화 함수 포함)를 사용할 때 기울기 소실 문제를 더 효과적으로 해결.
  • 사용 사례: ReLU 또는 Leaky ReLU, ELU, GELU, Swish, Mish와 같은 활성화 함수를 사용할 때 적합.
  • 장점: ReLU 활성화 함수가 가지는 비대칭적인 특성(음수는 0으로 바뀜)을 반영해 초기화.

케라스는 기본적으로 균등 분포의 글로럿 초기화를 사용한다.
층을 만들 때 kernel_initializer='he_uniform' 이나, 'he_normal'로 바구어 He 초기화를 사용할 수 있다.

dense = tf.keras.layers.Dense(50, activation="relu",
                              kernel_initializer="he_normal")

 
또는 다른 초기화 방법을 위해 VarianceScaling 을 사용할 수 있다.
아래는 균등 분포의 팬-인 대신 팬-아웃을 기반으로 He 초기화를 사용한 예제이다.

he_avg_init = tf.keras.initializers.VarianceScaling(scale=2., mode='fan_avg',
                                                     distribution='uniform')
dense = tf.keras.layers.Dense(50, activation='sigmoid',
                              kernel_initializer=he_avg_init)

 
※ 팬-인: 어떤 모듈을 제어(호출)하는 모듈의 수. 하나의 모듈이 제어받는 상위 모듈의 수. 게이트가 수용할 수 있는 최대 입력의  수
팬-아웃: 어떤 모듈어 의해 제어(호출)되는 모듈의 수. 하나의 모듈이 제어하는 하위 모듈의 수. 출력 단자에 접속하여 신호를 추출할 수 있는 최대 허용 출력 수
▶ 시스템 복잡도 최적화를 위해서는 팬인은 높게, 팬아웃은 낮게 설계해야 한다.


2. 고급 활성화 함수
 
[ReLU 활성화 함수]
앞서 언급한 논문에 의하면, 활성화 함수를 잘못 선택하면 자칫 그레이디언트의 소실이나 폭주로 이어질 수 있으며, 시그모이드 활성화 함수가 아닌 다른 활성화 함수가 심층 신경망에서 훨씬 더 잘 작동한다는 사실이 밝혀졌다. 특히 ReLU 함수는 특정 양숫값에 수렴하지 않고 계산도 빠르다는 장점이 있다.
그러나 ReLU 함수는 완벽하지 않은데, 훈련하는 동안 일부 뉴런이 0 이외의 값을 출력하지 않는 죽은 ReLU 문제가 있다.

  • 특히 큰 학습률을 사용하면 신경망의 뉴런 절반이 죽어있기도 하고
  • 뉴런의 가중치가 바뀌어 훈련 세트에 있는 모든 샘플에 대해 ReLU 함수의 입력이 음수가 되면 뉴런이 죽게 된다
  • 가중치 합이 음수이면 ReLU 함수의 그레이디언트가 0이 되므로 경사 하강법이 더는 작동하지 않음.

위 문제들을 해결하기 위해 ReLU 함수의 변형을 사용한다.
 
2-1. LeakyReLU

- 특징

  • ReLU와 비슷하지만 음수 부분이 작은 기울기를 가진다.
  • ReLU의 변형으로, 입력 값이 음수일 때도 작은 기울기를 허용하여 "죽은 ReLU 문제(Dead ReLU)"를 완화.
  • ReLU에서 음수 값이 0으로 고정되는 반면, LeakyReLU는 음수 값에 대해 α 배만큼 감소하도록 설정.

-장점:

  • 기울기 소실 문제를 완화.
  • 계산이 간단해 효율적.

- 단점:

  • α 값은 일반적으로 고정되어 있으며, 최적의 값을 찾기 어려울 수 있음.

케라스는 tf.keras.layers 패키지 아래 LeakyReLU와 PReLU 클래스를 제공하며, 다른 ReLU 변형과 마찬가지로 He 초기화를 사용해야 한다.

leaky_relu = tf.keras.layers.LeakyReLU(alpha=0.2) # alpha의 기본값은 0.3
dense = tf.keras.layers.Dense(50, activation=leaky_relu,
                              kernel_initializer='he_normal')

 
원한다면 LeakyReLU를 별도의 층으로 모델에 추가할 수 있으며, 훈련과 예측의 차이는 없다.

model = tf.keras.models.Sequential([
    # [...]  # 다른 층
    tf.keras.layers.Dense(50, kernel_initializer="he_normal"),  # 활성화 함수 없음
    tf.keras.layers.LeakyReLU(alpha=0.2),  # 별도의 층으로 활성화 함수 추가
    # [...]  # 다른 층
])

 
PReLU를 사용하려면 LeakyReLU 클래스를 PReLU로 바꾸면 된다.

※ PReLU(parametric leaky ReLU) : a가 훈련하는 동안 학습되는 ReLU 활성화 함수.
* 학습 가능한 매개변수 (alpha) : PReLU는 ReLU와 다르게 입력이 음수인 경우에 0을 출력하는 것이 아닌, 학습 가능한 매개변수 alpha를 사용해서 음수 영역의 기울기를 조절할 수 있다. 이로 인해 음수 영역에서의 비선형성을 증가시킬 수 있다.
 * 죽은 ReLU 문제 해결 


ReLU, LeakyReLU, PReLU는 모두 도함수가 z=0에서 갑자기 바뀌어 매끄러운 함수가 아니다. 이런 종류의 불연속성은 경사 하강법을 최적점에서 진동하게 만들거나 수렴을 느리게 만들 수 있다.
 
2-2. ELU, SELU
 
◆ ELU
이 함수는 다른 모든 ReLU 변형의 성능을 앞지르고, 훈련 시간이 줄며, 신경망의 테스트 세트 성능도 높다.
 
- ReLU 함수와의 차이점(특징)

  • 음수 값이 지수 함수 형태로 감소하기 때문에 평균 출력값이 0에 가까워져 학습이 안정화됨.: z<0일 때 음숫값이 들어오므로 활성화 함수의 평균 출력이 0에 더 가까워지며, 이는 그레이디언트 소실 문제를 완화해준다. 하이퍼파라미터 a는 z가 큰 음숫값일 때 ELU가 수렴할 값의 역수를 정의하며, 보통 1로 설정하지만 다른 하이퍼파라미터처럼 변경할 수 있다.
  • 입력 값이 음수(z<0) 일 때도 작은 음수 값으로 출력이 유지되므로 ReLU보다 부드러운 비선형성을 가짐.
  • 입력 값이 음수 (z<0) 일 때도 그레이디언트가 0이 아니므로 죽은 뉴런을 만들지 않는다.
  • a=1 이면 이 함수는 z=0에서 급격히 변동하지 않으므로, z=0을 포함해 모든 구간에서 매끄러워 경사 하강법의 속도를 높여준다.

- 장점:

  • ReLU보다 죽은 뉴런 문제에 덜 민감.
  • 출력값이 0에 가까워지는 효과가 있어 학습 속도 개선.

- 단점:

  • 지수 계산으로 인해 계산 비용이 ReLU보다 높음.
  • 지수 함수를 사용하므로 ReLU나 그 변형들보다 계산이 느림.

케라스에서 ELU를 사용하려면 간단히 activation='elu'로 지정하면 되며, 다른 ReLU 변형과 마찬가지로 He 초기화를 사용해야 한다.

dense = tf.keras.layers.Dense(50, activation="elu",
                              kernel_initializer="he_normal")

 
◆ SELU (Scaled ELU)
이 함수는 스케일이 조정된 ELU 활성화 함수의 변형이며, 완전 연결 층만 쌓아서 신경망(MLP)을 만들고 모든 은닉 층의 SELU 활성화 함수를 사용한다면 네트워크가 자기 정규화 된다. 훈련하는 동안 각 층의 출력이 평균 0과 표준 편차 1을 유지하는 경향이 있어 그레이디언트 소실과 폭주 문제를 막아준다. 주로 자기 정규화 신경망(Self-Normalizing Neural Networks, SNNs)에서 사용된다.

 
- 장점:

  • 입력 분포를 자동으로 정규화해 학습 안정성을 높임.
  • 깊은 네트워크에서 효과적.

- 단점:

  • 다른 활성화 함수에 비해 상대적으로 적은 사용 사례.
  • 네트워크 구조와 데이터에 따라 성능 차이가 날 수 있음.

SELU 활성화 함수는 MLP에서 다른 활성화 함수보다 높은 성능을 내며, 이를 케라스에서 사용하려면 activation='selu'로 지정하면 된다.

dense = tf.keras.layers.Dense(50, activation="selu",
                              kernel_initializer="lecun_normal")

 
단, 자기 정규화가 일어나려면 아래의 조건이 필요하다.

  • 입력 특성은 반드시 표준화(평균0, 표준 편차 1)되어야 한다
  • 모든 은닉 층의 가중치는 르쿤 정규 분포 초기화로 초기화되어야 한다. 케라스에서는 kernel_initializer='lecun_normal'로 실행
  • 자기 정규화는 일반적인 MLP에서만 보장된다. 만약 순환 신경망이나 스킵 연결과 같은 다른 구조에 SELU를 사용하면 ELU 함수보다 성능이 뛰어나지 않을 것이다
  • 규제를 사용할 수 없다. (L1, L2, 맥스-노름, 배치 정규화, 드롭아웃 등)

[SELU를 사용한 자기 정규화된 네트워크의 예시]
SELU 활성화 함수를 사용하여 100개의 은닉층이 있는 패션 MNIST용 신경망을 생성해 본다.

tf.random.set_seed(42)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=[28, 28]))
for layer in range(100):
    model.add(tf.keras.layers.Dense(100, activation="selu",
                                    kernel_initializer="lecun_normal"))
model.add(tf.keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
              optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
              metrics=["accuracy"])

 
이제 모델을 훈련해 본다. (※ 입력값을 평균 0, 표준편차 1로 스케일링 해야 한다)

fashion_mnist = tf.keras.datasets.fashion_mnist.load_data()
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist
X_train, y_train = X_train_full[:-5000], y_train_full[:-5000]
X_valid, y_valid = X_train_full[-5000:], y_train_full[-5000:]
X_train, X_valid, X_test = X_train / 255, X_valid / 255, X_test / 255
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
               "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
pixel_means = X_train.mean(axis=0, keepdims=True)
pixel_stds = X_train.std(axis=0, keepdims=True)
X_train_scaled = (X_train - pixel_means) / pixel_stds
X_valid_scaled = (X_valid - pixel_means) / pixel_stds
X_test_scaled = (X_test - pixel_means) / pixel_stds
history = model.fit(X_train_scaled, y_train, epochs=5,
                    validation_data=(X_valid_scaled, y_valid))

▶ 신경망이 매우 깊은데도 학습에 성공했다.
 
이제 ReLU 활성화 함수를 대신 사용하면 어떤 일이 발생하는지 살펴본다.

model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=[28, 28]))
for layer in range(100):
    model.add(tf.keras.layers.Dense(100, activation="relu",
                                    kernel_initializer="he_normal"))
model.add(tf.keras.layers.Dense(10, activation="softmax"))
model.compile(loss="sparse_categorical_crossentropy",
              optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
              metrics=["accuracy"])
history = model.fit(X_train_scaled, y_train, epochs=5,
                    validation_data=(X_valid_scaled, y_valid))

▶  그레이디언트 소멸/폭주 문제로 인해 학습에 어려움을 겪는다.
 
 
2-3. GELU, Swish, Mish
앞서 언급한 ELU, SELU 활성화 함수는 제약이 크기 때문에 좋은 성능을 가지고 있음에도 큰 관심을 얻지 못했으며, GELU, Swish, Mish 활성화 함수가 대부분의 작업에 일관되게 더 나은 성능을 발휘한다.
 
 GELU
 
- 특징:

  • 입력값의 가우시안 확률 분포를 활용해 부드러운 비선형성을 제공.
  • Swish와 유사하지만, 더 세밀한 경계를 가짐.

- 장점:

  • ReLU 및 Swish보다 자연스럽고 부드러운 학습 가능.
  • 경사 하강법이 복잡한 패턴을 학습하기 쉬워 다른 활성화 함수보다 성능이 뛰어난 경우가 많음.
  • BERT와 같은 최신 NLP 모델에서 사용.

- 단점:

  • 계산량이 조금 더 많으며 성능 향상이 추가 비용을 정당화하기에 항상 충분하지는 않음.

케라스는 GELU를 지원하므로 activation='gelu'로 지정하면 된다.

dense = tf.keras.layers.Dense(50, activation="gelu",
                              kernel_initializer="he_normal")

 
 Swish
 
- 특징:

  • 입력 값이 음수일 때도 작은 값을 유지(음의 기울기 허용).
  • Sigmoid와 선형 함수의 조합으로 부드럽고 연속적인 비선형성 제공.

- 장점:

  • ReLU보다 성능이 좋을 때가 많음.
  • Google에서 개발되어 대규모 신경망 모델에서 효과를 입증.

- 단점:

  • 시그모이드 계산으로 인해 약간의 계산 비용 증가.
  • 데이터에 과대적합될 위험이 있음.

케라스는 Swish를 지원하므로 activation='swish'로 지정하면 된다.

dense = tf.keras.layers.Dense(50, activation="swish",
                              kernel_initializer="he_normal")

 
그러나 일반화된 Swish 활성화 함수는 지원하지 않는다.
 
 Mish
 
- 특징:

  • Swish와 유사하지만, tanh를 사용해 더 부드럽고 자연스러운 출력값을 생성.
  • 입력 값이 음수일 때도 적당히 작은 음수 값을 허용.

- 장점:

  • Swish보다 학습 성능이 개선될 때가 많음.
  • 비선형성이 자연스럽고, ReLU 기반 함수의 문제(예: 기울기 소실, 죽은 뉴런)를 완화.

- 단점:

  • 계산 비용이 더 높음.
  • 일부 모델에서만 효과적.

케라스는 Mish 활성화 함수는 아직 지원하지 않는다.
 


3. 배치 정규화(batch normalization)
ReLU 또는 다른 ReLU 변형 함수와 함께 He 초기화를 사용하면 훈련 초기 단계에서 그레이디언트 소실이나 폭주 문제를 크게 줄일 수 있지만, 훈련하는 동안 다시 발생할 가능성이 있다.
 
배치 정규화 기법은 딥러닝에서 학습 안정성과 속도를 개선하기 위해 사용되는 기법이다. 입력 데이터나 은닉층 출력을 정규화(normalization)하는 과정을 통해 학습 과정에서 발생할 수 있는 여러 문제를 완화할 수 있다.
 
배치 정규화 기법은 각 층에서 활성화 함수를 통과하기 전이나 후에 모델에 연산을 하나 추가하는 데, 이 연산은 단순하게 입력을 원점에 맞추고 정규화한 다음, 각 층에서 두 개의 새로운 파라미터로 결괏값의 스케일을 조정하고 이동시킨다. 두 개의 파라미터는 하나는 스케일 조정에, 다른 하나는 이동에 사용된다.
많은 경우 신경망의 첫 번째 층으로 배치 정규화를 추가하면 훈련 세트를 표준화할 필요가 없다. 즉, 배치 정규화가 StandardScaler나 Normalization 클래스의 역할을 대신한다.
입력 데이터를 원점에 맞추고 정규화하려면 알고리즘은 평균과 표준 편차를 추정해야 하며, 이를 위해 현재 미니배치에서 입력의 평균과 표준 편차를 평가한다.
 
훈련하는 동안 배치 정규화는 입력을 정규화한 다음 스케일을 조정하고 이동시킨다. 테스트 시에는 샘플의 배치가 아니라 샘플 하나에 대한 예측을 만들어야 하는데, 이 경우 입력의 평균과 표준 편차를 계산할 방법이 없으며, 샘플의배치를 사용한다 하더라도 매우 작거나 독립 동일 분포 조건을 만족하지 못할 수 있다. 또한, 이런 배치 샘플에서 계산한 통계는 신뢰도가 떨어진다.
한 가지 방법은 훈련이 끝난 후 전체 훈련 세트를 신경망에 통과시켜 배치 정규화 층의 각 입력에 대한 평균과 표준 편차를 계산하는 것이며, 예측할 때 배치 입력 평균과 표준 편차로 최종 입력 평균과 표준 편차를 대신 사용할 수 있다.
 
케라스의 BatchNormalization 층은 입력 평균과 표준 편차의 이동 평균을 사용해 훈련하는 동안 최종 통계 추정을 자동으로 수행한다.
 
[배치 정규화의 장점]
1) 기울기 소실/폭발 문제 완화

  • 딥러닝 모델이 깊어질수록 기울기 소실(vanishing gradient)이나 기울기 폭발(exploding gradient) 문제가 발생하기 쉬운데, 배치 정규화는 각 레이어의 출력값을 정규화하여 데이터 분포가 너무 작아지거나 커지지 않도록 유지한다.

▶ 결과적으로 기울기가 안정적으로 유지되며, 네트워크가 더 깊어지더라도 학습이 가능해진다.
 
2) 학습 속도 향상

  • 입력 데이터의 분포를 정규화하기 때문에 학습 속도가 크게 개선된다.
  • 기울기(gradient)가 더 잘 전달되어 수렴 속도가 빨라지고, 모델이 더 적은 에포크(epoch)로 학습할 수 있다.

▶  이는 학습 비용을 줄이고 계산 시간을 절약할 수 있다는 장점이 있다.
 
3) 초기화 의존성 감소

  • 가중치 초기화(weight initialization)에 덜 민감해진다.
  • 초기화가 잘못 설정되었더라도, 배치 정규화는 데이터의 분포를 조정해 학습이 가능하도록 돕는다.

▶ 이는 모델 설계를 단순화하며, 초기화 설정에 대한 부담을 줄인다.
 
4) 높은 학습률 사용 가능

  • 배치 정규화는 높은 학습률(learning rate)을 사용할 수 있도록 돕는다.
  • 높은 학습률을 사용하면 빠르게 수렴할 수 있지만, 과도한 학습률은 발산 문제를 일으킬 수 있다. 배치 정규화는 이러한 문제를 완화해 더 공격적인 학습률 설정이 가능하다.

5) 과적합(Overfitting) 방지 효과

  • 배치 정규화는 간접적으로 정규화 효과를 제공해 과적합을 방지한다.
  • 미니배치 크기(batch size)에 따라 정규화 통계가 다르게 계산되므로, 이는 드롭아웃(dropout)처럼 일종의 노이즈를 추가하는 역할을 한다.

▶ 드롭아웃과 함께 사용할 경우 시너지 효과를 낼 수 있다.
 
6) 활성화 함수 선택 유연성

  • 배치 정규화를 통해 신경망의 출력 분포를 정규화하면, 특정 활성화 함수에 의존하지 않아도 안정적으로 학습할 수 있다.
  • ReLU, Tanh, Sigmoid 등 다양한 활성화 함수와 함께 효과적으로 사용할 수 있다.

▶ 이는 모델 설계 시 활성화 함수 선택의 폭을 넓힌힌다.
 
7) 모델 일반화 성능 개선

  • 배치 정규화는 네트워크가 훈련 데이터에 과도하게 적합되지 않도록 하여 일반화 성능을 향상시킨다.
  • 이는 훈련 데이터와 테스트 데이터 모두에서 성능이 일관되게 유지되도록 돕는다.

[배치 정규화의 한계]

  • 미니배치 크기 의존성: 배치 크기가 너무 작을 경우 정규화 통계가 정확하지 않아 성능이 저하될 수 있다.
  • 추론 단계에서 추가 계산: 학습과 추론 과정에서 배치 정규화의 동작이 다르므로 추가적인 계산이 필요하다.

 
[케라스로 배치 정규화 구현하기]
배치 정규화 층도 다른 케라스 코드처럼 간단하고 손쉽게 구현할 수 있는데, 은닉 층의 활성화 함수 전이나 후에 BatchNormlization을 추가하면 된다. 모델의 첫 번째 층으로 배치 정규화 층을 추가할 수도 있다.
 
아래는 각 은닉 층 다음과 모델의 첫 번째 층으로 배치 정규화 층을 적용하는 모델이다.

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[28, 28]),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(300, activation='relu',
                          kernel_initializer='he_normal'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(100, activation='relu',
                          kernel_initializer='he_normal'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10, activation='softmax')
])

▶ 은닉 층 두 개를 가진 작은 예제이기 때문에 배치 정규화가 큰 도움이 되지 않을 수 있으나, 깊은 네트워크에서는 엄청난 차이를 만들 수 있다.
 

model.summary()

▶ 배치 정규화 파라미터의 전체 개수를 2로 나누면 이 모델에서 훈련되지 않는 전체 파라미터 개수를 얻는다. 여기서는 2,368개
 
첫 번째 배치 정규화 층의 파라미터를 살펴본다.

[(var.name, var.trainable) for var in model.layers[1].variables]

▶ 두 개는 역전파로 훈련되고 두 개는 훈련되지 않는다.
 
모델 작동 확인

# 모델 작동 확인
model.compile(loss="sparse_categorical_crossentropy",
              optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
              metrics=["accuracy"])
history = model.fit(X_train, y_train, epochs=2,
                    validation_data=(X_valid, y_valid))

 
[배치 정규화 추가 위치: 활성화 함수 이전 vs 이후]
 
배치 정규화 논문의 저자들은 활성화 함수 이후보다 활성화 함수 이전에 배치 정규화 층을 추가하는 것이 좋다고 조언하지만, 두 가지 방법 모두 실험해보고 어떤 것이 주어진 데이터셋에 가장 잘 맞는지 확인하는 것이 좋다.
활성화 함수 전에 배치 정규화 층을 추가하려면 은닉 층에서 활성화 함수를 지정하지 말고 배치 정규화 층 뒤에 별도의 층으로 추가해야 하며, 배치 정규화 층은 입력마다 이동 파라미터를 포함하기 때문에 이전 층에서 편향을 만들 수 있다. 층을 만들 때 use_bias=False로 설정하면 된다.
첫 번째 은닉 층이 배치 정규화 층 두 개 사이에 끼지 않도록 첫 번째 배치 정규화 층을 삭제할 수 있다.
 
업데이트 된 코드

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[28, 28]),
    tf.keras.layers.Dense(300, kernel_initializer='he_normal', use_bias=False),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Activation('relu'),
    tf.keras.layers.Dense(100, kernel_initializer='he_normal', use_bias=False),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Activation('relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

 
모델 작동 확인

# 모델 작동 확인
model.compile(loss="sparse_categorical_crossentropy",
              optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
              metrics=["accuracy"])
history = model.fit(X_train, y_train, epochs=2,
                    validation_data=(X_valid, y_valid))

 


4. 그레이디언트 클리핑
그레이디언트 폭주 문제를 완화하는 또 다른 방법은 역전파될 때 특정 임곗값을 넘어서지 못하게 그레이디언트를 잘라내는 그레이디언트 클리핑이 있다. 이 기법은 일반적으로 배치 정규화를 사용하기 어려운 까다로운 순환 신경망에서 사용된다.
 
케라스에서 그레이디언트 클리핑을 구현하려면 다음과 같이 옵티마이저를 만들 때 clipvalue와 clipnorm 매개변수를 지정하면 된다.

optimizer = tf.keras.optimizers.SGD(clipvalue=1.0)
model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizer)
optimizer = tf.keras.optimizers.SGD(clipnorm=1.0)
model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizer)

 
이 옵티마이저는 그레이디언트 벡터의 모든 원소를 -1.0과 1.0 사이로 클리핑한다. 즉, 훈련되는 각 파라미터에 대한 손실의 모든 편미분값을 -1.0에서 1.0으로 잘라내며, 임곗값은 하이퍼파라미터로 튜닝할 수 있다.
이 기능은 그레이디언트 벡터의 방향을 바꿀 수 있다.
만약 그레이디언트 클리핑이 그레이디언트 벡터의 방향을 바꾸지 못하게 하려면 clipvalue 대신 clipnorm을 지정하여 노름으로 클리핑 해야 한다. 훈련하는 동안 그레이디언트가 폭주한다면 다른 임곗값으로 값과 노름을 모두 사용하여 클리핑할 수 있으며, 이는 텐서보드를 사용해 그레이디언트의 크기를 추적할 수 있다. 그리고 검증 세트에서 어떤 방식이 가장 좋은 성과를 내는지 확인할 수 있다.


다음 내용

[딥러닝] 심층 신경망 훈련 - 2

인공 신경망 [딥러닝] 인공 신경망(ANN)머신러닝 기반 분석 모형 선정  [머신러닝] 머신러닝 기반 분석 모형 선정머신러닝 기반 분석 모형 선정   지도 학습, 비지도 학습, 강화 학습, 준지도 학

puppy-foot-it.tistory.com


[출처]
핸즈 온 머신러닝
고등학생을 위한 인공신경망과 딥러닝
딥 러닝을 이용한 자연어 처리 입문
IBM
https://iambeginnerdeveloper.tistory.com/188
https://post.naver.com/my.naver?memberNo=26040503
https://jaylala.tistory.com

 
 
 

728x90
반응형