[CS231n 6강 정리본] Training Neural Networks I

2025. 11. 4. 23:01·Study/CS231n

Lecture 6 : Training Neural Networks I

 


0) Intro

이번 강의에서는 Neural Networks의 학습에 대해 다룰 것이다. 목차는 다음과 같다.

NN 학습을 시작할 때 필요한 기본 설정은 다음과 같다.
1. One time setup : activation functions, preprocessing, weight initialization, regularization, gradient checking
2. Training dynamics : babysitting the learning process, parameter updates, hyperparameter optimization
3. Evaluation : model ensembles


1) Activation Functions

데이터가 입력되면, FC나 CNN등을 이용해서 가중치와 곱한다. 그 후에 Activation Function을 거치게 된다.
이제 다양한 활성함수들에 대해 알아보자.
 

1-1) Sigmoid

Sigmoid는 각 입력을 받아서 그 출력은 [0, 1] 사이의 값이 되도록 하는 함수이다. number를 'squash'한다.
$\sigma(x) = \frac{1}{1 + e^{-x}}$
이러한 Sigmoid는 3가지 문제점을 가진다.

1. Saturated neurons "kill" the gradients (Vanishing Gradient)

만약 입력값 x가 매우 작은 값 또는 큰 값을 가질 경우, local gradient는 0에 가까운 값을 가지게 된다. 때문에 이후 Backpropagation을 진행하면서 점점 모든 gradient가 0으로 수렴하여 이후 파라미터 업데이트에 어려움을 겪게 된다.
 
2. Sigmoid outputs are not zero-centered
 
모든 입력값 $x_i$가 양수인 상황을 살펴보자.이 때 $x_i$는 가중치 $w_i$와 곱해지고, 그 합(+bias)은 활성함수를 통과하게 된다.
이 경우 $w_i$에 대한 gradient는 어떻게 될까? 결론부터 말하면, '모든' gradient의 부호가 동일하게 된다.

Backpropagation을 생각해보자. 우선 위쪽 레이어로부터 $\frac{dL}{df}$가 넘어올 건데, 이 값은 양수 또는 음수일 것이다.
그 다음으로 local gradient인 $\frac{df}{dw_i} = x_i$인데, 최종적으로 
$$\frac{dL}{dw_i} = \frac{dL}{df}  \frac{df}{dw_i} = \frac{dL}{df}  x_i$$
가 된다.  
따라서 $\frac{dL}{dw_i}$의 부호는 $\frac{dL}{df}$의 부호와 동일해진다. 즉, 모든 가중치에 대한 gradient가 같은 부호를 갖게 된다.

시그모이드에서만 이게 문제가 되는 이유는, 출력 범위가 항상 (0, 1)이라서 출력이 모두 양수이기 때문이다. 즉 다음 층의 입력 또한 항상 양수가 되어, 그 다음 층의 gradient 계산에서도 동일한 부호가 유지되기 때문이다.
 
그 결과, 가중치 업데이트 방향이 한쪽으로만 치우치게 되어 학습이 비효율적이고 수렴 속도가 느려지는 현상이 발생한다.
W에 대해 2개의 축으로 이루어졌을 때, 파란색 화살표가 최적의 가중치 업데이트 방향이라고 하자. 그러나 모든 gradient의 부호는 동일해지는 문제 때문에, 실제 업데이트는 빨간색 화살표처럼 지그재그 방향으로 움직이며 비효율적으로 수렴하게 된다.
 
이것이 바로 우리가 일반적으로 zero-mean data를 원하는 이유이다.
 
3. exp() is a bit compute expensive
하지만, 실제로 크게 문제는 아니라고 한다.
 

1-2) tanh

sigmoid랑 유사하지만, 가장 큰 차이를 뽑자면 범위가 [-1, 1]로 zero-centered라는 것이다.
이를 통해 sigmoid에서의 두 번째 문제는 해결되지만, 여전히 saturation 때문에 gradient가 소실된다. 
sigmoid보다는 조금 낫지만, 여전히 문제점이 있는 활성함수이다.
 

