꺼내먹는지식 준

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn 문제 해결 본문

AI/PyTorch

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn 문제 해결

알 수 없는 사용자 2022. 3. 8. 22:51

해당 에러는 require_grad = Fasle 즉 미분을 할 수 없는 상태인데 미분을 진행하고자 할 때 발생하는 에러이다. 

대부분의 경우는 하단의 disscussion에서 ptrblck님이 답변을 통해 다뤄주셨다. 

대부분은 detach 로 variable을 복사하였을 때 자동으로 require_grad=False 되는 것을 인지 못한 사례이다. 

https://discuss.pytorch.org/t/element-0-of-tensors-does-not-require-grad-and-does-not-have-a-grad-fn/32908/36?page=2 

 

Element 0 of tensors does not require grad and does not have a grad_fn

following is the code to my model import torch import numpy as np import math class DeCNN(torch.nn.Module): def __init__(self, gen_emb, domain_emb, num_classes=3, dropout=0.5): super(DeCNN, self).__init__() self.gen_embedding = torch.nn.Embedding(gen_emb.s

discuss.pytorch.org

 

하지만 나는 그렇지도 않았다. 그럼 나는 왜일까?

 

바로 validation 과정에 loss.backward() 가 숨어있었다. 

 

이 간단한걸 왜 debug하지 못했을까? 

 

이는 error log에는 validation 에서 loss.backward()에 문제 있다고 report 하지 않고 정말 이상하게도 train 단에서 loss.backward()에 문제가 있다고 report하여 애꿎게도 내가 custom 한 model 내에서 detach가 일어나는 것 아닌가 하는 의심을 하였다. 

 

하지만 이 의심을 빠르게 잠재울 방법도 여기에 같이 공유한다. 

for i in list(model_scratch.parameters()): 
    if not i.requires_grad == True:
        print(i)

그냥 단순하게 내가 구현한 모델의 parameters() 를 출력해보면 하단에 requires_grad 에 대한 정보가 적혀져있고, 이걸 접근하는 방법은 .requires_grad 이다. 

 

이를 통해 출력을 해보면 requires_grad가 False인 경우가 있나 확인 할 수 있다. 

그냥 parameter를 출력하면 

list(model_scratch.parameters())


Parameter containing:
 tensor([-4.8001e-03,  3.4146e-03,  4.2383e-03, -2.0340e-03, -6.4359e-04,
         -1.4145e-03,  3.6187e-03,  8.7051e-04,  8.5114e-04, -2.4563e-03,
          4.7941e-04, -3.6108e-04, -5.3498e-04, -2.6239e-03,  4.6721e-04,
         -4.3636e-04, -2.2344e-05,  3.1200e-03, -1.5904e-05,  2.8086e-04,
         -2.7654e-03,  3.9714e-03, -1.9250e-03, -7.0117e-04, -5.0921e-03,
          1.4134e-03, -6.0237e-03, -1.5591e-03,  6.9992e-04,  6.3157e-04,
         -5.1136e-03, -4.0031e-03,  1.9521e-03, -1.7295e-03, -1.0042e-03,
          1.4444e-03,  2.9182e-04,  1.1559e-04,  3.8018e-03,  2.4038e-03,
          2.3363e-04, -3.4902e-03,  1.6315e-03,  2.9419e-03,  1.9627e-03,
         -2.0772e-03, -8.8729e-04,  4.9071e-03,  2.5410e-03, -4.2978e-03,
          6.6888e-05, -3.9291e-03,  1.1227e-03,  3.9337e-03, -4.5141e-03,
          3.6703e-04, -1.2881e-03,  5.3931e-04, -5.1499e-03, -1.2320e-03,
         -2.8180e-04, -1.6004e-03, -2.2137e-03, -1.0102e-03], device='cuda:0',
        requires_grad=True),

다음과 같은 형태로 출력이 된다. 가장 짧은 log를 출력해도 이 길이이니, 직접 하나씩 살펴보는건 말도 안된다. 

Comments