Pytorch의 레이어 정규화(예시 포함)
코드와 인터랙티브 패널로 구성된, Pytorch의 레이어 정규화에 대한 빠르고 간단한 소개.
Created on March 14|Last edited on May 30
Comment
머신러닝 알고리즘의 훈련은 까다로운 작업이며, 특히 실제 데이터 세트를 사용하는 경우 더 어려울 수 있습니다. 수많은 어려움 중에서도 중간 활성화(intermediate activation)의 통계적 안정화는 위험이 꽤 높은 수준에 속합니다.
이번 글에서는 통계 안정화에 사용되는 일반적인 방법 중 하나인 레이어 정규화(Layer Norm)를 간단히 살펴 봅니다. 이 보고서는 배치 정규화부터 시작된 머신 러닝 정규화 시리즈의 일부입니다. 연말 전에 마지막 두 편이 나오기를 기대합니다.
Table of Contents
레이어 정규화란 무엇인가요?
문제점
이미 아시는 바와 같이, 머신 러닝 모델 훈련은 확률적(랜덤) 프로세스입니다. 이는 초기화와 가장 일반적인 최적화 도구(SGD, Adam 등)조차도 본질적으로 확률적이라는 사실에서 비롯됩니다.
이 때문에 머신 러닝(ML) 최적화는 솔루션 환경에서 급격하게 (일반화가 불가능한) 최소값으로 수렴하면서 기울기가 커질 위험이 있습니다. 간단히 말해, 활성화(즉, 비선형 레이어의 출력)가 큰 값으로 치솟는 경향이 있습니다. 이는 적절하지 않으며, 이 문제를 해결하는 가장 일반적인 방법은 배치 정규화(Batch Normalization)를 사용하는 것입니다.
하지만 여기에는 단점이 있습니다. 배치 정규화는 배치 수가 감소하면 빠르게 실패합니다. 최신 머신 러닝 알고리즘의 데이터 해상도가 높아지면서 이는 중대한 문제가 됩니다. 메모리에 데이터를 맞추기 위해서는 배치 크기가 작아야 하기 때문입니다. 또한 배치 정규화를 수행하려면 각 레이어에서 활성화의 실행 평균/분산을 계산해야 합니다. 이 방법은 레이어의 통계적 추정이 시퀀스 길이(숨겨진 동일 레이어가 호출되는 횟수)에 따라 달라지는 반복 모델(RNN 등)에는 적용되지 않습니다.
The Solution
LayerNorm은 활성화 배치에 있는 각 항목의 통계(평균과 분산)를 계산하고 이러한 통계 추정치로 각 항목을 정규화함으로써 이 두 가지 문제를 간단하게 해결할 수 있습니다.
구체적으로, 모양의 샘플이 있을 때 LayerNorm은 각 배치에서 모양의 모든 요소에 대한 평균과 분산을 계산합니다(아래 그림 참조). 이 방법은 위에서 언급한 두 가지 문제를 모두 해결할 뿐만 아니라 추론을 위해 평균과 분산을 저장(배치 정규화 레이어가 훈련 중에 수행해야 하는 작업)할 필요도 없습니다.

코드 예시
단, 컨볼루션 신경망의 경우, 컨볼루션을 수행하는 동안 사용된 파라미터를 고려하여 출력 활성화 맵의 모양도 계산해야 합니다. 아래에서는 calc_activation_shape() 함수로 간단하게 구현되어 있습니다. (자유롭게 가져가서 사용하세요).
class Network(torch.nn.Module):@staticmethoddef calc_activation_shape(dim, ksize, dilation=(1, 1), stride=(1, 1), padding=(0, 0)):def shape_each_dim(i):odim_i = dim[i] + 2 * padding[i] - dilation[i] * (ksize[i] - 1) - 1return (odim_i / stride[i]) + 1return shape_each_dim(0), shape_each_dim(1)def __init__(self, idim, num_classes=10):self.layer1 = torch.nn.Conv2D(3, 5, 3)ln_shape = Network.calc_activation_shape(idim, 3) # <--- 컨볼루션 출력의 모양 계산self.norm1 = torch.nn.LayerNorm([5, *ln_shape]) # <--- C, H, W에서의 활성화 정규화(위 그림 참조)self.layer2 = torch.nn.Conv2D(5, 10, 3)ln_shape = Network.calc_activation_shape(ln_shape, 3)self.norm2 = torch.nn.LayerNorm([10, *ln_shape])self.layer3 = torch.nn.Dense(num_classes)def __call__(self, inputs):x = F.relu(self.norm1(self.layer1(input)))x = F.relu(self.norm2(self.layer2(x)))x = F.sigmoid(self.layer3(x))return x
다음 차트에서 볼 수 있듯이 Colab 노트북에서 제공하는 모델에 대해 레이어 정규화를 사용한 모델과 사용하지 않은 모델을 벤치마���했습니다. 레이어 정규화는 여기서 상당히 효과적입니다. (참고: 4회 실행한 평균을 사용하였습니다. 실선은 이러한 실행의 평균 결과를 나타냅니다. 옅은 색은 표준 편차를 나타냅니다.)
Run set
8
결론
레이어 정규화에 대한 간단한 소개를 읽어 주셔서 감사합니다. 앞으로 몇 주에 걸쳐 인기 있는 기타 정규화 기법을 몇 가지 소개하고, 언제 어떤 기법을 사용하면 좋은지(물론 맥락이 가장 중요합니다)에 대한 팁과 요령을 담은 메타 리포트로 이 시리즈를 마무리하겠습니다.
그 외에 궁금하신 기초 기술이 있으시면 아래 댓글에 남겨 주세요. 그럼 다음에 뵙겠습니다!
Add a comment
Iterate on AI agents and models faster. Try Weights & Biases today.