1-3) ReLU

ReLU는 적어도 입력 스페이스의 절반인 양의 값에서는 saturation되지 않는다는 장점이 있다.
또한 단순 max 연산이기 때문에 계산효율이 뛰어나다.
생물학적 타당성도 ReLU가 sigmoid보다 크다고 한다. 
 
이런 ReLU에도 문제가 있는데, 바로 ReLU는 zero-centered가 아니라는 것이다.
또한 음의 값에서는 여전히 saturation된다는 것이다.

x가 0보다 작거나 같을 때에는 gradient가 0이기 때문에, ReLU는 gradient의 절반을 죽여버린다. 
때문에 backpropagation 과정에서 gradient가 전달되지 않아 해당 뉴런의 가중치가 업데이트되지 않는다. 그 결과, 그 뉴런은 계속 0만 출력하게 되고, 더 이상 활성화되지 못하는 상태에 빠져버린다. 이 현상을 'Dead ReLU'라고 한다.

주로 잘못된 초기화 또는 학습률이 너무 클 때, 입력 데이터의 분포가 음수 쪽으로 치우쳐져 있을 때 이러한 현상이 발생한다고 한다.
 

1-4) leaky ReLU

leaky ReLU는 기존 ReLU와 유사하지만, 음수 영역에서 더 이상 0이 아니다. 
음수 영역에서도 기울기를 살짝 주게 되면서, 음수 영역에서도 saturation되지 않는다. -> dead ReLU 현상 발생하지 않음
또한 여전히 계산이 효율적이며, sigmoid나 tanh보다 수렴속도가 빠르다.

1-5) PReLU (Parametric Rectifier)

PReLU는 leaky ReLU와 유사한 형태를 가진다. 차이점은 음수 영역에서의 기울기가 alpha라는 parameter를 통해 결정된다는 것이다. alpha를 처음에 정해놓는 것이 아니라, backpropagation으로 학습시키는 것이다. 때문에 활성함수가 조금 더 유연해질 수 있다.
 

1-6) ELU (Exponential Linear Units)

ELU는 ReLU의 이점을 그대로 가져오면서, zero-mean에 가까운 출력값을 보인다.
하지만 Leaky ReLU와 비교해보면, ELU는 negative에서 또 다시 saturation된다. 
ELU의 주장은 이러한 saturation이 noise에 robust할 수 있다는 것이다. 
결론적으로 ELU는 ReLU와 Leaky ReLU의 중간 정도로 이해하면 된다. 
ELU는 saturation의 관점에서는 ReLU의 특성을 가지고 있고, zero-mean의 관점에서는 leaky-ReLU의 특성을 가지고 있다.
 

1-7) Maxout Neuron

지금까지 본 활성함수들과는 다르게, 입력을 받는 특정 기본형식을 미리 정의하지 않는다.
대신 아래와 같이 두 값중의 최댓값을 사용한다.

Maxout은 두 개의 선형함수를 취하기 때문에, ReLU의 일반화된 형태라고 할 수 있다.
Maxout은 선형이기 때문에 saturation되지 않으며, gradient가 죽지 않는다.
그러나 뉴런당 필요한 파라미터의 수가 2배이기 때문에, 연산량이 많다는 단점이 있다.
 

지금까지 다양한 활성함수를 살펴보았는데, 실제로 가장 많이 쓰는 것은 ReLU이다. 다만 learning rate를 조심스럽게 결정하라고 한다. 


2) Data Preprocessing

데이터를 전처리하는 가장 흔한 방법은 normalization이다. 
데이터의 모든 feature에 대해 평균을 빼서 zero-centered가 되도록 만들고, 그 후 차원마다 동일한 척도가 되도록 표준편차로 값을 나누는 것이다. normalization을 해주는 가장 큰 이유는 모든 차원이 동일한 범위 안에 있게 해서 전부 동등하게 기여하도록 하는 것이다.
ML에서는 PCA나 whitening같은 더 복잡한 전처리 과정도 있지만, 이미지에서는 단순히 zero-centered가 되도록 만드는 정도까지만 진행한다.
 
