💡 가중치 초기화
: 모델 초기 가중치 값을 설정
: 초기 가중치에 따라 모델을 최적화 하는 데 많은 어려움을 겪을 수 있음
💡 가중치 초기화 방법
1. 상수 초기화
- 가중치를 모두 같은 값으로 초기화
- 구현이 간단하고 계산 비용이 거의 들지 않음
- 대칭 파괴(Breaking Symmetry) 현상 발생
* 대칭 파괴
** 예를들어 가중치 값을 모두 0으로 할당하면 역전파 과정에서 모든 가중치가 동일한 값으로 갱신
- 스칼라값을 입력으로 받는 매우 작은 모델이나 퍼셉트론에 적용
- 주로 0 or 0.01등의 형태로 초기화
2. 무작위 초기화
- random 값이나 특정 분포 형태로 초기화
* Random, Unifom Distribution, Normal Distribution, Truncated Normal Distribution, Sparse Normal Distribution Initialization)
- 노드의 가중치 편향을 무작위로 할당해 네트워크가 학습할 수 있게 하여 대칭 파괴 문제 방지
- 계층이 적거나 하나만 있는 경우에는 보편적으로 적용가능
- 단, 계층이 깊어질 수록 활성화 값이 양 끝단에 치우치게 되어 기울기 소실(Gradient Vanishing) 현상 발생
3. 제이비어(Xavier Initialization) 초기화 (= 글로럿(Glorot Initializtion) 초기화)
- 균등 분포나 정규 분포를 사용하여 가중치 초기화
- 각 노드의 출력 분산이 입력 분산과 동일하도록 가중치 초기화
- 은닉층의 노드 수에 따라 다른 표준편차를 할당 ( 확률 분포 초기화 방법과 다름 → 같은 표준편차 할당 )
- 이전 계층의 노드 수와 다음 계층의 노드 수에 따라 표준편차 계산
- Sigmoid , Hyperbolic Tanh 를 활성화 함수로 사용하는 네트워크에 효과적
4. 카이밍(Kaiming Initialization) 초기화 (= 허 초기화 (He Initialization))
- 제이비어 초기화에서 발생한 문제점 보완
- 균등 분포 또는 정규 분포를 사용해 가중치 초기화
- Forward 신경망 네트워크에서 가중치를 초기화 할 때 효과적
- 현재 계층의 입력 뉴런 수를 기반으로만 가중치 초기화
- 노드의 출력 분산이 입력 분산과 동일하도록 가중치 초기화하여 ReLU함수의 죽은 뉴런(Dead Neuron) 문제를 최소화
*죽은 뉴런(Dead Neuron) : 가중치 합이 음수가 되는 순간 가중치를 0만 반환하는 문제
- ReLU 함수를 활성화 함수로 사용하는 네트워크에 효과적
5. 직교 초기화 (Orthogonal Initializtion)
- 특잇값 분해(SVD)를 활용해 자기 자신을 제외한 나머지 모든 열, 행 벡터들과 직교이면서 동시에 단위 벡터인 행렬을 만드는 방법
- 직교행렬의 고윳값의 절댓값은 1이기 때문에 행렬 곱을 여러 번 수행하더라도 기울기 소실(Gradient Vanishing)과 폭주(Exploding)문제가 발생하지 않음
- RNN에서 기울기가 사라지는 문제를 방지하는데 사용
- 순방향 네트워크에선 특정 초기화 값에 지나치게 민감해지는 문제때문에 사용하지 않음
가중치 초기화 종류 | code | meaning |
상수 초기화 | torch.nn.init.constant_(tensor, val) | tensor를 val로 초기화 |
scalar initialization (0) | torch.nn.init.ones_(tensor) | tensor를 1로 초기화 |
scalar initialization (1) | torch.nn.init.zeros_(tensor) | tensor를 0으로 초기화 |
scalar initialization (eye) | torch.nn.init.eye_(tensor) | 대각선을 1로 채우고 다른곳은 0으로 초기화 |
dirac delta function initialization | torch.nn.init.dirac_(tensor) | tensor를 디랙 델타함수로 초기화( 3,4,5차원 텐서만 가능) |
Uniform Distribution initialization | torch.nn.init.unifor_(tensor,a,b) | tensor를 u(a,b)로 초기화 |
Normal Distribution initialziation | torch.nn.init.normal_(tensor, mean, std) | tensor를 N(mean, std^2)로 초기화 |
Trunc Normal Distribution initialziation | torch.nn.init.trunc_normal_(tensor, mean, std, a, b) | tensor를 N(mean,std^2)[a,b]로 초기화 |
Sparse Normal Distribution Initialization | torch.nn.init.spare_(tensor, sparsity) | tensor를 sparsity비율만큼 N(0,0.01)로 초기화 |
Xavier Initialization (Normal Distribution) | torch.nn.init.xavier_normal_(tensor, gain) | tensor를 제이비어 정규분포로 초기화 |
Xavier Initialization (Uniform Distribution) | torch.nn.init.xavier_uniform_(tensor, gain) | tensor를 제이비어 균등분포로 초기화 |
Kaiming Initialization (Normal Distribution) | torch.nn.init.kaiming_normal_(tensor, a) | tensor를 카이밍 정규분포로 초기화 |
Kaiming Initialization (Uniform Distribution) | torch.nn.init.kaiming_uniform_(tensor, a) | tensor를 카이밍 균등분포로 초기화 |
Orthogonal Initializtion | torch.nn.init.orthogonal_(tensor, gain) | tensor를 직교 행렬로 초기화(gain은 배율을 의미) |
https://www.yes24.com/Product/Goods/122753048
참고 도서 : 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
'AI > Pytorch' 카테고리의 다른 글
[Pytorch] Seq2Seq Transformer 실습 (2) | 2024.02.04 |
---|---|
[Pytorch] Transformer (2) | 2024.01.28 |
[Pytorch] train(), eval(), torch.no_grad()의 차이점 (0) | 2023.08.26 |