-
RuntimeError: Trying to backward through the graph a second time검색하기 귀찮아서 블로그에 박제 2024. 1. 15. 15:36728x90
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.
라는 에러가 발생.
원인
: backward()를 여러번 호출할 때 발생한다.
해결방법
1. 여러번 호출하는 경우가 맞을 경우
1) multi-task learning 중 앞서 만든 그래프를 공유해야할 경우 (멀티스레드)
-> retain_graph=True 추가
loss_1.backward(retain_graph=True) # 그래프 버퍼 유지 loss_2.backward() # 그래프 버퍼 제거 optimizer.step() ...
2) 여러 loss function 계산
- 각 loss를 독립적으로 처리할 경우
-> loss.backward() 에서 계산 그래프가 제거되기 때문에 각 loss에 대해 별도의 backward pass를 수행하기 전에 optimizer의 gradient를 초기화해야한다.
# 첫 번째 loss 계산 및 backward optimizer.zero_grad() # 첫 번째 optimizer의 gradient 초기화 loss.backward() # 첫 번째 loss에 대한 backward optimizer.step() # 첫 번째 optimizer 업데이트 scheduler.step() # 첫 번째 scheduler 업데이트 # 두 번째 loss 계산 및 backward optimizer2.zero_grad() # 두 번째 optimizer의 gradient 초기화 loss2.backward() # 두 번째 loss에 대한 backward optimizer2.step() # 두 번째 optimizer 업데이트 scheduler2.step() # 두 번째 scheduler 업데이트
-> 두 loss를 결합하여 단일 backward pass로 처리
# 두 loss 결합 combined_loss = loss + loss2 # 결합된 loss에 대한 backward 및 optimizer 업데이트 optimizer.zero_grad() # optimizer의 gradient 초기화 combined_loss.backward() # 결합된 loss에 대한 backward optimizer.step() # optimizer 업데이트 scheduler.step() # scheduler 업데이트 # 만약 optimizer2와 scheduler2가 다르고 별도로 업데이트되어야 한다면 optimizer2.step() scheduler2.step()
2. 의도치 않은(코드실수) 호출
1) 학습 iteration 바깥에서 requires_grad=True 설정
- iter마다 그래프가 생성된다.
-> iter 바깥에서 선언
2) iter내에서 tensor를 학습에 재사용
-> clone() 으로 복사해서 사용
728x90'검색하기 귀찮아서 블로그에 박제' 카테고리의 다른 글