Q. normalization이 sigmoid problem을 해결할 수 있는가?
A. 단지 '첫 번째' 레이어에서만 해결할 수 있을 것이다. 처음에는 입력값이 zero-centered이기 때문에 문제가 없겠지만, 결국 다음 레이어부터는 똑같은 문제가 반복된다. 따라서 전처리가 sigmoid에서의 문제를 해결하기에는 충분하지 않다.


3) Weight Initialization

weight를 어떻게 초기화시켜야 하는지 알아보자.

위와 같은 Two Layer Neural Network를 예시로 보자. 맨 처음에는 어떤 초기 가중치들이 존재할 것이다. 그리고 gradient를 계산해서 가중치를 업데이트할 것이다.
 
Q. 만약 모든 가중치를 0 등의 같은 값으로 초기화한다면 어떻게 될까?
A. 입력이 뭐든 간에 모든 뉴런은 모두 다 같은 연산을 수행한다. 따라서 모든 뉴런의 출력이 완전히 동일하게 되며, gradient 또한 같아진다. 그럼 업데이트 후에도 각 뉴런의 가중치들은 결국 같은 값을 가지게 되는데, 이것은 우리가 원하는 결과가 아니다. 우리는 뉴런들이 서로 다르게 연산하기를 바란다. 즉, Symmetry Breaking을 바란다. 
즉, 각 뉴런이 서로 다른 feature를 학습하려면 가중치 초기값은 서로 달라야 한다. 그래야 backpropagation 중에 서로 다른 gradient를 받게 되고, 결국 가기 다른 역할을 학습할 수 있게 된다.
 
가중치 초기화의 첫번째 해결책은 '작은 랜덤값으로 초기화하는 것'이다. 예를 들어, W ~ N($0$, $(0.01)^2$)
이 경우 얕은 네트워크일 때는 잘 작동하지만, 깊은 네트워크에서는 문제가 생긴다.

이 예시는 10-layer MLP이다. 각 layer에 500개의 뉴런이 있으며, 활성함수로는 tanh를 사용했다. 
Forward pass를 할 때 각 층마다 W를 곱하게 되는데, W의 값이 작기 때문에 출력값 또한 작은 값이 나온다. 즉 layer가 깊어질 수록 각 층의 출력 분포가 점점 납작해져서 결국 0 근처에 몰리게 된다. 
Backward pass에서도 같은 현상이 나타난다. backpropagation을 진행할 때, 각 층의 gradient는 chain rule로 계산되는데 W가 작은 값이기 때문에 결국 gradient는 0으로 수렴하게 된다. (Vanishing Gradient Problem)
 
이제 가중치 초기화의 두번째 해결책인 '가중치를 큰 값으로 초기화하는 것'을 살펴보자. 예를 들어, W ~ N($0$, $1^2$)

큰 가중치를 통과한 출력 WX를 구하고, 이것이 tanh를 거치게 된다면 값들이 saturation될 것이다. 그렇게 되면 출력은 위의 이미지에서 볼 수 있듯이 항상 -1 또는 1일 것이다. 결론적으로는 gradient는 0이 될 것이고, 가중치 업데이트는 일어나지 않을 것이다.
 
위에서 언급한 두 해결책의 문제점을 요약하면 다음과 같다.
 

  • 가중치를 너무 작게 초기화하면
    → Forward pass에서 activation이 0에 수렴하고
    → Backward pass에서 gradient가 사라짐 (Vanishing Gradient)
  • 가중치를 너무 크게 초기화하면
    → activation이 Saturation 영역(tanh의 ±1 부근)에 머물러서
    → gradient 폭발(Exploding Gradient) 또는 0에 가까워짐

이를 통해 정할 수 있는 우리의 목표는, 각 레이어의 입력과 출력의 분산이 비슷하게 유지되도록 초기화하는 것이다.

3-1) Xaiver Initialization

