본문 바로가기
Computer/ML·DL·NLP

[PyTorch] .grad.zero_() zero_grad() 차이점

by injeolmialmond 2024. 1. 16.

pytorch에서 gradient 값을 저장하는 방식

- 모든 파라미터(모델에서 학습하고자 하는 대상)에 .grad 라는 attribute를 붙여서, 파라미터마다 grad를 보관

- 어떤 파라미터를 학습할지는 초기에 텐서를 만들 때 requires_grad=True 옵션을 줘서 지정한다.

 

.grad.zero_() zero_grad() 를 하는 이유

- gradient를 계산할 때 pytorch가 자동으로 gradient 값을 누적(accumulate)하기 때문.

- 한 번 .backward() 를 불렀으면 그 값이 각 파라미터의 .grad에 누적되고, 따라서 나중에 한 번 더 .backward() 를 불렀을 때 영향을 끼침

- 따라서 .backward() 를 부르기 전에, 파라미터의 .grad에 원래 누적된 값을 치워주고 (=0으로 초기화 해주고) gradient를 계산하도록 해야 함.

(참고: https://tutorials.pytorch.kr/beginner/basics/autogradqs_tutorial.html#optional-reading-jacobian-product)

 

.grad.zero_() zero_grad() 차이점

- .grad.zero_()는 파라미터에 적용함. weight .grad.zero_() 와 같이

(참고: zero_()는 inplace로 값을 0으로 만들어주는 함수임. '텐서.zero_()' == '텐서 = torch.zeros_like(텐서)')

- zero_grad()는 옵티마이저에 적용함. 모든 파라미터에 직접 .grad.zero_()를 적용하는 것이 불편하니, optimizer를 처음에 부를 때 다음과 같이 어떤 파라미터를 최적화하고 싶은지 정의하며 시작함.

optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

 

- 그리고 나서 optimizer로 최적화를 해야 할 때, 다음과 같이 gradient 값들을 0으로 초기화해 준다

 optimizer.zero_grad()

 

위의 파이토치 튜토리얼에서 "동일한 인자로 backward를 두차례 호출하면 변화도 값이 달라집니다. 이는 역방향 전파를 수행할 때, PyTorch가 변화도를 누적(accumulate)해주기 때문입니다. 즉, 계산된 변화도의 값이 연산 그래프의 모든 잎(leaf) 노드의 grad 속성에 추가됩니다. 따라서 제대로 된 변화도를 계산하기 위해서는 grad 속성을 먼저 0으로 만들어야 합니다. 실제 학습 과정에서는 옵티마이저(optimizer)가 이 과정을 도와줍니다."라고 언급되어있는 부분이 여기까지의 내용을 나타냄

댓글