Getting RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn error

Hi,
I have defined my binary classifier as :
class CreditCardTransactionClassifier(nn.Module):
def init(self):
super(CreditCardTransactionClassifier, self).init()
self.fc1 = nn.Linear(29, 29)
self.relu1 = nn.ReLU()
self.dout = nn.Dropout(0.2)
self.fc2 = nn.Linear(29, 58)
self.prelu = nn.PReLU(1)
self.out = nn.Linear(58, 2)

def forward(self, input_):
    a1 = self.fc1(input_)
    h1 = self.relu1(a1)
    dout = self.dout(h1)
    a2 = self.fc2(dout)
    h2 = self.prelu(a2)
    a3 = self.out(h2)
    return a3

def predict(self,x):
    #Apply softmax to output. 

    pred = F.softmax(self.forward(x))
    ans = []
    #Pick the class with maximum weight
    for t in pred:
        if t[0]>t[1]:
            ans.append(0)
        else:
            ans.append(1)
    return torch.tensor(ans)

model = CreditCardTransactionClassifier().double()

My training loop is :

for epoch in range(num_epochs):
h = np.array([])
for data in train_loader:
x = data[:,0:29]

    y = data[:,29]
    y = y.reshape((-1,1))
    #output = model(x)
    y_pred = model.predict(x)
    y_pred = y_pred.reshape((-1,1))

print(y_pred)

    print(y_pred.shape)
    print(y.shape)
    
    loss = criterion(y_pred.float(),y.float())
    h = np.append(h, loss.item())
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    mean_loss = np.mean(h)
print('epoch [{}/{}], loss:{:.4f}'
      .format(epoch + 1, num_epochs, mean_loss))
history['train_loss'].append(mean_loss)

torch.save(model.state_dict(), ‘./credit_card_model.pth’)

I am getting RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn error

Can somebody please help.

Thx

Vimal

Stack trace looks like :


RuntimeError Traceback (most recent call last)
in
17 h = np.append(h, loss.item())
18 optimizer.zero_grad()
—> 19 loss.backward()
20 optimizer.step()
21 mean_loss = np.mean(h)

/data/anaconda/envs/vimal_pytorch/lib/python3.7/site-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)
105 products. Defaults to False.
106 “”"
–> 107 torch.autograd.backward(self, gradient, retain_graph, create_graph)
108
109 def register_hook(self, hook):

/data/anaconda/envs/vimal_pytorch/lib/python3.7/site-packages/torch/autograd/init.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
91 Variable._execution_engine.run_backward(
92 tensors, grad_tensors, retain_graph, create_graph,
—> 93 allow_unreachable=True) # allow_unreachable flag
94
95

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

Since you are recreating a tensor in self.predict, you are detaching the output from the computation graph.
Try to use output = model(x) to train your model, i.e. pass it to your criterion instead of y_pred.

Thanks a lot. Yup that worked.

@ptrblck
class Autoencoder(nn.Module):

def __init__(self):
    super(Autoencoder, self).__init__()
    self.encoder = nn.Sequential(
       # nn.Dropout2d(dropout_p= 0.5),
        nn.Conv2d(1, 16,kernel_size=3,stride =1, padding= 1,bias= False),  
        nn.ReLU(True),
        nn.MaxPool2d( 2, 2),  
        nn.Conv2d(16,32,kernel_size=3,stride =1, padding=1),  
        nn.ReLU(True),
        #nn.MaxPool2d(2, 2),  
        nn.Conv2d(32,64,kernel_size=3,stride =1, padding= 1),  
        nn.ReLU(True),
       # nn.Linear(64 * 3 *3, 120)
        #nn.MaxPool2d(2, 2),  
        
    )
    self.decoder = nn.Sequential(
        nn.MaxUnpool2d(2, 2),
        nn.ConvTranspose2d(64, 32, kernel_size=3), 
        nn.ReLU(True),
        nn.MaxUnpool2d(2, 2),
        nn.ConvTranspose2d(32, 16, kernel_size=3),  
        nn.ReLU(True),
        nn.MaxUnpool2d(2, 2),
        nn.ConvTranspose2d(16, 8, kernel_size=3),
        
        
        #nn.Tanh()
    )

def forward(self, x):
    x = self.encoder(x)
    encoded_x = x
    x = self.decoder(x)
    print(x.shape)
    x = x.view(-1, 64 * 3 * 3)
    x = F.log_softmax(self.fc2(x), dim=0)
    return x, encoded_x

