Implementing Softmax Regression from Scratch with PyTorch


import torch

# Initialize a tensor with gradient tracking
x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)

# Compute a scalar output
y = 3 * torch.dot(x, x)

# Backpropagation
y.backward()

# Display gradients
print(f"Input tensor: {x}")
print(f"Gradients: {x.grad}")

Gradinet Management


# Zero out gradients before reuse
x.grad.zero_()

# Verify gradient clearing
print(f"Cleared gradients: {x.grad}")

Linear Regression Implementation


from torch import nn

# Synthetic data generation
def generate_data(w, b, num_samples):
    X = torch.normal(0, 1, (num_samples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape(-1, 1)

true_weights = torch.tensor([2.0, -3.4])
true_bias = 4.2
features, labels = generate_data(true_weights, true_bias, 1000)

Data Loading and Model Setup


from torch.utils.data import DataLoader, TensorDataset

batch_size = 32
dataset = TensorDataset(features, labels)
data_loader = DataLoader(dataset, batch_size, shuffle=True)

# Model architecture
model = nn.Sequential(nn.Linear(2, 1))

# Initialize parameters
model[0].weight.data.normal_(0, 0.01)
model[0].bias.data.fill_(0)

# Training components
loss_fn = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.03)

Training Loop


epochs = 10
for epoch in range(epochs):
    for X, y in data_loader:
        # Forward pass
        pred = model(X)
        loss = loss_fn(pred, y)
        
        # Backward pass
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    # Print progress
    epoch_loss = loss_fn(model(features), labels)
    print(f"Epoch {epoch+1}, Loss: {epoch_loss.item():.4f}")

Softmax Classification


def softmax(z):
    exp_z = torch.exp(z - z.max(dim=1, keepdim=True)[0])
    return exp_z / exp_z.sum(dim=1, keepdim=True)

# Model definition for classification
class SoftmaxClassifier(nn.Module):
    def __init__(self, input_size, output_size):
        super().__init__()
        self.linear = nn.Linear(input_size, output_size)
        
    def forward(self, x):
        return softmax(self.linear(x))

Training Metrics


def accuracy(y_pred, y_true):
    pred_labels = y_pred.argmax(axis=1)
    return (pred_labels == y_true).float().mean()

def evaluate(model, data_loader):
    model.eval()
    correct, total = 0, 0
    with torch.no_grad():
        for X, y in data_loader:
            outputs = model(X)
            correct += (outputs.argmax(1) == y).sum().item()
            total += y.size(0)
    return correct / total

Tags: pytorch softmax autograd linear-regression Classification

Posted on Wed, 20 May 2026 04:57:19 +0000 by AngusL