일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- Optimizer
- SBERT
- Roberta
- 클래스 분류
- 다항분포
- 블루 아카이브
- 옵티마이저
- 블루아카이브 토픽모델링
- 원신
- 자연어 모델
- 조축회
- 트위치
- 데벨챌
- 피파온라인 API
- 개체명 인식
- 문맥을 반영한 토픽모델링
- 데이터리안
- 붕괴 스타레일
- CTM
- 포아송분포
- 데이터넥스트레벨챌린지
- 토픽 모델링
- Tableu
- KeyBert
- LDA
- BERTopic
- 구글 스토어 리뷰
- 코사인 유사도
- NLP
- geocoding
- Today
- Total
분석하고싶은코코
기울기(Gradient) - 소실과 폭주(Vanishing & Exploding) 본문
이번 포스팅에서는 딥러닝 모델을 설계할때 고려해야할 기울기(Gradient)에 관한 내용을 다뤄 보겠습니다.
기울기(Gradient)?
기울기는 모델 설계 과정에서 가중치에 대한 업데이트를 하는 과정에서 나오는 개념인데 이 기울기를 바탕으로 역전파 과정에서 가중치가 업데이틑하게 됩니다. 그런데 이 기울기가 항상 정상적인 값들이 나온다면 좋겠지만 그렇지 못합니다. 기울기가 점점 작아지다가 0으로 수렴해 소실되는 기울기 소실(Gradient Vansihing)문제와 반대로 기울기가 점점 커져 이게 가중치들에게 영향을 주어 너무 큰 값을 갖게 되는 폭주(Exploding)현상 두 가지가 발생할 수 있습니다. 이번 포스팅에서는 소실과 폭주에 대한 예시를 통해 발생하는 현상을 확인해보고 이를 방지하기 위한 방법들에 무엇이 있는지 살펴보도록 하겠습니다.
소실과 폭주(Vanishing & Exploding)
소실
우선 기울기 소실(Gradient Vanishing)에 대해서 먼저 다뤄보겠습니다. 기울기 소실을 이해하기 앞서 딥러닝 모델의 구조에 대해서 생각해볼 필요가 있습니다. 딥러닝 모델에는 하나의 층을 쌓는 것으로 모델의 표현력이 증가한다고 표현합니다. 그렇다면 딥러닝 모델이 학습하는 세세한 부분을 이해하기 어렵더라도 많은 층을 쌓는 것이 좋은 모델 설계일까요? 그렇지 않습니다. 불필요하게 많은 층을 쌓는 것은 기울기 소실의 문제를 발생시킬 수 있습니다. 이게 무슨 의미냐 하면 아래 그림과 같이 딥러닝 모델을 설계 했다고 한다면 모델이 훈련 과정을 통해 학습하는 역전파 과정에서 학습해야하는 층이 그 많큼 깊어집니다. (이 부분에 대해서 이해하기 위해서는 딥러닝의 역전파와 활성화 함수에 대한 이해가 필요합니다.) 따라서 층이 깊어질수록 과정에서 처음에 역전파로 보냈던 정보가 희미해지게 됩니다.
딥러닝 모델을 설계할때 층에 따른 활성화 함수(activation function)를 설정할 수 있음을 아시리라 생각합니다. 활성화 함수는 모델이 학습하는 과정 중 값이 너무 커지는 것을 방지, 혹은 결과 원하는 결과 형태를 얻기 위해 설정할 수 있습니다. 그런데 이 활성화 함수가 역전파 과정에서 기울기 소실의 문제를 발생시키는 요인중 하나가 됩니다. 활성화 함수 중 대표적으로 기울기 소실을 발생시키는 Sigmoid와 tanh함수에 대해서 이야기해보겠습니다.
우선 Sigmoid함수부터 살펴보겠습니다. 왼쪽은 활성화 함수로 설정하여 순전파과정에서 얻을 수 있는 값을 표현합니다. 당연히 0~1사이 값을 얻을 수 있게 됩니다. 오른쪽은 역전파 과정에서 사용될 Sigmoid함수의 미분 그래프 입니다. Sigmoid함수의 미분값중 가장 큰 값은 0.25로 작은 값에 해당합니다. 이렇게 작은 값이 역전파 과정에서 여러층을 거치면서 곱해진다면 어떻게 될까요? 당연히 0으로 수렴하는 결과가 나오게되고 이는 곧 출력층에서 역전파시킨 기울기의 소실 문제가 발생하게 됩니다.
다음은 하이퍼볼릭 탄젠트(tanh)함수 입니다. Sigmoid에 비해 다루는 값이 -1에서 1로 확장되어 2배의 범위로 좀더 많은 값을 다룰 수 있도록 하는 함수 입니다. 하지만 tanh함수 역시 미분을 통해서 나오는 값은 주어진 x값에 따라 낮은 값을 갖게되고 Sigmoid와 같이 층이 깊어질수록 그 역전파 과정에서 기울기 소실에 대한 문제가 동일하게 발생하는 문제점이 있습니다. 이를 해결하기 위해서 등장한 활성화 함수가 ReLU함수 입니다.
기본 ReLu함수의 형태는 왼쪽의 모양과 같습니다. 음수의 값은 0의 값을 갖는 형태를 취합니다. 이 ReLU함수의 미분형태는 오른쪽과 같은 음수일 경우 0 양수일 경우 1의 값을 고정적으로 갖는 형태로 만들어지게 됩니다. 이를 통해서 역전파가 이뤄진다면 Sigmoid와 tanh에서 발생한 기울기 소실에 대한 문제를 해결할 수 있게 됩니다. 그런데 ReLU역시 문제점은 존재합니다. 기본형태가 음수일 경우 0의 값을 반환하기 떄문에 미분값 역시 0의 값을 갖는데 이를 역전파 과정에서 사용하게되면 해당 뉴런은 죽어버립니다. 이렇게 할 경우 해당 뉴런은 다시 소생시킬 수 없다는 문제점이 발생하는데 이를 해결하기 위해 변형된 형태로 등장한 많은 함수들이 있는데 그 중 대표적인게 Leaky ReLU함수 입니다.
Leaky ReLU함수는 아래와 같은 형태로 음수일때 결과값이 매우 작은 값을 갖도록 설정합니다. 이를 통해 0으로 수렴하는 문제를 해결하고 ReLU함수에서 발생하는 뉴런이 죽는 현상을 방지합니다. 이러한 기울기 소실과 관련된 내용은 은닉층의 활성화 함수를 설정할때 중요하게 고려해야할 부분이라고 할 수 있겠습니다.
폭주
기울기 폭주를 방지하는 방법은 간단하게 클리핑(Clipping)하는 방법이 있습니다. 역전파 과정에서 기울기의 임계값을 설정하여 해당 값이 넘어간다면 설정한 임계값으로 값을 줄이는 설정을 통해 기울기 폭주를 방지할 수 있습니다. 이러한 기능은 Keras에서는 옵티마이저 설정을 통해서 손쉽게 설정할 수 있습니다.
그런데 이러한 기울기 소실과 폭주에 대한 문제를 활성화 함수 변경이나 임계값 설정을 통해서 방지해볼 수 있겠지만 그럼에도 발생할 수 있습니다. 그렇기에 추가적인 방법들을 통해서 이를 방지하는데 대표적인 방법은 가중치 초기화, 배치or층 정규화가 있습니다.
가중치 초기화
가중치 초기화는 기울기 소실과 폭주에 관한 문제에서 나아가 모델 학습 시간뿐 아니라 성능이 어떻게 나오는가에도 영향을 주는 요소입니다. 초기화된 가중치에 따라 모델의 성능이 다르게 나오는 경우가 존재합니다. 가중치를 초기화 하는 방법중 세이비어(Xavier)와 He 초기화 방법에 대해서 알아보겠습니다.
세이비어 초기화
세이비어 초기화는 이전 층의 뉴런 수와 다음 층의 뉴런의 수를 기준으로 가중치를 초기화 하는 방법입니다. 이 두 가지
값을 통해 균등분포 혹은 정규분포를 활용해 그 값을 구할 수 있는데 링크된 논문에서 제시하는 균등분포와 정규분포는 다음과 같은 조건을 만족하라고 제시하고 있습니다.
이러한 세이비어 초기화는 모든층을 고려한 초기화 방법이라고 할 수 있습니다. 반대로 이야기하면 설계한 모델 중 특정 층이 주목받을 만한 가중치를 초기화 하지 않는 방법이라고 말할 수 있습니다. 이는 S자 커브를 갖는 활성화 함수인 Sigmoid, tanh와 같은 모델에서 좋은 성능을 보인다고 알려져있고 ReLU와 같은 함수에서는 그에비해 좋지 못한 성능이 나와 이 경우 He초기화를 권장하고 있습니다.
He 초기화
He초기화는 균등분포, 정규분포를 사용한 방법까지 세이비어 초기화와 거의 비슷하지만 가장 큰 다른점 다음 층의 뉴런을 고려하지 않고 이전 층의 뉴런의 개수에 초점을 두고 설정한다는데 있습니다.
배치 정규화 & 층 정규화
해당 내용은 실제로 모델을 설계하는 과정에서 모델의 성능 향상을 위해 선택할 수 있는 좋은 방법들이기에 따로 두 정규화에 대한 포스팅을 통해 자세히 알아보고 이번 포스팅에서는 왜 정규화를 진행하고 어떻게 진행되는지에 대해서 간단하게만 이야기해보겠습니다.
정규화에 대한 이해를 하기 위해서는 내부 공변량에 대해서 이해할 필요가 있는데 간단하게 이야기하자면 기울기를 역전파 시켜 가중치를 업데이트하는 과정에서 각 층들의 분포의 변화가 일어나 이전에 진행했던 과정에서의 분포를 다음층에 적용하게 됐을때 문제가 발생할 수 있다는데 있습니다. 이를 해결하기 위한 방법으로 제시되었던 방법이 배치 정규화였다고 합니다. (실제로는 해당 부분을 해결하기에는 부적합하다는 반론이 제기되었는데 실제로 이 배치 정규화가 하지 않는 것과 비교해서는 모델의 학습에 도움이 된다는 부분에는 이견이 없다고 합니다.)
배치 정규화(Batch Normailization, BN)
배치 정규화는 층의 활성화 함수 이전에 진행되는 작업으로 정규화를 진행한 후 활성화 함수를 통해 다음 층으로 전달 된 값들이 만들어지게 되면 일정한 범위의 값들만 다음 층으로 전달되게 됩니다. 이러한 과정을 거치면서 얻는 효과는 다음과 같습니다.
- 은닉층에서 시그모이드, 하이퍼볼릭 탄젠트와 같은 S커브의 활성화 함수를 사용하더라도 기울기 소실 문제를 완화시킬 수 있다.
- 가중치 초기화에 덜 민감하다.
- 높은 학습률을 설정하여 보다 빠른 학습시간을 얻을 수 있다.
- 과적합 방지효과로 드롭아웃과 비슷한 효과를 얻을 수 있다. (단,두 개 모두 사용하는게 더 좋은 결과를 얻을 수 있다.)
- 모델의 성능과 학습과정에서 이점이 있을 수 있겠지만 데이터를 통해 모델로 예측값을 얻을 경우 계산해야할 요소(배치마다 평균과 분산을 계산)가 늘어나기 때문에 이에 따른 시간 증가의 단점이 있기에 이를 고려해 필요성에 대한 고민이 필요하다.
층 정규화(Layer Normailization, LN)
층 정규화는 배치 정규화의 방법이 반대로 적용되는 것인데 말로 설명하는것 보다는 그림으로 이해하는게 훨씬 이해하기 쉽습니다. 층 정규화는 실제로 BERT모델에도 적용된 방법으로 구조에 대한 이해를 위해서는 알아갈 필요성이 있는 개념입니다. 이번 포스팅은 기울기에 대한 이야기를 하기에 배치와 층 정규화에 대한 자세한 이야기는 다음번 포스팅을 통해서 다뤄보도록 하겠습니다.
래퍼런스
'머신러닝&딥러닝' 카테고리의 다른 글
QLoRA-Efficient Finetuning of Quantized LLMs (1) | 2024.01.24 |
---|---|
Pytorch - Error 정리 페이지 (0) | 2024.01.18 |
Tensorflow GPU사용하기 No colab (0) | 2023.09.13 |
Optimizer - OGD, SGD, RLS (0) | 2023.03.26 |
딥러닝에 대한 이해와 순전파, 역전파 직접 구현 (0) | 2023.03.23 |