[딥러닝 기초] 가중치의 초깃값
초기값을 0으로하면?
- 가중치의 초깃값을 무엇으로 설정하느냐가 신경망 학습의 성패를 가른다.
- 오버피팅을 억제해 범용 성능을 높이는 테크익을 가중치 감소라고 한다.
- 가중치 감소는 가중치 매개변수의 값이 작아지도록 학습하는 방법이다.
- 가중치 값을 작게 만들어서 오버피팅이 일어나지 않게 하는 것이다.
- 가중치를 작게 만들고 싶으면 초기값도 최대한 작은 값에서 시작하는게 정공법이다.
- 초기값을 0.01 과 같은 값을 두는데 초기값을 모두 0으로 하게 된다면 (가중치를 균일한 값으로 설정) 한다면 오차역전파법에서 모든 가중치의 값이 똑같이 갱신되기 때문에 초기값을 0으로 하면 안된다.
- 예를 들어 2층 신경망에서 첫 번째와 두 번째 층의 가중치가 0이라고 가정할 때 순전파 때는 입력층의 가중치가 0이기 때문에 두 번째 층의 뉴런에 모두 같은 값이 전달된다.
- 두 번쨰 층의 모든 뉴런에 같은 값이 입력된다는 것은 역전파 때 두 번째 층의 가중치가 모두 똑같이 갱신된다는 뜻( 곱셉 노드의 역전파 )
- 그래서 가중치들은 같은 초기값에서 시작하고 갱신을 거쳐도 여전히 같은 값을 유지한다.
- 이는 가중치를 여러 개 같는 의미를 사라지게 한다.
- 이 가중치가 고르게 되어버리는 상황을 막으려면 (정확히는 가중치의 대칭적인 구조를 무너뜨리려면) 초깃값을 무작위로 설정해야한다.
은닉층의 활성화값 분포
- 은닉층의 활성화값(활성화 함수의 출력 데이터)의 분포를 관찰하면 중요한 정보를 얻을 수 있다.
- 가중치의 초깃값에 따라 은닉층 활성화 값들이 어떻게 변화하는지 간단히 알아보자.
- 구체적으로는 활성화 함수 시그모이드를 사용해서 5층 신경망에 무작위로 생성한 입력 데이터를 흘리며 각 층의 활성화 값 분포를 히스토그램으로 그려보려고 한다.
코드구현
# coding: utf-8
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) # 1000개의 데이터
node_num = 100 # 각 은닉층의 노드(뉴런) 수
hidden_layer_size = 5 # 은닉층이 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
# w = np.random.randn(node_num, node_num) * np.sqrt(1.0 / node_num)
# w = np.random.randn(node_num, node_num) * np.sqrt(2.0 / node_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([], [])
# plt.xlim(0.1, 1)
# plt.ylim(0, 7000)
plt.hist(a.flatten(), 30, range=(0,1))
plt.show()
- 층은 5개, 각 층의 뉴런은 100개
- 입력 데이터로서 1,000개의 데이터를 정 규분포로 무작위로 생성하여 이 5층 신경망에 흘린다.
- 활성화 함수로는 시그모이드 함수를 이용했고, 각 층의 활성화 결과를 activations 변수에 저장.
- 이 코드에서는 가중치의 분 포에 주의해야 한다.
- 이번에는 표준편차가 1 인 정규분포를 이용했는데, 이 분포된 정도(표준 편차)를 바꿔가며 활성화 값들의 분포가 어떻게 변화하는지 관찰하는 것이 이 실험의 목적이다.
- activations에 저장된 각 층의 활성화값 데이터를 히스토그램으로 그리면 아래와 같다.
-
- 각 층의 활성화 값들이 0과 1에 치우쳐 분포되어 있다.
- 여기에서 사용한 시그모이드 함수는 그 출력이 0이나 1에 가까우면 그 미분은 0에 다가간다.
- 그래서 데이터가 0과 1에 치우쳐 분포하게 되면 역전파의 기울기 값이 점점 작아지다가 사라진다.
- 이것이 기울기 소실이라 알려진 문제다.
- 층을 깊게 하는 딥러닝에서 기울기 소실은 더 심각한 문제가 될 수 있다
- 가중치의 표준편차를 0.01로 바꿔서 동일 조건으로 진행
-
- 이번에는 0.5 부근에 집중되어 있다.
- 앞의 예처럼 0과 1로 치우치진 않았고 기울기 소실 문제는 일어나지 않았다.
- 활성화 값들이 치우쳤다는 것은 표현력 관점에서 큰 문제가 있다는 건데 이 상황에서는 다수의 뉴런이 거의 같은 값을 출력하고 있으니 뉴런을 여러 개 둔 의미가 없어진다는 뜻이다.
- 예를 들어 뉴런 100개가 거의 같은 값을 출련한다면 뉴런 1개 짜리와 별반 다를 게 없다는 뜻이다.
- 그래서 활성화 값들이 치우치면 표현력을 제한 한다는 관점에서 문제가 된다.
- 각 층의 활성화 값은 적당히 고루 분포 되어야 한다.
- 층과 층 사이에 적당하게 다양한 데이터가 흐르게 해야 신경망 학습이 효율적으로 이뤄지기 때문이다.
- 반대로 치우친 데이터가 흐르면 기울기 소실이나 표현력 제한 문제에 빠져서 학습이 잘 이뤄지지 않는 경우가 생긴다.
Xavier 초기값
- 일반적인 딥러닝 프레임워크들이 표준적으로 사용하고 있다.
- 논문에서는 각 층의 활성화 값들을 광범위하게 분포시킬 목적으로 가중치의 적절한 분포를 찾고자 했다
- 앞 계층의 노드가 n 개라면 표준편차가 인 분포를 사용하면 된다는 결론을 이끈다.
- Xavier 초깃값을 사용하면 앞 층에 노드가 많을수록 대상 노드의 초깃값으로 설정하는 가중치가 좁게 퍼진다.
- 다음은 Xavier 초깃값을 쓴 결과다.
-
- Xavier 초기값을 사용한 결과를 보면 층이 깊어지면서 형태가 어느정도 일그러지긴 하지만 앞에와는 다르게 확실히 넓게 분포됨을 알 수 있다.
- 각 층에 흐르는 데이터는 적당히 퍼져 있고 시그모이드 함수의 표현력에 제한받지 않고 효율적으로 학습이 이뤄질 수 있다.
- 하지만 오른쪽으로 갈수록 약간씩 일그러지고 있다.
- 이 일그러짐은 sigmoid 함수 대신 tanh 함수(쌍곡선 함수)를 이용하면 개선된다.
- tanh 함수도 sigmoid 함수와 같은 ‘S’자 모양 곡선 함수다.
- 다만 tanh 함수는 원점 (0,0)에서 대칭인 S 곡선인 반면 Sigmoid는 (x,y) = (0,0.5) 에서 대칭인 S 곡선이다.
-
활성화 함수용으로는 원점에서 대칭인 함수가 바람직하다고 알려져있다.
- 밑에는 동일조건에서 넘파이에 내장된 np.tanh() 함수를 썼을 때 모양이다.
-
- 탄젠트 함수는 대부분 0에 치우쳐져있지만 꽤 넓게 분포되어 있다.
- 그렇다면 층을 2배로 늘린 은닉층을 10개로 만들면 어떻게 될까?
-
- 층이 깊어질 수록 0에 치우치는 걸 확인할 수 있다.
- 0에 가까울수록 미분 값은 0에 가까워지면서 역전파의 기울기 값이 점점 작아지다가 사라지기 때문에 기울기 소실문제에서 자유롭지 못 할 수 있다는 걸 확인할 수 있다.
ReLU를 사용할 때의 가중치 초깃값
- Xavier 초깃값은 활성화 함수가 선형인 것을 전제로 이끈 결과다.
- Sigmoid 함수나 tanh 함수는 좌우 대칭이라 중앙 부근이 선형인 함수로 볼 수 있다.
- 따라서 Xavier 초깃값이 정당한 반면 ReLU를 이용할 때는 ReLU에 특화된 초깃값을 이용하라고 권장된다.
- 이는 He 초깃값이라고 한다. 표준편차가 인 정규분포를 사용한다.
- ReLU는 음의 영역이 0이라서 더 넓게 분포시키기 위해 2배의 계수가 필요하다고 해석된다.
가중치 초깃값을 표준편차 0.01인 정규분포로 사용했을 때
Xavier 초깃값을 사용했을 때
He 초깃값을 사용했을 때
- 결과를 보면 std= 0.01 (가중치) 에 가까울 때 각 층의 활성화 값들은 아주 작은 값들이다.
- 신경망에서 아주 작은 데이터가 흐른다는 것은 역전파 때 가중치의 기울기 역시 작아진다는 뜻이다.
- 이는 중대한 문제로 실제로도 학습이 거의 이뤄지지 않는다.
- Xavier 초깃값은 층이 깊어지면서 치우침이 조금씩 커진다.
- 실제로 층이 깊어지면 활성화 값들의 치우침도 커지고 학습할 떄 기울기 소실 문제를 일으킨다.
- 마지막으로 He 초깃값은 모든 층에서 균일하게 분포되어 있다.
- 층이 깊어져도 분포가 균일하게 유지되기에 역전파 때도 적절한 값이 나올 수 있다.
활성화 함수로 ReLU를 사용할 때는 He 초깃값을 sigmoid나 tanh 등의 S 자 곡선일 때는 Xavier 초깃값을 쓰는게 모범사례라고 한다.
라고 책에는 나와있지만 동일 조건에서 아까 사용했던 tanh 함수에 He 초깃값을 사용하면 더 좋은 결과가 나온다.
- 층을 늘려도 골고루 분포된다.
-
은닉층이 더 늘어난다면?
- 은닉층을 좀 더 깊게 만든다면 책에서 나온데로 나올까?
- 밑에는 은닉층 30개 tanh 함수 He 초깃값
- 밑에는 은닉층 30개 ReLU 함수 He 초깃값
-
- 층이 깊어질수록 약간 왼쪽으로 치우친다.
- 조건을 다르게 하고 문제에 따라서 어떻게 쓰냐에 따라서 다 다르겠지만 일단 다 의심하고 직접 해보는게 제일 좋은거 같다.
선형함수의 조건
-
1.선형성 (Linearity) : 함수의 값이 변할 때, 그 변화량이 입력 값의 변화량에 비례하여 변화 즉, 함수가 직선이라는 의미
-
2.동차성 (Homogeneity) : 함수의 입력 값에 상수를 곱한 경우, 함수의 출력 값도 그 상수와 같은 비율로 변화한다. 즉, 입력 값의 크기에 비례하여 출력 값의 크기도 변화한다.
수식
- 선형성(Linearity) : f(x+y) = f(x) + f(y) f(ax) = af(x)
- 동차성(Homogeneity) : f(ax) = af(x)
여기서, x와 y는 임의의 입력 값이며, a는 임의의 상수 f(x)는 함수의 출력 값
ReLU가 비선형인 이유
ReLU(Rectified Linear Unit) 함수는 비선형 함수다. 이는 ReLU 함수가 입력 값에 대해 선형적인 반응을 보이지 않기 때문
선형 함수는 입력 값에 따라 그 출력 값이 직선으로 변한다. 즉, 입력 값이 증가하면 출력 값도 비례하여 증가하며, 입력 값이 감소하면 출력 값도 비례하여 감소한다.
반면, ReLU 함수는 입력 값이 0보다 작을 때는 출력 값이 0이 되고, 입력 값이 0보다 큰 경우는 입력 값 그대로를 출력한다. 이러한 함수의 특성은 입력 값이 증가하더라도 출력 값이 증가하지 않고, 0부터 시작하여 양수 값만 증가하게 된다. 따라서 ReLU 함수는 비선형 함수이며, 입력 값의 변화에 따라 출력 값이 비선형적으로 변화한다.
또한, ReLU 함수는 입력 값이 0보다 작을 때 그 경사도(기울기)가 0이 되기 때문에, 비선형 함수의 한 종류인 piecewise-linear function으로 분류된다. 이러한 비선형 함수의 사용은 딥러닝 신경망에서 중요한 역할을 한다.
출처 : 밑바닥부터 시작하는 딥러닝
댓글남기기