Adam optimizer calculates adaptive learning rates for each parameter using estimates of first (mean) and second (variance) moments of gradients. SGD applies the same learning rate to all parameters unless manually changed.
import torch import torch.nn as nn import torch.optim as optim model = nn.Linear(2, 1) criterion = nn.MSELoss() x = torch.tensor([[1.0, 2.0]]) y = torch.tensor([[1.0]]) # Using SGD optimizer optimizer_sgd = optim.SGD(model.parameters(), lr=0.1) # Forward pass output = model(x) loss = criterion(output, y) # Backward and optimize optimizer_sgd.zero_grad() loss.backward() optimizer_sgd.step() loss_sgd = criterion(model(x), y).item() # Reset model weights model = nn.Linear(2, 1) optimizer_adam = optim.Adam(model.parameters(), lr=0.1) output = model(x) loss = criterion(output, y) optimizer_adam.zero_grad() loss.backward() optimizer_adam.step() loss_adam = criterion(model(x), y).item() print(round(loss_sgd, 3), round(loss_adam, 3))
After one update step, both optimizers reduce the loss, but Adam typically reduces it more because it adapts learning rates per parameter.
Adam typically works well with a learning rate around 0.001 as a default starting point.
Adam usually converges faster and reaches higher accuracy earlier because it adapts learning rates per parameter.
import torch import torch.nn as nn import torch.optim as optim model = nn.Linear(3, 1) optimizer = optim.Adam(model.parameters(), lr=0.01) x = torch.randn(5, 3) y = torch.randn(5, 1) criterion = nn.MSELoss() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step()
optimizer.zero_grad() should be called before loss.backward() to clear old gradients. Calling zero_grad after backward causes incorrect gradient accumulation and runtime error.
