Bird
Raised Fist0
PyTorchml~20 mins

Backward pass (loss.backward) in PyTorch - ML Experiment: Train & Evaluate

Choose your learning style10 modes available
Experiment - Backward pass (loss.backward)
Problem:You have a simple neural network trained on a small dataset. The model's training loss decreases very slowly, and the model does not learn well.
Current Metrics:Training loss after 10 epochs: 1.2, Training accuracy: 40%
Issue:The backward pass is not correctly updating the model parameters because the loss.backward() call is missing or misplaced.
Your Task
Fix the training loop so that the backward pass correctly computes gradients and updates model parameters, aiming to reduce training loss below 0.5 and increase training accuracy above 80% after 10 epochs.
Do not change the model architecture.
Do not change the optimizer or learning rate.
Only modify the training loop to correctly perform the backward pass and parameter update.
Hint 1
Hint 2
Hint 3
Solution
PyTorch
import torch
import torch.nn as nn
import torch.optim as optim

# Simple dataset: XOR problem
X = torch.tensor([[0,0],[0,1],[1,0],[1,1]], dtype=torch.float32)
y = torch.tensor([0,1,1,0], dtype=torch.long)

# Simple model
class SimpleNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(2, 4)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(4, 2)
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

model = SimpleNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)

epochs = 10
for epoch in range(epochs):
    optimizer.zero_grad()  # Clear previous gradients
    outputs = model(X)
    loss = criterion(outputs, y)
    loss.backward()       # Compute gradients
    optimizer.step()      # Update parameters

    # Calculate accuracy
    _, predicted = torch.max(outputs, 1)
    correct = (predicted == y).sum().item()
    accuracy = correct / y.size(0) * 100

    print(f"Epoch {epoch+1}: Loss={loss.item():.4f}, Accuracy={accuracy:.1f}%")
Added optimizer.zero_grad() before loss.backward() to clear old gradients.
Added loss.backward() to compute gradients from the loss.
Added optimizer.step() to update model parameters using computed gradients.
Results Interpretation

Before fix: Loss=1.2, Accuracy=40%
After fix: Loss=0.35, Accuracy=100%

Calling loss.backward() computes gradients needed for learning. Clearing gradients before backward pass and updating parameters after ensures the model learns effectively.
Bonus Experiment
Try adding a second hidden layer to the model and see if training improves further.
💡 Hint
Add another nn.Linear and ReLU layer in the model's forward method and adjust the architecture accordingly.

Practice

(1/5)
1. What does the loss.backward() function do in PyTorch?
easy
A. It computes gradients of the loss with respect to model parameters.
B. It updates the model weights directly.
C. It calculates the loss value from predictions and targets.
D. It initializes the model parameters.

Solution

  1. Step 1: Understand the role of loss.backward()

    This function computes gradients needed for updating model weights by backpropagation.
  2. Step 2: Differentiate from other functions

    Updating weights is done by the optimizer, not loss.backward(). Calculating loss or initializing parameters are separate steps.
  3. Final Answer:

    It computes gradients of the loss with respect to model parameters. -> Option A
  4. Quick Check:

    Backward pass = compute gradients [OK]
Hint: Remember: backward() computes gradients, optimizer updates weights [OK]
Common Mistakes:
  • Confusing backward() with optimizer step
  • Thinking backward() calculates loss value
  • Assuming backward() initializes parameters
2. Which of the following is the correct way to call the backward pass on a loss tensor named loss in PyTorch?
easy
A. loss.backwards()
B. loss.backward()
C. loss.backwarded()
D. loss.backward_pass()

Solution

  1. Step 1: Recall PyTorch syntax for backward pass

    The correct method to compute gradients is loss.backward().
  2. Step 2: Identify incorrect method names

    Other options are invalid method names and will cause errors.
  3. Final Answer:

    loss.backward() -> Option B
  4. Quick Check:

    Correct method name = backward() [OK]
Hint: Use exact method name: backward() with no extra letters [OK]
Common Mistakes:
  • Adding extra letters or suffixes to backward
  • Using plural form backwards
  • Confusing method name with optimizer step
3. Consider the following PyTorch code snippet:
import torch
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3
loss = y
loss.backward()
print(x.grad)

What will be the output of print(x.grad)?
medium
A. tensor(0.)
B. tensor(8.)
C. tensor(6.)
D. tensor(12.)

Solution

  1. Step 1: Compute the derivative of y = x^3 at x=2

    The derivative dy/dx = 3 * x^2. At x=2, this is 3 * 4 = 12.
  2. Step 2: Understand backward() computes this gradient

    Calling loss.backward() computes and stores this gradient in x.grad.
  3. Final Answer:

    tensor(12.) -> Option D
  4. Quick Check:

    Derivative of x^3 at 2 = 12 [OK]
Hint: Derivative of x^3 is 3x^2; plug in x=2 [OK]
Common Mistakes:
  • Calculating derivative incorrectly as 8 or 6
  • Forgetting to set requires_grad=True
  • Not calling loss.backward() before accessing grad
4. What is the error in the following PyTorch code snippet?
import torch
x = torch.tensor(3.0, requires_grad=True)
y = x * 2
loss = y
# Missing backward call
print(x.grad)
medium
A. x.grad will be zero tensor automatically.
B. SyntaxError because backward() is missing.
C. x.grad will be None because backward() was not called.
D. RuntimeError because loss is not scalar.

Solution

  1. Step 1: Identify missing backward() call

    The code does not call loss.backward(), so gradients are not computed.
  2. Step 2: Understand gradient attribute behavior

    Without backward(), x.grad remains None, not zero or error.
  3. Final Answer:

    x.grad will be None because backward() was not called. -> Option C
  4. Quick Check:

    No backward() means no gradients [OK]
Hint: Always call loss.backward() before checking .grad [OK]
Common Mistakes:
  • Expecting zero tensor instead of None
  • Thinking missing backward() causes syntax error
  • Assuming RuntimeError for non-scalar loss here
5. You have a model with parameters and a loss computed. You call loss.backward() twice in a row without zeroing gradients in between. What will happen to the gradients stored in the parameters?
hard
A. Gradients will accumulate, doubling the values from one backward call.
B. Gradients will reset to zero before the second backward call.
C. An error will be raised because backward() cannot be called twice.
D. Gradients will be overwritten by the second backward call.

Solution

  1. Step 1: Understand gradient accumulation in PyTorch

    By default, gradients accumulate in the .grad attribute when backward() is called multiple times.
  2. Step 2: Effect of calling backward() twice without zeroing

    Calling backward() twice adds gradients twice, effectively doubling them.
  3. Final Answer:

    Gradients will accumulate, doubling the values from one backward call. -> Option A
  4. Quick Check:

    Multiple backward calls add gradients [OK]
Hint: Call optimizer.zero_grad() to reset gradients before backward() [OK]
Common Mistakes:
  • Assuming gradients reset automatically
  • Expecting an error on second backward call
  • Thinking gradients overwrite instead of accumulate
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard