가중치를 0으로 설정하면?

0을 가중치로 초기화 하면 모든 뉴런들이 같은 값을 나타내고, Back Propagation 과정에서 각 가중치가 동일한 값으로 Update된다.

이 Update는 학습을 진행하면서 계속 발생되고, 결국 모델은 제대로 학습되지 않는다. 또한 이렇게 동일한 값으로 Update 되는 것은 레이어를 여러 층으로 나눈 의미를 상쇄시킨다.

 

 

 


초기값 설정의 중요성

위의 표에서 초기값이 μ라면 Gradient Descent를 진행하면서 최종적으로 x에서 멈출 확률이 높습니다.

하지만 초기값이 z라면 y에 멈출 확률이 높아지게 됩니다.

이렇듯 초기값 설정에 따라서 local minimum에 빠질 수도 있는 문제가 발생하기도 합니다.

 

 

 


평균 0, 표준편차 1

그리고 데이터를 평균 0, 표준편차 1의 weights에 5개의 sigmoid 활성화 함수에 넣는다고 가정하겠습니다.

평균 0, 표준편차 1

왼쪽 사진은 데이터들이 평균 0, 표준편차 1인 weights에 5개의 sigmoid를 통과했을때의 분포입니다.

즉 오른쪽의 sigmoid 함수의 양끝에 데이터들이 몰려 있는 것입니다.

그렇다면 빨간 부분에서의 미분값은 0에 가까우므로 Gradient Vanishing 현상이 일어나게 됩니다.

 

 

 


평균 0, 표준편차 0.01

그렇다면 평균 0, 표준편차 0.01의 데이터를 살펴보겠습니다.

평균 0, 표준편차 0.01

표준편차가 1인 weights들과는 완전 다른 분포를 보입니다.

하지만 너무 한쪽으로 데이터들이 모여 있는게 문제가 됩니다.

값들이 치우쳐져 있다는 것은 다수의 뉴런이 거의 같은 값을 출력하고 있으니 여러개의 층을 구성한 이유가 없어집니다.

즉, 표현력이 제한됩니다.

또한, 가운데 부분은 linear한 부분이기 때문에 학습이 제대호 이루어지지 않습니다.

 

※ 참고사항 ※

여기서도 학습이 반복된다면 Gradient Vanishing 현상이 발생합니다!

왜냐하면 sigmoid의 가장 큰 미분값은 0.25이기 때문에 학습이 계속 된다면 Gradient Vanishing 현상 발생!

 

 

 


Xavier 초기값

위와 같은 문제들 때문에 초기값을 설정하는 방법이 나왔습니다.

대표적으로 Xavier (자비어) 초기값이 있습니다.

Xavier initialization

여기서 n_in은 입력 뉴련수, n_out은 출력 뉴런수 입니다.

즉, 평균은 0, 표준편차는 위의 식을 따르는 겁니다.

Xavier initialization

위의 표들보다 훨씬 보기 편해졌습니다.

이러한 분포를 가지고 있으면 위의 단점들을 완화 시켜 줍니다.

 

 

 


He 초기값

활성화 함수가 ReLU 일때 He initialization을 사용하면 Xavier 보다 성능이 좋다고 합니다.

He initialization

식들을 보면 간단간단 합니다.

He 초기값은 평균 0, 표준편차는 위의 식을 따릅니다.

He initialization

 

다음은 Batch Normalization에 대해 알아보겠습니다.

 

▼ 코드

더보기
import numpy as np
import matplotlib.pyplot as plt
from math import *


def sigmoid(x):
    return 1 / (1 + np.exp(-x))


def ReLU(x):
    return np.maximum(0, x)


if __name__ == '__main__':
    x = np.random.randn(1000, 100)      # 데이터
    node_num = 100                      # 각 은닉층의 노드(뉴런) 수
    hidden_layer_size = 5               # 은닉층 5개
    activations = {}                    # 활성화 결과 저장

    for i in range(hidden_layer_size):
        if i != 0:
            x = activations[i-1]
        # w = np.random.randn(node_num, node_num) * 1       # 표준편차 1
        # w = np.random.randn(node_num, node_num) * 0.01      # 표준편차 0.01
        # w = np.random.randn(node_num, node_num) * sqrt(1.0 / (node_num + node_num))       # Xavier
        w = np.random.randn(node_num, node_num) * sqrt(2.0 / node_num)      # He

        a = np.dot(x, w)
        z = sigmoid(a)
        # z = ReLU(a)
        activations[i] = z

    # 히스토그램 그리기
    for i, a in activations.items():
        plt.subplot(1, len(activations), i+1)
        plt.title(str(i+1) + "-layer")
        plt.xlim(0.1, 1)
        plt.ylim(0, 7000)
        if i != 0:
            ax = plt.gca()
            ax.axes.yaxis.set_ticks([])
        plt.hist(a.flatten(), 30, range=(0, 1))

    plt.show()

 

 

출처:

https://www.youtube.com/watch?v=LQ8Rm09jgAE&list=PLBiQZMT3oSxXNGcmAwI7vzh2LzwcwJpxU&index=6

'Deep Learning > deep learning' 카테고리의 다른 글

04_Max Pooling  (0) 2022.04.18
03_Batch Nomalization 배치 정규화  (0) 2022.04.06
01_Optimizer 설명 및 여러 기법들  (0) 2022.03.31
Conda 가상환경 파일로 옮기기  (0) 2022.01.11
Pytorch Conv Output_Size 계산  (0) 2021.06.14

+ Recent posts