이를 해결할 수 있는 초기화 방법 중 하나로는 2010년 Xavier Glorot이 제안한 Xaiver Initialization이 있다.
핵심 아이디어는 초기 가중치 W의 분산을 조절하는 것이다. 수식은 아래와 같다.
 
$$W_{ij} \sim \mathcal{N}(0, \frac{1}{n_{\text{in}}}), \quad n_{\text{in}} = \text{number of input units}$$
이렇게 하면 forward로 전파될 때도, backward로 gradient가 전파될 때도 분산이 일정하게 유지된다.

입력의 개수가 적으면 곱해지는 term이 적으니까 가중치를 크게 하고, 입력의 개수가 많으면 곱해지는 term이 많아 출력 분산이 너무 커지니까 가중치를 더 작게 하는 것이다.
 
그러나 이러한 Xaiver 초기화에도 한계가 있었는데, ReLU에서 잘 작동하지 않는다는 것이다.

입력의 절반 정도는 음수인데, ReLU를 거치면 출력이 0이 되기 때문이다. 즉, 평균적으로 출력의 분산이 절반으로 줄어들기 때문에 잘 작동하지 않는다. 그 결과 여전히 ReLU를 쓰면 activation 값이 점점 더 작아지고, 일부 뉴런이 완전히 비활성되어버리는 현상이 발생한다.

3-2) He Initialization

 

 
이 경우 He Initialization으로 해결 가능하다. 수식은 아래와 같다.
$$W_{ij} \sim \mathcal{N}(0, \frac{2}{n_{\text{in}}})$$
Xaiver 때와 달라진 것은 분산이 2배가 된 것뿐이다. ReLU는 절반만 활성화되므로, 절반만 보정한다는 아이디어이다.
 
현업에서는 이러한 작은 초기화 차이가 트레이닝에 있어서 엄청난 차이를 보인다고 한다. 따라서 초기화 분야는 여전히 활발하게 연구되는 분야라고 한다.


4) Batch Normalization

깊은 네트워크에서 층을 지날수록 활성값의 분산이 커지거나 작아져 학습이 불안정해지는 문제가 있었다. 이를 해결하기 위해 학습 시작 시점에 딱 한 번은 Xaiver / He Initialization을 이용하여 분산을 맞출 수 있으나, 학습이 진행되면 그 균형이 다시 무너질 수 있다는 문제점이 있다.
Batch Normalization(BN)의 아이디어는, 그렇다면 '각 Mini-batch의 평균과 분산을 이용해서 층의 입력이 unit gaussian이 되도록 강제하자'이다.

일반적으로는 FC/Conv -> BN -> 활성함수 순서로 BN을 사용한다. 활성함수에 들어가기 직전의 분포를 안정화해야, 비선형의 포화 영역에 과도하게 머무는 것을 줄이고 gradient 흐름을 원활하게 만들 수 있기 때문이다.

정규화만 하면, tanh를 기준으로 했을 때 항상 선형영역 근처로 몰려 포화(saturation)가 거의 안 일어난다.
하지만, 포화를 '얼마나' 허용할 지가 성능에 유리할 때도 있다고 한다. 따라서 아래와 같은 scaling 연산 또한 BN에 추가된다.

 
$\gamma$와 $\beta$는 weight처럼 일반적인 모델 파라미터이다. 초기화 후 backpropagation을 통해 loss function L에 대한 gradient가 계산되어 SGD 등으로 업데이트된다.
 
이러한 scaling 연산을 통해 네트워크가 '정규화의 강도'를 학습적으로 조절할 수 있게 된다. 그 뿐 아니라, 만약 네트워크가 BN이 불필요하다고 판단할 경우 위 이미지의 우측처럼 파라미터 값을 조정하여 원래 스케일로 복원할 수도 있다 (이런 경우는 보통 없긴 하다).

 
BN은 결론적으로 gradient의 흐름을 보다 원활하게 해주며, 학습이 더 잘 되도록(robust) 해준다.
Initialization 뿐 아니라 BN 까지 같이 사용하면 안정적이다.


5) Babysitting the Learning process 