num_epochs = 5
learning_rate = 1e-5
model= Autoencoder()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):

for data in loader_train_set:
    
    img, label = data
    print(img.size())
    img = torch.tensor(img)
    labels = labels.view(-1)
    img = img[:, 0:1]
    encoded_output = model.encoder(img)
    
    print(encoded_output.size())
    output_of_net = torch.rand(20, 2, 240, 320)
    label = torch.LongTensor(20,240, 320)

    output_of_net_linearized = output_of_net.permute(0, 2, 3, 1).reshape(-1, output_of_net.size(1))
    label_linearized = label.view(-1)
    loss = criterion(output_of_net_linearized, label_linearized)
    
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()



print('epoch [{}/{}], loss:{:.4f}'.format(epoch+1, num_epochs, loss.data()))

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
I tried making few changes, but now I encountered the above mentioned error.

You are creating a new tensor as the output from your model in:

output_of_net = torch.rand(20, 2, 240, 320)

which won’t work.

Thank for helping me out.I have few questions. I want to calculate the accuracy of the training model.So, I found the skit_learn accuracy_score function, but I didn’t understand that
accuracy_score ( y_true , y_pred)
y_true: “will be the output from the model”
y_pred: " will be the images from the DataLoader"
Please, correct if I am wrong
for epoch in range(Epochs):
for data in trainloader:
image,_ = data
o_image = train_model(image)
loss = criterion(o_image, image)
loss.backward()
optimizer.step()
optimizer.zero_grad()
print(‘Epoch:{}, Loss:{:.4f}’.format(epoch+1, float(loss)))

This is my training code.

y_true would be the label tensor in the current batch (which you are currently not storing) and y_pred would be the prediction of your model.
For a multi-class classification you can get the prediction via: pred = torch.argmax(output, 1).

Let me know, if you need more information.

For epoch in range(Epochs):
for data in trainloader:
image, label= data
o_image = train_model(image)
loss = criterion(o_image, image)
loss.backward()
optimizer.step()
optimizer.zero_grad()

pred = torch.argmax(o_image, 1)
accuracy_score = accuracy_score(label, pred)
print(‘Epoch:{}, Loss:{:.4f}’.format(epoch+1, float(loss)), accuracy_score)

class Autoencoder(nn.Module):
def init(self):
super(Autoencoder, self).init()
self.encoder = nn.Sequential( # like the Composition layer you built
nn.Conv2d(1, 12, 5, stride=1),
nn.ReLU(),
nn.Dropout2d(p=0.05),
nn.Conv2d(12, 24, 5, stride=1),
nn.ReLU(),
nn.Conv2d(24, 48, 3),
nn.ReLU(),
nn.Dropout2d(p=0.05),
)
self.decoder = nn.Sequential(
nn.ConvTranspose2d(48, 24, 5),
nn.ReLU(),
nn.ConvTranspose2d(24, 12, 5, stride=1),
nn.ReLU(),
nn.ConvTranspose2d(12, 1, 3, stride=1),
nn.ReLU()
)

def forward(self, value):
    value = self.encoder(value)
    value = self.decoder(value)
    return value

For epoch in range(Epochs):
for data in trainloader:
images, label= data
o_image = train_model(images)
loss = criterion(o_image, images)
loss.backward()
optimizer.step()
optimizer.zero_grad()

_,prediction = torch.max(o_image, 1)
train_acc += torch.sum(prediction == images)
print(‘Epoch:{}, Loss:{:.4f}’.format(epoch+1, float(loss)), accuracy_score)

~````Training Accuracy is increasing , which means there can be overfitting of data . But i used dropout function as well. Please suggest if i am missing something.
`Epoch 0, Train Accuracy: 93386456.0 , TrainLoss: 0.2611906826496124
Epoch 1, Train Accuracy: 186969568.0 , TrainLoss: 0.2584492564201355
Epoch 2, Train Accuracy: 280305408.0 , TrainLoss: 0.0300734955817461
Epoch 3, Train Accuracy: 373835808.0 , TrainLoss: 0.01294061541557312
Epoch 4, Train Accuracy: 466917440.0 , TrainLoss: 0.011260838247835636
Epoch 5, Train Accuracy: 560389248.0 , TrainLoss: 0.011532839387655258