가중치 초기화
- 가중치 초기화 Weight Initialization: 모델의 초기 가중치 값을 설정하는 것
- 적절한 초깃값 설정
- 기울기 폭주나 기울기 소실 문제 완화 가능
- 모델의 수렴 속도 향상, 전반적인 학습 프로세스 개선
상수 초기화
- 가중치를 초기화 하는 간단한 방법, 비용 거의 x
- 초기 가중치 값을 모두 같은 값으로 초기화
- 대표적으로, 0, 1, 특정 값 (Constant), 단위 행렬(Unit Matrix), 디랙 델타 함수(Dirac Delta Function) 값 등이 있음
- 일반적으로 사용되지 않는 초기화 방법. 모든 가중치 초깃값을 같은 값으로 초기화하면, 배열 구조의 가중치에서 문제 발생하기 때문
- 대칭 파괴 Breaking Symmetry 현상 발생. 모든 노드가 동일한 출력 생성. 모델 학습 불가
- 스칼라값을 입력으로 받는 매우 작은 모델, 퍼셉트론 등에 적용.
- 편향을 초기화하는 경우 0이나 0.01 등의 형태로 초기화하는데 사용됨
무작위 초기화
- 초기 가중치 값을 무작위 값이나 특정 분포 형태로 초기화하는 것
- 대표적으로, 무작위(Random), 균등 분포(Uniform Distribution), 정규 분포(Normal Distribution), 잘린 정규 분포(Truncated Normal Distribution), 희소 정규 분포 초기화(Sparse Normal Distribution Initialization) 등
- 대칭 파괴 문제 방지, 간단, 많이 사용되는 초기화 방법
- 기울기 소실 현상 발생 가능성 존재
- 계층이 적거나 하나만 있는 경우 보편적으로 적용 가능
- 계층이 많아질수록 활성화 값이 양 끝단에 치우치게 되어 기울기 소실 현상 발생
제이비어 & 글로럿 초기화
- 제이비어 초기화 Xavier Initialization: 글로럿 초기화 Glorot Initialization라고도 불림
- 균등 분포나 정규 분포를 사용한 가중치 초기화 방법
- 가중치의 초기 분산을 이전 레이어의 노드수(fan-in)와 다음 레이어의 노드 수(fan-out)의 평균에 반비례하게 설정
- $$
W \sim U\left(-\sqrt{\frac{6}{\text{fan_in} + \text{fan_out}}}, \sqrt{\frac{6}{\text{fan_in} + \text{fan_out}}}\right) $$ - (확률 분포 초기화 방법과의 차이) 동일한 표준 편차를 사용하지 않고 은닉층의 노드 수에 따라 다른 표준 편차를 할당
- 이전 계층의 노드 수와 다음 계층의 노드 수에 따라 표준 편차가 계산됨
- 시그모이드나 하이퍼볼릭 탄젠트(S자형)를 활성화 함수로 하는 네트워크에서 효과적 (입력 데이터의 분산이 출력 데이터에서도 유지되도록 가중치 초기화를 하기 때문에)
카이밍 & 허 초기화
- 카이밍 초기화 Kaiming Initialization: 허 초기화 He Initialization라고도 불림
- 레이어의 입력 노드 수(fan_in)에 따라 가중치 스케일을 조정하는 방법
- $$
W \sim N\left(0, \sqrt{\frac{2}{\text{fan_in}}}\right)
$$
$$
W \sim U\left(-\sqrt{\frac{6}{\text{fan_in}}}, \sqrt{\frac{6}{\text{fan_in}}}\right)
$$
- (제이비어 초기화와 비교)
- (공통) 균등 분포나 정규 분포를 사용해 가중치를 초기화하는 방법
- (공통) 각 노드의 출력 분산이 입력 분산과 동일하도록 가중치 초기화
- (차이) 현재 계층의 입력 뉴런 수를 기반으로만 가중치를 초기화
- ReLU를 활성화 함수로 사용하는 네트워크에서 효과적
- 제이비어 초기화와 비교했을 때, 카이밍 초기화는 더 큰 분산을 사용하여 ReLU의 특성을 보완
직교 초기화
- 직교 초기화 Orthogonal Initialization: 특잇값 분해를 활용해 자기 제신을 제외한 나머지 모든 열, 행 벡터들과 직교이면서 동시에 단위 벡터인 행렬을 만드는 방법
- 가중치 행렬의 특이값을 보존
- → 장기간 메모리 Long Short Term Memory, LSTM 및 게이트 순환 유닛 Gated Recurrent Unit GRU과 같은 순환 신경망 RNN에서 주로 사용됨
- 직교 행렬의 고윳값의 절대값은 1이기 때문에 행렬 곱을 여러번 수행하더라도, 기울기 폭주나 기울기 소실 발생x
가중치 초기화 실습
- 예제1: 간단한 예시 (모델 단순)
- [_init_weights] 메서드: 모델 매개변수 초기값 설정
- 프로텍티드 메서드 Protected Method
- 메서드 이름 앞에 하나의 밑줄(_)을 붙여 사용
- 클래스 또는 하위 클래스 외부에서 사용돼서는 안된다는 것을 나타내는 컨벤션으로 강제성은 없음
- 가중치 초기화가 필요한 모듈, 클래스, 함수 등을 초기화
- 프로텍티드 메서드 Protected Method
- 가중치는 제이비어 초기화 적용, 편향은 상수 초기화 적용
- 제이비어 초기화: nn.init.xavier_uniform_
- 편향: fill_
- 가중치 적용 변수: self.layer, self.fc
- self.layer
- init 메서드에서 Sequential 클래스를 활용해 선형 변환 함수(nn.Linear(1, 2))와 시그모이드 함수(nn.Sigmoid())를 하나로 묶음
- 선형 변환 함수의 가중치와 편향 초기화 → 첫번째 index=0값을 불러옴
- self.fc
- init 메서드에서 단순히 선형 변환 함수 설정이기에 단순히 불러오면 됨
- self.layer
- 초기화 메서드 호출은 모델의 계층이 정의된 직후 호출됨
- [_init_weights] 메서드: 모델 매개변수 초기값 설정
from torch import nn
class Net(nn.Module):
def __init__(self):
super().__init__()
self.layer = nn.Sequential(
nn.Linear(1, 2),
nn.Sigmoid()
)
self.fc = nn.Linear(2, 1)
self._init_weights()
def _init_weights(self):
nn.init.xavier_uniform_(self.layer[0].weight)
self.layer[0].bias.data.fill_(0.01)
nn.init.xavier_uniform_(self.fc.weight)
self.fc.bias.data.fill_(0.01)
model = Net()
- 예제2: 가중치 초기화 함수를 모듈화해 적용
- 모델이 커지고 복잡해지면 코드도 복잡해짐 → 모듈화해 적용
- torch.apply
- 가중치 초기화 메서드를 범용적으로 적용
- 적용 함수: 텐서의 각 요소에 임의의 함수를 적용, 결과와 함께 새 텐서 반환
- 예제에서는 적용 함수에 가중치 초기화 메서드 전달해 초깃값 설정
- 가중치 초기화 메서드에 module 매개변수 추가
- nn.Module 클래스의 인스턴스들(여기서는 선형 레이어, 활성화 함수 등) 모두 모듈로 간주
- 각 모듈이 nn.Linear 타입의 인스턴스인지 확인 (isinstance)
- nn.Linear 타입의 인스턴스라면, 해당 모듈의 가중치를 제이비어 초기화하고, 편향을 상수 0.01로 초기화
- 하위 모듈에 재귀적으로 적용
- self.layer 변수의 선형 변환 함수, 시그모이드 함수가 적용된 후에 시퀀셜 호출
- 모든 계층 호출했다면 최종으로 네트워크까지 호출하고 종료
from torch import nn
class Net(nn.Module):
def __init__(self):
super().__init__()
self.layer = nn.Sequential(
nn.Linear(1, 2),
nn.Sigmoid()
)
self.fc = nn.Linear(2, 1)
self.apply(self._init_weights)
def _init_weights(self, module):
if isinstance(module, nn.Linear):
nn.init.xavier_uniform_(module.weight)
nn.init.constant_(module.bias, 0.01)
print(f"Apply : {module}")
model = Net()
- 이외에도 self.modules 메서드로도 모듈을 호출해 코드 구성 방법
- 가중치 초기화 메서드는 파이토치의 내장 함수가 아니므로, 필수적인 요소는 아니지만, 코드의 가독성과 생산성을 위해 사용하기를 권장
'Theory > Pytorch' 카테고리의 다른 글
[파이토치 트랜스포머 #10] 4장 파이토치 심화 - 4) 데이터 증강 및 변환 (1) | 2024.06.30 |
---|---|
[파이토치 트랜스포머 #9] 4장 파이토치 심화 - 3) 정칙화 (0) | 2024.04.12 |
[파이토치 트랜스포머 #7] 4장 파이토치 심화 - 1) 과대적합과 과소적합, 배치 정규화 (0) | 2024.04.12 |
[파이토치 트랜스포머 #6] 3장 파이토치 기초 - 6) 순전파와 역전파, 퍼셉트론 (1) | 2024.04.03 |
[파이토치 트랜스포머 #6] 3장 파이토치 기초 - 5) 활성화 함수 (1) | 2024.03.17 |