[밑바닥부터 시작하는 딥러닝] #12 Xavier/He 초기값

Clay Ryu's sound lab·2022년 3월 24일
0

Note for 2022

목록 보기
24/47

가중치의 초기값 설정

sigmoid를 거친 affine층에서의 활성화값의 분포는 다음과 같다.

표준편차를 너무 크지도 너무 작지도 않은 값으로 설정하는 것이 중요하다.

표현력 제한

가중치의 값들이 너무 비슷해지면(표준편차가 지나치게 작아지면) 데이터의 정보를 담을 weight가 작아지게 된다.


2층의 affine층은 1층에서 나온 y1, y2, y3에 3w'를 그저 곱해주는 것과 동일하다. 이것은 layer의 forward과정에서 큰 변화가 없어진다는 것을 의미한다.




문제는 가중치의 초기값이 비슷해져버리면 forward 한 값들이 비슷해져서 이 값들을 이용하는 역전파를 해도 dw값들이 크게 바뀌지 않는데에 있다. 결국 w를 update해도 변화량이 작아져서 학습이 오래 걸리게 된다.

Vanishing Gradient Problem


은닉층이 많은 다층 퍼셉트론에서, 은닉층을 많이 거칠수록 전달되는 오차가 크게 줄어들어 학습이 되지 않는 현상이 발생하는데, 이를 기울기 소멸 문제라고 한다. sigmoid는 분포를 살펴보면 양 극단에 값들이 몰려있는데, 이 양극단의 접선의 기울기는 0에 가깝다. 기울기가 거의 0으로 소멸되어 버리면 네트워크의 학습은 매우 느려지고, 학습이 다 이루어지지 않은 상태에서 멈추게 된다. 이를 지역 최솟값에 도달한다고 표현하기도 합니다.

코드 구현

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))
    
def ReLU(x):
    return np.maximum(0, x)
    
def tanh(x):
    return np.tanh(x)
    
input_data = np.random.randn(1000, 100)
node_num = 100
hidden_layer_size = 5
activations = {}
x = input_data

for i in range(hidden_layer_size):
    if i != 0:
        x = activations[i-1]
    
    # 초기값을 바꿔가며 실험하자.
    w = np.random.randn(node_num, node_num) * 1
    # w = np.random.randn(node_num, node_num) * 0.01
    # LeCun 초기값이다.
    # w = np.random.randn(node_num, node_num) * np.sqrt(1.0 / nude_num)
    # w = np.random.randn(node_num, node_num) * np.sqrt(2.0 / nude_num)
    
    a = np.dot(x, w)
    
    # 활성화 함수도 바꿔가며 실험하자.
    z = sigmoid(a)
    # z = ReLU(a)
    # z = tanh(a)
    
    activations[i] = z
for i, a in activations.items():
    plt.subplot(1, len(activations), i+1)
    plt.title(str(i+1) + "-layer")
    if i != 0:
        plt.yticks([], [])
    # 100,000개를 30 등분한 histogram
    plt.hist(a.flatten(), 30, range=(0,1))
plt.show()

표준편차가 1일때
-sigmoid

-ReLU

-tanh

표준편차가 0.01일때
-sigmoid

-ReLU

-Tanh

LeCun / Xavier 초기값

sigmoid를 사용할때

표준편차가 LeCun, Xavier초기값, 루트 1 / node_num일때
-sigmoid

-ReLU

-Tanh

He 초기값

ReLU를 사용할때

표준편차가 He 초기값, 루트 2 / node_num일때
다만 이 코드는 튀는 초기 값이 극소수 있어서 xlim, ylim의 제한을 걸어 주었다.
-sigmoid

-ReLU

-Tanh

profile
chords & code // harmony with structure

0개의 댓글