
딥러닝 모델링 과정에서 가중치를 직접 초기화하고 학습할 때 ValueError: can't optimize a non-leaf Tensor를 겪고,
리프 텐서와 논리프 텐서에 대해 알아보고 에러 없이 가중치 초기화, 학습 파라미터에 추가하는 방법에 대해!
leaf란, 잎을 의미
본래 의미와 비슷하게 리프 텐서는 가장 바깥쪽에 위치한. 즉, 최초의 입력값이다.
유저가 직접 생성한 텐서거나,단, requires_grad = Falsenn.Parameter()로 선언한 가중치이다.특징
다른 텐서로부터 연산된 값이 아닌 원본 가중치
파이토치 연산그래프(DAG)의 Root에 위치한 노드
최종 기울기 정보를 내부에 저장
리프 텐서에 in-place를 수행하면 기존 데이터가 사라지는 문제(= history 파괴) 발생하여 기울기 계산 불가해짐
requires_grad=True인 경우
- 예시
- 아래 두 코드는 모두 에러 발생
code_1query=nn.Parameter(torch.empty(768,768)).to(device) nn.init.xavier_uniform_(query)
Error_1
- nn.Parameter 선언하여 리프 텐서 생성 이후 gpu에 올리기 위해 .to(device)를 사용하는경우,
복사본이 GPU에 올라가고 이 복사본 또한 연산의 결과물이므로non-leaf tensor가 되어 오휴 발생
code_2query=torch.empty(768,768, requires_grad = True) nn.init.xavier_uniform_(query)
Error_2
- 기울기 옵션을 True로 설정하고 query 생성 시, in-place 과정에서 오류 발생
requires_grad = True를 사용하는 순간, 미분 엔진은 연산 과정의 모든 데이터를 기억하는데,in-place 연산은 원본을 덮어씌우기 때문에 원본이 사라지는 문제 발생하기 때문!
- 적절한 가중치 초기화 방법
query=torch.empty(768,768, device=device) nn.init.xavier_uniform_(query) query = nn.Parameter(query)
리프 텐서가 아닌 텐서
특징
다른 텐서로부터 연산을 통해 생성
| 연산 | 기록 이름 |
|---|---|
+ | AddBackward |
* | MulBackward |
matmul() | MmBackward |
copy | ToCopyBackward |
기울기 전달의 통로
다리 역할업데이트 불가
ValueError: can't optimize a non-leaf Tensor의 직접적인 이유로, 중간 연산 결과인 논리프 텐서는 업데이트 불가