지금까지는 네트워크 설계를 주로 다루었다. 이제는 학습과정을 어떻게 모니터링하고 하이퍼파라미터를 조절할 것인지 다뤄보자.
우선 데이터 전처리를 진행하고, 아키텍쳐를 선택한다.

그 이후, 네트워크를 초기화시킨다.
이 때 초기 loss가 reasonable한지 확인해보는 것이 중요하다.

클래스 수가 10일 경우, 가중치가 작은 값일 때 Softmax classifier의 Loss는 negative log likelihood 가 되어야 한다. 즉 -log(1/10)인 대략 2.3의 값이 나와야 한다. 이를 우선적으로 확인한다. 이후 regularization을 추가하면 Loss가 증가하는 것이 정상임으로, 이 또한 확인하면 좋다.
 
이제 학습을 시작해보자. 처음 시작할 때 가장 좋은 방법은 데이터의 일부만 우선적으로 학습시켜 보는 것이다.
이렇게 할 경우 데이터가 적기 때문에 Overfitting을 유도하여 Loss가 줄어드는 것을 확인할 수 있다. 즉 학습 루프가 제대로 돌아가는지를 빠르게 검증할 수 있다.

이제 본격적으로 학습을 시작하면 된다. 강의에서는 적절한 learning rate을 찾기 위해 1e-6부터 1e6등을 적용해보며, 그 과정에서 발생하는 문제점을 언급한다. 그 내용들을 바탕으로, 우리가 하이퍼파라미터를 어떻게 정해줘야 하는가? 에 대해 물어본다. 

6) Hyperparameter Optimization

하이퍼파라미터를 최적화시키고 그 중 가장 좋은 것을 선택하기 위해 취할 수 있는 한 가지 전략으로 Cross-Validation이 있다.
Cross-Validation은 training set으로 학습시키고 validation set으로 평가하는 방법이다. 우선 coarse stage에서는, 넓은 범위에서의 값을 골라낸 후 fine stage에서 더 좁은 범위를 설정하여 학습을 길게 시켜보며 최적의 값을 찾는다.

또 다른 방법으로는 Random Search와 Grid Search가 있다.

우선 Grid Search의 경우, 모델이 특정 파라미터(초록)의 변화에 더 민감하게 반응한다고 가정할 때 그 파라미터에 대해서 3개의 값 만 사용한다. 반면 Random Search의 경우 확률적으로 더 다양한 값을 샘플링할 수 있다. 그렇기 때문에 Random Search가 일반적으로 더 유리하다고 한다.

'Study > CS231n' 카테고리의 다른 글

[CS231n 5강 정리본] Convolutional Neural Networks  (0) 2025.10.29
[CS231n 4강 정리본] Backpropagation and Neural Networks  (0) 2025.10.27
[CS231n 3강 정리본] Loss Functions and Optimization  (0) 2025.10.23
[CS231n 2강 정리본] Image Classification  (0) 2025.10.13
[CS231n 1강 정리본] Introduction to CNN for Visual Recognition  (0) 2025.10.12
'Study/CS231n' 카테고리의 다른 글
  • [CS231n 5강 정리본] Convolutional Neural Networks
  • [CS231n 4강 정리본] Backpropagation and Neural Networks
  • [CS231n 3강 정리본] Loss Functions and Optimization
  • [CS231n 2강 정리본] Image Classification
입질하는 펠리컨
입질하는 펠리컨
Time Series Analysis | Anomaly Detection | Domain Adaptation
  • 입질하는 펠리컨
    입질하는 펠리컨
    입질하는 펠리컨
  • 전체
    오늘
    어제
    • All (31)
      • Paper Review (6)
      • Study (14)
        • ML | DL (5)
        • Multivariate Data Analysis (3)
        • CS231n (6)
      • Certificate (4)
      • Diary (7)
  • 링크

    • GitHub
    • velog
  • hELLO· Designed By정상우.v4.10.3
입질하는 펠리컨
[CS231n 6강 정리본] Training Neural Networks I
상단으로

티스토리툴바