Notice
Recent Posts
Recent Comments
Link
관리 메뉴

뛰는 놈 위에 나는 공대생

[PyTorch] retain_graph = True라고 했음에도 backward 문제가 발생하는 경우 본문

연구 Research/인공지능 Artificial Intelligent

[PyTorch] retain_graph = True라고 했음에도 backward 문제가 발생하는 경우

보통의공대생 2023. 1. 5. 14:45
RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.

 

위와 같은 에러는 한 번 모델에서 forward propagation을 한 다음에 backward(또는 autograd.grad)를 할 때 두 번 이상 수행하면 발생하는 코드이다.

 

retain_graph=True로 해놓지 않으면 back propagation 계산을 하면서 메모리를 위해 만들어놓은 그래프를 다 지워버린다. 대신 gradient는 각 파라미터에 남겨져있기 때문에 optimizer.zero_grad() 또는 model.zero_grad()로 초기화를 해줘야 누적없이 계속 사용할 수 있는 것이다.

 

그래서 위의 에러는 만들어놓은 그래프가 free되었으니(free: 없애다) backward에 retain_graph=True로 설정하거나, backward 전에 저장된 값들에 접근하라는 설명이다.

 

그런데 나는 원래 이런 걸 대비해서 retain_graph=True를 해놓기 때문에 사실 backward나 autograd.grad의 문제가 아니었다.

 

나와 같은 사람들이 있을 수도 있어서 기록하는 글이다.

 

 

나의 경우에는 첫 번째 epoch는 문제가 없는데 두 번째 epoch부터 gradient를 구하는 데 문제가 발생했다. 이 말은 뭐냐면, 처음 설정한 데이터와 모델은 문제가 없다는 소리다.

 

아무리 생각해도 backward나 autograd.grad 문제가 아닌 것 같아서 입력이나 출력, 또는 loss function를 주목했다.

입력이나 출력을 내 입맛대로 바꾸는 과정에서 문제가 발생할 수도 있기 때문이다.

간단하게는 reshape나 view 함수를 써서 입력을 바꾸는 것도 문제를 일으킬 수 있다. (꼭 gradient 문제가 아니라도 예를 들어 input를 a라는 변수에 넣었을 때 clone을 쓰지 않고 넣으면 나중에 input이 바뀌어서 문제가 생긴다던가..)

requires_grad가 제대로 설정되었는지 이런 것도 체크했다.

 

그 결과, 나는 model 안에서 loss를 구하는 과정에서 output data를 가져다가 쓰는데,

첫 epoch에서 output data가 requires_grad가 True로 바뀌면서 그 이후의 epoch에 영향을 줬고, 그래서 오류가 발생했다.

 

파이토치는 모델을 훨씬 유동적으로 쓸 수 있는 게 큰 장점이지만, 모델을 계속 커스터마이징하고 바꾸는 과정에서 이런 자잘한 문제들이 발생하므로 조심해야겠다.

Comments