on
[밑바닥딥러닝] 13. 모델 가중치의 초기화
[밑바닥딥러닝] 13. 모델 가중치의 초기화
본 게시글은 한빛미디어 『밑바닥부터 시작하는 딥러닝, 사이토 고키, 2020』의 내용을 참조하였음을 밝힙니다.
좋은 모델을 만들기 위해서는 모델 가중치를 처음에 적절히 설정하는 것이 중요하다.
가중치를 처음 초기화할 때 고르게 분포시키지 않고, 한쪽에 치우치게 하면 어떻게 될까?
표준편차를 1로 설정
위는 활성화 함수로 시그모이드 함수를 가진 모델의 가중치 초기화에 표준편차를 1로 설정했을 때
각 층에 나타난 저장된 활성화 값들을 나타낸다. 시그모이드 함수에 의해 0이나 1에 값이 쏠려있는데
학습 시 역전파의 기울기 값이 점점 작아지다 사라지는 기울기 소실 현상이 발생할 수 있다.
표준편차가 0.01
표준편차를 0.01로 작게 설정하면 위와 같이 된다. 대부분의 값이 0.5로 편중되어 있는데,
이 역시 모델의 표현력 관점에서 부정적인 현상이다.
Xavier, He 초기화
Xavier는 가중치의 값 초기화 때 이전 층의 노드 개수(n)의 루트값으로 가중치를 나누는 방법이다.
class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01, Xavier = False, He=False, l2=False, dropout=False): self.params = {} . . if Xavier: self.params['W1'] = (1 / np.sqrt(input_size)) * np.random.randn(input_size, hidden_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = (1 / np.sqrt(hidden_size)) * np.random.randn(hidden_size, output_size) self.params['b2'] = np.zeros(output_size)
Xavier 초기화를 사용하면 가중치 분포가 고르게 이루어져 모델의 높은 표현력을 기대할 수 있다.
기존 vs Xavier
위 그래프는 표준편차 0.01의 가중치 초기화 방식과 Xavier 초기화 방식의 정확도, 손실 그래프 비교이다.
두 가지 측면 모두에서 Xavier가 기존 방식보다 나은 성능을 보여준다.
He 초기화 방식은 Xavier 초기화의 아류이다. 활성화 함수인 ReLU 함수가 0 이하의 값들을 모두 0으로 만들기 때문에
이를 고려하여 Xavier보다 2배로 넓은 분포로 만드는 초기화 방식이다.
class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01, Xavier = False, He=False, l2=False, dropout=False): self.params = {} . . if He: self.params['W1'] = (2 / np.sqrt(input_size)) * np.random.randn(input_size, hidden_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = (2 / np.sqrt(hidden_size)) * np.random.randn(hidden_size, output_size) self.params['b2'] = np.zeros(output_size)
Xavier에서 곱하는 값이 1에서 2로 바뀐 것 뿐이다.
trainer = Trainer(optimizers, TwoLayerNet) trainer.train(iternum=10000, Xavier=True, He=False, l2=False, dropout=False) comparison = 'Xavier' plt.subplot(1,2,1) trainer.display_acc_chart(['train_acc('+comparison+')', 'test_acc('+comparison+')']) plt.subplot(1,2,2) trainer.display_loss_chart('train_loss('+comparison+')') regulation = 'He' trainer = Trainer(optimizers, TwoLayerNet) trainer.train(iternum=10000, Xavier=False, He=True, l2=False, dropout=False) plt.subplot(1,2,1) trainer.display_acc_chart(['train_acc('+regulation+')', 'test_acc('+regulation+')']) plt.subplot(1,2,2) trainer.display_loss_chart('train_loss('+regulation+')') plt.show()
Xavier와 He의 정확도/손실을 비교해보자.
Xavier vs He
He 초기화 방식이 xavier 포기화 방식에 비해서 더 나은 성능을 보이고 있다.
from http://humankind.tistory.com/63 by ccl(A) rewrite - 2021-10-16 20:26:38