<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged pytorch</title>
<link>https://coderlegion.com/tag/pytorch</link>
<description>Powered by Question2Answer</description>
<item>
<title>AWS PyTorch: Build, Train, and Deploy Deep Learning Models in the Cloud</title>
<link>https://coderlegion.com/31929/aws-pytorch-build-train-and-deploy-deep-learning-models-in-the-cloud</link>
<description>&lt;hr&gt;
&lt;p&gt;title: &quot;AWS PyTorch: Build, Train, and Deploy Deep Learning Models in the Cloud&quot;&lt;br&gt;
published: true&lt;br&gt;
description: &quot;Learn how to build a PyTorch image classifier, store model artifacts in Amazon S3, and move toward managed machine learning training and deployment with Amazon SageMaker AI.&quot;&lt;/p&gt;
&lt;h3 id=&quot;tags-aws-pytorch-machinelearning-python&quot;&gt;tags: aws, pytorch, machinelearning, python&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/neldd08v6n3oeqcj5r1g.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;PyTorch makes it easier to experiment with neural networks, computer vision, natural language processing, and deep learning.&lt;/p&gt;
&lt;p&gt;But building a model is only one part of a machine learning project.&lt;/p&gt;
&lt;p&gt;When it's time to move from experimentation to production, you need reliable compute, data storage, repeatable training, model artifacts, deployment, monitoring, and cost controls.&lt;/p&gt;
&lt;p&gt;This is where AWS can help.&lt;/p&gt;
&lt;p&gt;By combining &lt;strong&gt;PyTorch, Amazon SageMaker AI, Amazon S3, and Amazon CloudWatch&lt;/strong&gt;, developers can build machine learning workflows that move from local experiments toward scalable cloud deployments.&lt;/p&gt;
&lt;p&gt;In this article, we'll build a simple image classifier and explore how to extend the project into an AWS-based machine learning pipeline.&lt;/p&gt;
&lt;h3 id=&quot;1-what-is-pytorch-on-aws-&quot;&gt;1. What Is PyTorch on AWS?&lt;/h3&gt;
&lt;p&gt;PyTorch is an open-source deep learning framework that provides tensor operations, automatic differentiation, GPU acceleration, and tools for creating neural networks.&lt;/p&gt;
&lt;p&gt;AWS provides several services that can support PyTorch workloads:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amazon SageMaker AI:&lt;/strong&gt; Run managed training jobs and deploy machine learning models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon S3:&lt;/strong&gt; Store datasets, model artifacts, and training outputs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon EC2:&lt;/strong&gt; Run PyTorch on virtual machines, including suitable GPU instances.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS Deep Learning Containers:&lt;/strong&gt; Use supported, preconfigured machine learning environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon CloudWatch:&lt;/strong&gt; Monitor supported metrics, logs, and application behavior.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS IAM:&lt;/strong&gt; Control access to training data, infrastructure, and model artifacts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You don't need all these services for every project. Start with what your workload requires and add complexity when it provides a clear benefit.&lt;/p&gt;
&lt;h3 id=&quot;2-understand-the-architecture&quot;&gt;2. Understand the Architecture&lt;/h3&gt;
&lt;p&gt;A typical workflow looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;        Training Dataset
               |
               v
         Amazon S3
               |
               v
      Amazon SageMaker AI
          Training Job
               |
               v
         PyTorch Model
               |
               v
       Model Artifacts in S3
               |
               v
       Deployment / Inference
               |
               v
       Application Predictions
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Amazon S3 provides durable storage for datasets and artifacts. SageMaker AI can run managed training jobs, while a suitable inference service can expose the trained model to applications.&lt;/p&gt;
&lt;p&gt;CloudWatch and related AWS monitoring capabilities help you investigate failures, latency, and resource usage.&lt;/p&gt;
&lt;p&gt;For small experiments, you can train locally first. For larger workloads, managed training can reduce infrastructure-management overhead.&lt;/p&gt;
&lt;h3 id=&quot;3-hands-on-project-build-a-digit-classifier&quot;&gt;3. Hands-On Project: Build a Digit Classifier&lt;/h3&gt;
&lt;p&gt;We'll train a small neural network on the MNIST handwritten-digit dataset.&lt;/p&gt;
&lt;p&gt;Our model will learn to classify grayscale images into one of ten categories, representing the digits from 0 to 9.&lt;/p&gt;
&lt;h4 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h4&gt;
&lt;p&gt;You'll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.&lt;/li&gt;
&lt;li&gt;Basic Python knowledge.&lt;/li&gt;
&lt;li&gt;An internet connection to download the dataset.&lt;/li&gt;
&lt;li&gt;An AWS account only when you move to the cloud steps.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first part runs locally and does not require AWS resources.&lt;/p&gt;
&lt;h4 id=&quot;step-1-create-a-project-environment&quot;&gt;Step 1: Create a project environment&lt;/h4&gt;
&lt;p&gt;Create a project directory and enter it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir aws-pytorch-demo
cd aws-pytorch-demo
python -m venv .venv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Activate the virtual environment on Windows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;.venv\Scripts\Activate.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On Linux or macOS:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;source .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install torch torchvision
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For GPU training, install a PyTorch build compatible with your GPU and CUDA configuration. Follow the official installation instructions: &lt;a rel=&quot;nofollow&quot; href=&quot;https://pytorch.org/get-started/locally/&quot;&gt;https://pytorch.org/get-started/locally/&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&quot;step-2-create-the-training-script&quot;&gt;Step 2: Create the training script&lt;/h4&gt;
&lt;p&gt;Create &lt;code&gt;train.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

device = torch.device(
    &quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;
)

print(f&quot;Training device: {device}&quot;)

transform = transforms.ToTensor()

train_data = datasets.MNIST(
    root=&quot;data&quot;,
    train=True,
    download=True,
    transform=transform,
)

test_data = datasets.MNIST(
    root=&quot;data&quot;,
    train=False,
    download=True,
    transform=transform,
)

train_loader = DataLoader(
    train_data,
    batch_size=64,
    shuffle=True,
)

test_loader = DataLoader(
    test_data,
    batch_size=256,
    shuffle=False,
)


class DigitClassifier(nn.Module):
    def __init__(self):
        super().__init__()

        self.network = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 128),
            nn.ReLU(),
            nn.Linear(128, 10),
        )

    def forward(self, x):
        return self.network(x)


model = DigitClassifier().to(device)

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(
    model.parameters(),
    lr=0.001,
)

# Training loop
for epoch in range(3):
    model.train()
    total_loss = 0.0

    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        outputs = model(images)
        loss = criterion(outputs, labels)

        loss.backward()
        optimizer.step()

        total_loss += loss.item()

    average_loss = total_loss / len(train_loader)

    print(
        f&quot;Epoch {epoch + 1}/3, &quot;
        f&quot;Loss: {average_loss:.4f}&quot;
    )

# Evaluation
model.eval()
correct = 0
total = 0

with torch.no_grad():
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)

        outputs = model(images)
        predictions = outputs.argmax(dim=1)

        correct += (predictions == labels).sum().item()
        total += labels.size(0)

accuracy = 100 * correct / total
print(f&quot;Test accuracy: {accuracy:.2f}%&quot;)

# Save model parameters
torch.save(
    model.state_dict(),
    &quot;digit_classifier.pth&quot;,
)

print(&quot;Saved digit_classifier.pth&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;step-3-train-the-model&quot;&gt;Step 3: Train the model&lt;/h4&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python train.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The script downloads MNIST, trains the neural network, evaluates it against the test dataset, and saves the learned parameters.&lt;/p&gt;
&lt;p&gt;Your output should include:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Training device: cpu
Epoch 1/3, Loss: ...
Epoch 2/3, Loss: ...
Epoch 3/3, Loss: ...
Test accuracy: ...
Saved digit_classifier.pth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The loss and accuracy values depend on the training run. If a compatible GPU is available, the script can use it automatically.&lt;/p&gt;
&lt;h4 id=&quot;step-4-make-a-prediction&quot;&gt;Step 4: Make a prediction&lt;/h4&gt;
&lt;p&gt;Create &lt;code&gt;predict.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import torch
from torch import nn
from torchvision import datasets, transforms


class DigitClassifier(nn.Module):
    def __init__(self):
        super().__init__()

        self.network = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 128),
            nn.ReLU(),
            nn.Linear(128, 10),
        )

    def forward(self, x):
        return self.network(x)


device = torch.device(
    &quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;
)

model = DigitClassifier().to(device)

state = torch.load(
    &quot;digit_classifier.pth&quot;,
    map_location=device,
    weights_only=True,
)

model.load_state_dict(state)
model.eval()

dataset = datasets.MNIST(
    root=&quot;data&quot;,
    train=False,
    download=True,
    transform=transforms.ToTensor(),
)

image, actual_label = dataset[0]

with torch.no_grad():
    logits = model(image.unsqueeze(0).to(device))
    predicted_label = logits.argmax(dim=1).item()

print(f&quot;Predicted digit: {predicted_label}&quot;)
print(f&quot;Actual digit: {actual_label}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run the prediction:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python predict.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Predicted digit: 7
Actual digit: 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These values are illustrative. The actual result depends on your trained model.&lt;/p&gt;
&lt;p&gt;You now have a basic end-to-end deep learning workflow: train, evaluate, save, reload, and predict.&lt;/p&gt;
&lt;h3 id=&quot;4-move-the-project-to-aws&quot;&gt;4. Move the Project to AWS&lt;/h3&gt;
&lt;p&gt;Once the model works locally, you can move the workflow to AWS.&lt;/p&gt;
&lt;h4 id=&quot;step-1-create-an-s3-bucket&quot;&gt;Step 1: Create an S3 bucket&lt;/h4&gt;
&lt;p&gt;Choose a globally unique bucket name:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;aws s3 mb s3://YOUR-UNIQUE-PYTORCH-BUCKET \
  --region us-east-1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace the placeholder with your actual bucket name.&lt;/p&gt;
&lt;p&gt;Upload the training script:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;aws s3 cp train.py \
  s3://YOUR-UNIQUE-PYTORCH-BUCKET/code/train.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For this example, the script downloads MNIST directly. A production pipeline should manage dataset preparation, storage, and versioning more explicitly.&lt;/p&gt;
&lt;h4 id=&quot;step-2-run-training-with-sagemaker-ai&quot;&gt;Step 2: Run training with SageMaker AI&lt;/h4&gt;
&lt;p&gt;Amazon SageMaker AI supports PyTorch training jobs using supported framework environments and training configurations.&lt;/p&gt;
&lt;p&gt;At a high level, you need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure an execution role with appropriate permissions.&lt;/li&gt;
&lt;li&gt;Prepare your training script and dependencies.&lt;/li&gt;
&lt;li&gt;Select a supported PyTorch environment.&lt;/li&gt;
&lt;li&gt;Configure the training input and output locations.&lt;/li&gt;
&lt;li&gt;Choose an appropriate instance type.&lt;/li&gt;
&lt;li&gt;Set runtime limits and launch the job.&lt;/li&gt;
&lt;li&gt;Review the training logs and saved artifacts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Use the current official guide for the SDK version you install:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.aws.amazon.com/sagemaker/latest/dg/pytorch.html&quot;&gt;https://docs.aws.amazon.com/sagemaker/latest/dg/pytorch.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SageMaker SDK interfaces evolve, so use examples matching your installed SDK version rather than mixing older estimator APIs with newer SDK workflows.&lt;/p&gt;
&lt;h4 id=&quot;step-3-store-model-artifacts-in-s3&quot;&gt;Step 3: Store model artifacts in S3&lt;/h4&gt;
&lt;p&gt;For a locally trained model, you can upload the saved parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;aws s3 cp digit_classifier.pth \
  s3://YOUR-UNIQUE-PYTORCH-BUCKET/models/digit_classifier.pth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a managed training job, configure the output location so SageMaker AI saves the model artifacts automatically.&lt;/p&gt;
&lt;p&gt;Keep a record of the dataset version, source-code version, training parameters, framework version, and evaluation metrics. This makes it easier to reproduce and audit experiments.&lt;/p&gt;
&lt;h3 id=&quot;5-deploy-the-model-for-inference&quot;&gt;5. Deploy the Model for Inference&lt;/h3&gt;
&lt;p&gt;Training and inference are separate stages.&lt;/p&gt;
&lt;p&gt;For an application to request predictions, you need a serving interface that loads the model, validates input, executes inference, and returns a response.&lt;/p&gt;
&lt;p&gt;With Amazon SageMaker AI, you can deploy supported PyTorch models to a managed endpoint. The required model packaging and inference code depend on the selected deployment approach.&lt;/p&gt;
&lt;p&gt;A typical inference flow is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load the approved model artifact.&lt;/li&gt;
&lt;li&gt;Convert the input into the tensor format expected by the model.&lt;/li&gt;
&lt;li&gt;Run the model in evaluation mode.&lt;/li&gt;
&lt;li&gt;Convert the output into a response your application can consume.&lt;/li&gt;
&lt;li&gt;Log relevant errors and operational metrics.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the MNIST model, input should represent a grayscale image with dimensions of 28 × 28 pixels. Validate the request before running inference.&lt;/p&gt;
&lt;p&gt;For workloads that don't need immediate responses, consider batch inference instead of keeping an online endpoint available continuously.&lt;/p&gt;
&lt;h3 id=&quot;6-production-best-practices&quot;&gt;6. Production Best Practices&lt;/h3&gt;
&lt;p&gt;A model that works locally isn't automatically production-ready.&lt;/p&gt;
&lt;h4 id=&quot;cost-optimization&quot;&gt;Cost optimization&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Start with CPU training for small models when practical.&lt;/li&gt;
&lt;li&gt;Use GPU instances when benchmarks show a meaningful benefit.&lt;/li&gt;
&lt;li&gt;Set job time limits.&lt;/li&gt;
&lt;li&gt;Stop endpoints and compute resources when they are no longer required.&lt;/li&gt;
&lt;li&gt;Evaluate batch inference for offline workloads.&lt;/li&gt;
&lt;li&gt;Include storage, logging, data transfer, and supporting services in cost estimates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;security&quot;&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Apply least-privilege IAM policies.&lt;/li&gt;
&lt;li&gt;Keep S3 buckets private.&lt;/li&gt;
&lt;li&gt;Encrypt sensitive datasets and artifacts.&lt;/li&gt;
&lt;li&gt;Avoid embedding credentials in source code.&lt;/li&gt;
&lt;li&gt;Restrict access to training data and deployed models.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;reproducibility&quot;&gt;Reproducibility&lt;/h4&gt;
&lt;p&gt;Track dataset versions, dependencies, training parameters, random seeds, and model artifacts. Store code in version control and preserve evaluation results for each model version.&lt;/p&gt;
&lt;h4 id=&quot;monitoring&quot;&gt;Monitoring&lt;/h4&gt;
&lt;p&gt;Monitor training failures, compute utilization, inference latency, and application errors using supported AWS monitoring capabilities.&lt;/p&gt;
&lt;p&gt;Also evaluate model quality over time. A service can remain operational while its predictions become less accurate because real-world data has changed.&lt;/p&gt;
&lt;h4 id=&quot;model-evaluation&quot;&gt;Model evaluation&lt;/h4&gt;
&lt;p&gt;Don't rely on training loss alone.&lt;/p&gt;
&lt;p&gt;For classification tasks, consider precision, recall, F1 score, confusion matrices, and performance on representative held-out data. Select metrics based on the real business problem.&lt;/p&gt;
&lt;h3 id=&quot;7-where-can-you-use-pytorch-on-aws-&quot;&gt;7. Where Can You Use PyTorch on AWS?&lt;/h3&gt;
&lt;p&gt;Common applications include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Computer vision:&lt;/strong&gt; Image classification and defect detection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Natural language processing:&lt;/strong&gt; Text classification and domain-specific model fine-tuning.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recommendation systems:&lt;/strong&gt; Ranking and personalization.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Forecasting:&lt;/strong&gt; Demand prediction and time-series analysis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generative AI:&lt;/strong&gt; Training or fine-tuning compatible neural network models.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For large-scale distributed training, additional planning is needed for GPU memory, network communication, checkpointing, and data loading.&lt;/p&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;PyTorch provides the flexibility to build deep learning models, while AWS offers several ways to run training workloads, store model artifacts, and deploy predictions.&lt;/p&gt;
&lt;p&gt;Start with a small experiment, validate the results, and then introduce cloud infrastructure where it provides measurable value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The real goal is not just to train a model in the cloud. It's to create a secure, reproducible, observable machine learning workflow that can grow with your application.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;official-resources&quot;&gt;Official Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.aws.amazon.com/sagemaker/latest/dg/pytorch.html&quot;&gt;PyTorch on Amazon SageMaker AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://aws.amazon.com/blogs/machine-learning/&quot;&gt;AWS machine learning blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.aws.amazon.com/s3/&quot;&gt;Amazon S3 documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.aws.amazon.com/cloudwatch/&quot;&gt;Amazon CloudWatch documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pytorch.org/get-started/locally/&quot;&gt;Install PyTorch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;aws-pytorch-machinelearning-deeplearning-amazonsagemaker&quot;&gt;AWS #PyTorch #MachineLearning #DeepLearning #AmazonSageMaker&lt;/h2&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/31929/aws-pytorch-build-train-and-deploy-deep-learning-models-in-the-cloud</guid>
<pubDate>Wed, 21 Oct 2026 06:46:29 +0000</pubDate>
</item>
<item>
<title>How to Build a Deep learning model to detect Ships</title>
<link>https://coderlegion.com/31753/how-to-build-a-deep-learning-model-to-detect-ships</link>
<description>&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=2248772476490076519&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;For anyone studying practical computer vision and deep learning deployment:&lt;br&gt;
A frequent challenge in applied vision projects is balancing spatial accuracy against computational overhead during training. Selecting an architecture variant like YOLOv8l provides the parameter capacity necessary to resolve multi-scale objects in clustered environments, but success depends entirely on proper configuration and validation monitoring. This tutorial breaks down the mechanics of training a custom detector from scratch, detailing how loss convergence curves and validation checkpoints guide the selection of deployable weights.&lt;/p&gt;
&lt;p&gt;The progression moves methodically from environment initialization to final model inference. It covers dataset re-indexing, parsing raw coordinate tags into standardized label files, executing supervised training runs while monitoring loss metrics, and implementing an OpenCV inference script to handle bounding box coordinates, class labels, and confidence thresholds on unseen imagery.&lt;/p&gt;
&lt;p&gt;The Resources:&lt;/p&gt;
&lt;p&gt;Reading on Medium: &lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/object-detection-tutorials/yolov8-custom-object-detection-full-code-walkthrough-23fa476f834e&quot;&gt;https://medium.com/object-detection-tutorials/yolov8-custom-object-detection-full-code-walkthrough-23fa476f834e&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Detailed written explanation and source code: &lt;a rel=&quot;nofollow&quot; href=&quot;https://eranfeit.net/yolov8-custom-object-detection-full-code-walkthrough/&quot;&gt;https://eranfeit.net/yolov8-custom-object-detection-full-code-walkthrough/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Join my Newsletter : &lt;a rel=&quot;nofollow&quot; href=&quot;https://eranfeit.net/advance-your-skills-in-computer-vision-ai/&quot;&gt;https://eranfeit.net/advance-your-skills-in-computer-vision-ai/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Deep-dive video walkthrough: &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/zAyPboTjcAA&quot;&gt;https://youtu.be/zAyPboTjcAA&lt;/a&gt;&lt;br&gt;
This material is published solely for educational purposes. Feel free to leave constructive feedback or questions about threshold tuning and batch performance below.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/31753/how-to-build-a-deep-learning-model-to-detect-ships</guid>
<pubDate>Mon, 19 Oct 2026 16:30:01 +0000</pubDate>
</item>
<item>
<title>GPU-Accelerating MSCRED with CUDA, im2col, GEMM, and a Custom PyTorch Extension</title>
<link>https://coderlegion.com/26883/gpu-accelerating-mscred-with-cuda-im2col-gemm-and-a-custom-pytorch-extension</link>
<description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;During my M.Tech in Data Science and Artificial Intelligence at IIT Bhilai (2021–2023), I conducted thesis research on multivariate time-series anomaly detection and GPU acceleration using industrial process signals.&lt;/p&gt;
&lt;p&gt;My thesis, titled &lt;strong&gt;“Anomaly Detection of Multivariate Time Series Data and Acceleration Using GPUs,”&lt;/strong&gt; explored an MSCRED—Multi-Scale Convolutional Recurrent Encoder-Decoder—and ConvLSTM-based pipeline for modelling relationships between signals and detecting abnormal temporal patterns.&lt;/p&gt;
&lt;p&gt;Although the model produced useful anomaly-detection results, its convolution-heavy encoder created a significant CPU bottleneck. I therefore implemented GPU-accelerated operations using CUDA, transformed convolution into an &lt;code&gt;im2col&lt;/code&gt; plus GEMM workflow, investigated global-memory and shared-memory implementations, and integrated the accelerated operations with PyTorch.&lt;/p&gt;
&lt;p&gt;In the measured workload, encoder runtime decreased from &lt;strong&gt;300 seconds on the CPU to 23.664 seconds on the GPU&lt;/strong&gt;, representing an approximately &lt;strong&gt;12.68× encoder speed-up&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Research attribution:&lt;/strong&gt; MSCRED and ConvLSTM are established architectures introduced by the researchers cited in the References section. This article describes how I used, adapted, profiled, and accelerated selected operations as part of my M.Tech thesis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Data confidentiality:&lt;/strong&gt; The original research involved industrial process data. This article discusses the architecture, optimisation methodology, and aggregate benchmark results without publishing proprietary signals, internal process details, confidential datasets, or restricted source code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-anomaly-detection-problem&quot;&gt;The Anomaly-Detection Problem&lt;/h3&gt;
&lt;p&gt;Industrial systems often generate many related sensor and process-control signals at the same time. A single signal may appear normal when viewed independently, while the relationship between several signals may indicate an abnormal operating condition.&lt;/p&gt;
&lt;p&gt;This makes multivariate time-series anomaly detection more difficult than analysing one signal at a time.&lt;/p&gt;
&lt;p&gt;The model must learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Relationships between multiple signals&lt;/li&gt;
&lt;li&gt;Changes across different time windows&lt;/li&gt;
&lt;li&gt;Temporal dependencies between successive observations&lt;/li&gt;
&lt;li&gt;Deviations from normal operating patterns&lt;/li&gt;
&lt;li&gt;Reconstruction differences that may indicate anomalies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal of the research was to detect unusual multivariate patterns while preserving the temporal and spatial relationships present in the data.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;mscred-and-convlstm-architecture&quot;&gt;MSCRED and ConvLSTM Architecture&lt;/h3&gt;
&lt;p&gt;MSCRED models relationships between multiple time-series signals by constructing &lt;strong&gt;signature matrices&lt;/strong&gt; over different temporal windows.&lt;/p&gt;
&lt;p&gt;At a high level, the pipeline contains:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Signature-matrix generation from multivariate signals&lt;/li&gt;
&lt;li&gt;A convolutional encoder for spatial feature extraction&lt;/li&gt;
&lt;li&gt;ConvLSTM layers for temporal modelling&lt;/li&gt;
&lt;li&gt;A decoder that reconstructs expected signal relationships&lt;/li&gt;
&lt;li&gt;Reconstruction-error analysis for anomaly scoring&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The encoder processes the signature matrices through convolutional operations, while ConvLSTM captures how the encoded representations evolve over time.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Multivariate signals
        ↓
Signature matrices
        ↓
CNN encoder
        ↓
ConvLSTM
        ↓
Decoder
        ↓
Reconstruction error
        ↓
Anomaly score
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;why-signature-matrices-are-useful&quot;&gt;Why Signature Matrices Are Useful&lt;/h4&gt;
&lt;p&gt;A signature matrix represents pairwise relationships between signals over a selected time interval.&lt;/p&gt;
&lt;p&gt;By generating these matrices at multiple scales, the model can observe both short-term and longer-term relationships. This helps identify anomalies that may not be visible in an individual signal.&lt;/p&gt;
&lt;h4 id=&quot;role-of-the-encoder&quot;&gt;Role of the Encoder&lt;/h4&gt;
&lt;p&gt;The convolutional encoder extracts spatial patterns from the signature matrices. It reduces the raw matrix representation into compact feature maps that capture important relationships between signals.&lt;/p&gt;
&lt;h4 id=&quot;role-of-convlstm&quot;&gt;Role of ConvLSTM&lt;/h4&gt;
&lt;p&gt;ConvLSTM models how those spatial representations change over time.&lt;/p&gt;
&lt;p&gt;Unlike a standard fully connected LSTM, ConvLSTM preserves the spatial structure of feature maps while learning temporal dependencies.&lt;/p&gt;
&lt;h4 id=&quot;role-of-the-decoder&quot;&gt;Role of the Decoder&lt;/h4&gt;
&lt;p&gt;The decoder reconstructs the expected signature matrices.&lt;/p&gt;
&lt;p&gt;When the reconstructed output differs significantly from the observed input, the reconstruction error can indicate an anomalous pattern.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;anomaly-detection-evaluation&quot;&gt;Anomaly-Detection Evaluation&lt;/h3&gt;
&lt;p&gt;The purpose of the MSCRED and ConvLSTM pipeline was to detect abnormal relationships and temporal behaviour across multiple industrial process signals.&lt;/p&gt;
&lt;p&gt;The model learned normal multivariate patterns by reconstructing signature matrices. During evaluation, the difference between the observed signature matrices and the reconstructed outputs was used to calculate a reconstruction error.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Observed signature matrix
            ↓
MSCRED reconstruction
            ↓
Reconstruction error
            ↓
Thresholding
            ↓
Normal or anomalous
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A larger reconstruction error indicated that the observed relationships differed from patterns learned during normal operation and could therefore represent an anomaly.&lt;/p&gt;
&lt;p&gt;The thesis evaluated anomaly-detection quality using the F1 score. Under the reported experimental setup, the &lt;strong&gt;best recorded F1 score was 0.941&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This result represents model-quality evaluation and should be interpreted separately from the CUDA runtime measurements presented later. The GPU memory optimisations were designed to reduce computation time, not to improve predictive accuracy.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;where-the-performance-bottleneck-appeared&quot;&gt;Where the Performance Bottleneck Appeared&lt;/h3&gt;
&lt;p&gt;The encoder repeatedly applied convolutional operations to signature matrices.&lt;/p&gt;
&lt;p&gt;On the CPU, these operations involved substantial nested computation across:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Input channels&lt;/li&gt;
&lt;li&gt;Output filters&lt;/li&gt;
&lt;li&gt;Spatial positions&lt;/li&gt;
&lt;li&gt;Kernel dimensions&lt;/li&gt;
&lt;li&gt;Batch elements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This made the encoder a strong candidate for GPU acceleration because many convolution calculations could be performed in parallel.&lt;/p&gt;
&lt;p&gt;The objective was not to redesign the anomaly-detection model. Instead, it was to preserve its expected computational behaviour while accelerating selected expensive operations.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;transforming-conv2d-into-im2col-and-gemm&quot;&gt;Transforming Conv2D into &lt;code&gt;im2col&lt;/code&gt; and GEMM&lt;/h3&gt;
&lt;p&gt;A convolution repeatedly applies a kernel to overlapping regions of an input feature map.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;im2col&lt;/code&gt;, or image-to-column, transformation rearranges those local regions into columns of a matrix.&lt;/p&gt;
&lt;p&gt;After this transformation, convolution can be expressed as a general matrix multiplication:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Output matrix = Weight matrix × im2col(Input)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This conversion is useful because matrix multiplication is highly parallel and can be executed efficiently on a GPU.&lt;/p&gt;
&lt;h4 id=&quot;conceptual-transformation&quot;&gt;Conceptual Transformation&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Input feature map
        ↓
Extract overlapping kernel windows
        ↓
Arrange windows as matrix columns
        ↓
Multiply by reshaped filter matrix
        ↓
Reshape result into output feature map
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;why-use-gemm-&quot;&gt;Why Use GEMM?&lt;/h4&gt;
&lt;p&gt;GEMM stands for &lt;strong&gt;General Matrix-Matrix Multiplication&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Modern GPU architectures are designed to perform large numbers of multiply-and-accumulate operations in parallel. Expressing convolution as GEMM allows the workload to use that parallelism.&lt;/p&gt;
&lt;h4 id=&quot;trade-off&quot;&gt;Trade-Off&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;im2col&lt;/code&gt; introduces additional memory usage because overlapping input regions are copied into an intermediate matrix.&lt;/p&gt;
&lt;p&gt;The method is most effective when the computational benefit of parallel matrix multiplication outweighs the cost of creating and storing the intermediate representation.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;cuda-kernel-design&quot;&gt;CUDA Kernel Design&lt;/h3&gt;
&lt;p&gt;The CUDA implementation divided the computation across many GPU threads.&lt;/p&gt;
&lt;p&gt;Each thread was responsible for part of the output, while thread blocks grouped related work.&lt;/p&gt;
&lt;p&gt;Important kernel-design considerations included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mapping output elements to threads&lt;/li&gt;
&lt;li&gt;Selecting thread-block dimensions&lt;/li&gt;
&lt;li&gt;Coalescing memory access where possible&lt;/li&gt;
&lt;li&gt;Reducing unnecessary global-memory operations&lt;/li&gt;
&lt;li&gt;Avoiding excessive synchronisation&lt;/li&gt;
&lt;li&gt;Preserving correct tensor indexing&lt;/li&gt;
&lt;li&gt;Managing intermediate buffers efficiently&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The implementation required careful validation because incorrect indexing in GPU code can produce plausible-looking but incorrect outputs.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;global-memory-and-shared-memory&quot;&gt;Global Memory and Shared Memory&lt;/h3&gt;
&lt;p&gt;The first GPU implementation relied primarily on &lt;strong&gt;global memory&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Global memory provides access to the complete input, but its latency is considerably higher than that of on-chip shared memory.&lt;/p&gt;
&lt;p&gt;The optimised implementation staged reusable tiles inside &lt;strong&gt;shared memory&lt;/strong&gt;. Threads within the same block could then reuse nearby values without repeatedly loading them from global memory.&lt;/p&gt;
&lt;p&gt;The shared-memory optimisation was intended to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce repeated global-memory reads&lt;/li&gt;
&lt;li&gt;Improve data locality&lt;/li&gt;
&lt;li&gt;Increase data reuse within each thread block&lt;/li&gt;
&lt;li&gt;Reduce memory-related kernel overhead&lt;/li&gt;
&lt;li&gt;Improve matrix-multiplication efficiency&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;conceptual-data-flow&quot;&gt;Conceptual Data Flow&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Global memory
      ↓
Load reusable tile
      ↓
Shared memory
      ↓
Threads perform repeated calculations
      ↓
Write result to global memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Shared memory is limited in capacity, so tile dimensions and thread-block organisation must be selected carefully.&lt;/p&gt;
&lt;p&gt;Poorly selected configurations can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce occupancy&lt;/li&gt;
&lt;li&gt;Increase synchronisation overhead&lt;/li&gt;
&lt;li&gt;Create bank conflicts&lt;/li&gt;
&lt;li&gt;Use too much shared memory per block&lt;/li&gt;
&lt;li&gt;Limit the number of active thread blocks&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;integrating-the-cuda-implementation-with-pytorch&quot;&gt;Integrating the CUDA Implementation with PyTorch&lt;/h3&gt;
&lt;p&gt;To use the accelerated operations inside the existing model pipeline, I connected the CUDA implementation to PyTorch through a custom extension.&lt;/p&gt;
&lt;p&gt;The integration enabled PyTorch tensors to be passed to the CUDA implementation and the computed results to be returned to the model pipeline.&lt;/p&gt;
&lt;p&gt;Important integration concerns included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tensor dimensions&lt;/li&gt;
&lt;li&gt;Device placement&lt;/li&gt;
&lt;li&gt;Data types&lt;/li&gt;
&lt;li&gt;Contiguous-memory assumptions&lt;/li&gt;
&lt;li&gt;Compilation and linking&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;CPU-versus-GPU output comparison&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Correctness validation was essential. A faster kernel is not useful if it changes tensor shapes, produces incorrect indexing, introduces unacceptable numerical differences, or behaves inconsistently for the tested configurations.&lt;/p&gt;
&lt;p&gt;The custom extension made it possible to retain PyTorch for model development while using lower-level CUDA operations for selected performance-critical components.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;experimental-setup&quot;&gt;Experimental Setup&lt;/h3&gt;
&lt;p&gt;The benchmark used the following environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA RTX A6000, 48 GB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU:&lt;/strong&gt; 16-core Intel Xeon Gold 5218&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System memory:&lt;/strong&gt; 64 GB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data points:&lt;/strong&gt; 36,000&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Number of features:&lt;/strong&gt; 30&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Batch size:&lt;/strong&gt; 128&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU threads:&lt;/strong&gt; 32&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;timing-methodology&quot;&gt;Timing Methodology&lt;/h4&gt;
&lt;p&gt;The timings reported here are measurements from my thesis experiments using the specified hardware and workload. The CPU and GPU implementations used the same input dimensions and batch configuration.&lt;/p&gt;
&lt;p&gt;The results should be treated as comparative experimental measurements rather than universal library benchmarks. Performance may vary with implementation details, CUDA configuration, tensor dimensions, data-transfer costs, compiler settings, and hardware.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;performance-benchmark-results&quot;&gt;Performance Benchmark Results&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Component &lt;/th&gt;&lt;th&gt;CPU &lt;/th&gt;&lt;th&gt;GPU: global memory &lt;/th&gt;&lt;th&gt;GPU: shared memory&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Encoder &lt;/td&gt;&lt;td&gt;300 s &lt;/td&gt;&lt;td&gt;27.492 s &lt;/td&gt;&lt;td&gt;23.664 s&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ConvLSTM &lt;/td&gt;&lt;td&gt;1,200 s &lt;/td&gt;&lt;td&gt;909.208 s &lt;/td&gt;&lt;td&gt;847.260 s&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Total runtime &lt;/td&gt;&lt;td&gt;2,700 s &lt;/td&gt;&lt;td&gt;1,594 s &lt;/td&gt;&lt;td&gt;1,481 s&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;results-at-a-glance&quot;&gt;Results at a Glance&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Anomaly-detection quality:&lt;/strong&gt; best recorded F1 score of &lt;strong&gt;0.941&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encoder acceleration:&lt;/strong&gt; approximately &lt;strong&gt;12.68×&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;End-to-end acceleration:&lt;/strong&gt; approximately &lt;strong&gt;1.82×&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total runtime reduction:&lt;/strong&gt; approximately &lt;strong&gt;45.1%&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The shared-memory implementation reduced encoder runtime from &lt;strong&gt;300 seconds to 23.664 seconds&lt;/strong&gt;, producing an approximately &lt;strong&gt;12.68× encoder speed-up&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For the complete measured pipeline, runtime decreased from &lt;strong&gt;2,700 seconds to 1,481 seconds&lt;/strong&gt;. The total-runtime measurement represents the complete measured pipeline rather than only the encoder and ConvLSTM components shown separately.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-the-encoder-improved-more-than-convlstm&quot;&gt;Why the Encoder Improved More Than ConvLSTM&lt;/h3&gt;
&lt;p&gt;The convolutional encoder benefited strongly from GPU execution because its operations provided substantial data parallelism.&lt;/p&gt;
&lt;p&gt;ConvLSTM achieved a smaller improvement because of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recurrent dependencies&lt;/li&gt;
&lt;li&gt;Sequential temporal processing&lt;/li&gt;
&lt;li&gt;Memory movement&lt;/li&gt;
&lt;li&gt;Repeated state updates&lt;/li&gt;
&lt;li&gt;More limited parallelism across time steps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consequently, the &lt;strong&gt;12.68× encoder acceleration&lt;/strong&gt; did not translate into a &lt;strong&gt;12.68× end-to-end speed-up&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;After the encoder was accelerated, ConvLSTM became the dominant runtime bottleneck.&lt;/p&gt;
&lt;p&gt;This is an important performance-engineering lesson: accelerating one component can move the bottleneck to another part of the system.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;correctness-validation&quot;&gt;Correctness Validation&lt;/h3&gt;
&lt;p&gt;The CUDA implementation was compared with the reference implementation for the tested tensor shapes and configurations.&lt;/p&gt;
&lt;p&gt;The optimisation work focused on reducing execution time while preserving the expected computational behaviour. Model-quality evaluation and runtime evaluation were treated as separate concerns.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;engineering-challenges&quot;&gt;Engineering Challenges&lt;/h3&gt;
&lt;p&gt;Several engineering challenges appeared during the implementation.&lt;/p&gt;
&lt;h4 id=&quot;1-correct-tensor-indexing&quot;&gt;1. Correct Tensor Indexing&lt;/h4&gt;
&lt;p&gt;The CUDA kernel had to reproduce the same logical output as the reference convolution operation.&lt;/p&gt;
&lt;p&gt;A small indexing error could generate incorrect feature maps without necessarily causing a runtime failure.&lt;/p&gt;
&lt;h4 id=&quot;2-memory-management&quot;&gt;2. Memory Management&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;im2col&lt;/code&gt; transformation created additional intermediate data.&lt;/p&gt;
&lt;p&gt;This required careful allocation, reuse, and release of GPU memory.&lt;/p&gt;
&lt;h4 id=&quot;3-synchronisation&quot;&gt;3. Synchronisation&lt;/h4&gt;
&lt;p&gt;Threads sharing data through shared memory had to synchronise at appropriate points.&lt;/p&gt;
&lt;p&gt;Missing or unnecessary synchronisation could cause incorrect results or reduced performance.&lt;/p&gt;
&lt;h4 id=&quot;4-kernel-configuration&quot;&gt;4. Kernel Configuration&lt;/h4&gt;
&lt;p&gt;Thread-block dimensions and tile sizes affected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Occupancy&lt;/li&gt;
&lt;li&gt;Shared-memory usage&lt;/li&gt;
&lt;li&gt;Memory access&lt;/li&gt;
&lt;li&gt;Work distribution&lt;/li&gt;
&lt;li&gt;Overall kernel performance&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;5-pytorch-integration&quot;&gt;5. PyTorch Integration&lt;/h4&gt;
&lt;p&gt;The extension had to account for tensor shapes, data types, device placement, memory layout, compilation, linking, and output comparison.&lt;/p&gt;
&lt;h4 id=&quot;6-measuring-the-correct-bottleneck&quot;&gt;6. Measuring the Correct Bottleneck&lt;/h4&gt;
&lt;p&gt;Improving one component changed the relative cost of other components.&lt;/p&gt;
&lt;p&gt;Profiling therefore had to be repeated after major optimisations.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;engineering-lessons&quot;&gt;Engineering Lessons&lt;/h3&gt;
&lt;h4 id=&quot;1-optimising-one-component-does-not-guarantee-an-equivalent-end-to-end-improvement&quot;&gt;1. Optimising One Component Does Not Guarantee an Equivalent End-to-End Improvement&lt;/h4&gt;
&lt;p&gt;Once the encoder was accelerated, ConvLSTM represented a larger proportion of the remaining runtime.&lt;/p&gt;
&lt;h4 id=&quot;2-im2col-makes-convolution-gpu-friendly-but-introduces-memory-overhead&quot;&gt;2. &lt;code&gt;im2col&lt;/code&gt; Makes Convolution GPU-Friendly but Introduces Memory Overhead&lt;/h4&gt;
&lt;p&gt;The transformation enables GEMM-based execution while creating a larger intermediate representation.&lt;/p&gt;
&lt;h4 id=&quot;3-shared-memory-is-valuable-when-threads-repeatedly-reuse-nearby-data&quot;&gt;3. Shared Memory Is Valuable When Threads Repeatedly Reuse Nearby Data&lt;/h4&gt;
&lt;p&gt;Its benefit depends on access patterns, tile sizes, synchronisation, and thread-block configuration.&lt;/p&gt;
&lt;h4 id=&quot;4-profiling-must-guide-optimisation&quot;&gt;4. Profiling Must Guide Optimisation&lt;/h4&gt;
&lt;p&gt;Performance work should focus on measured bottlenecks rather than assumptions about which component is slow.&lt;/p&gt;
&lt;h4 id=&quot;5-correctness-is-as-important-as-speed&quot;&gt;5. Correctness Is as Important as Speed&lt;/h4&gt;
&lt;p&gt;GPU output should be compared against a trusted reference implementation before performance improvements are accepted.&lt;/p&gt;
&lt;h4 id=&quot;6-custom-pytorch-extensions-offer-flexibility-at-the-cost-of-additional-complexity&quot;&gt;6. Custom PyTorch Extensions Offer Flexibility at the Cost of Additional Complexity&lt;/h4&gt;
&lt;p&gt;Device handling, tensor shapes, data types, compilation, numerical validation, and fallback behaviour all require careful attention.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h3&gt;
&lt;h4 id=&quot;what-is-mscred-&quot;&gt;What is MSCRED?&lt;/h4&gt;
&lt;p&gt;MSCRED stands for &lt;strong&gt;Multi-Scale Convolutional Recurrent Encoder-Decoder&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is an architecture designed to model relationships between multiple time-series signals and detect abnormal behaviour through reconstruction error.&lt;/p&gt;
&lt;h4 id=&quot;what-does-im2col-do-&quot;&gt;What does &lt;code&gt;im2col&lt;/code&gt; do?&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;im2col&lt;/code&gt; rearranges overlapping convolution windows into matrix columns, allowing convolution to be expressed as matrix multiplication.&lt;/p&gt;
&lt;h4 id=&quot;why-did-shared-memory-help-&quot;&gt;Why did shared memory help?&lt;/h4&gt;
&lt;p&gt;Shared memory allowed threads in the same block to reuse data without repeatedly loading it from slower global memory. This reduced memory-access overhead for reusable tiles.&lt;/p&gt;
&lt;h4 id=&quot;did-gpu-memory-optimisation-improve-the-f1-score-&quot;&gt;Did GPU memory optimisation improve the F1 score?&lt;/h4&gt;
&lt;p&gt;That was not the purpose of the optimisation, and this article does not claim that it did.&lt;/p&gt;
&lt;p&gt;The best recorded F1 score describes anomaly-detection quality in the thesis experiments. The CPU and GPU timing results describe computational performance. They should be interpreted separately.&lt;/p&gt;
&lt;h4 id=&quot;why-was-the-encoder-speed-up-much-larger-than-the-total-speed-up-&quot;&gt;Why was the encoder speed-up much larger than the total speed-up?&lt;/h4&gt;
&lt;p&gt;After the encoder became faster, ConvLSTM represented a larger share of total runtime. The overall system was therefore limited by the remaining bottleneck.&lt;/p&gt;
&lt;h4 id=&quot;is-a-custom-cuda-kernel-always-faster-than-pytorch-operations-&quot;&gt;Is a Custom CUDA Kernel Always Faster Than PyTorch Operations?&lt;/h4&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Optimised PyTorch and CUDA libraries are already highly efficient for many operations. A custom kernel is most useful when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The workload has a specialised access pattern&lt;/li&gt;
&lt;li&gt;Existing operations create unnecessary overhead&lt;/li&gt;
&lt;li&gt;Profiling identifies a clear bottleneck&lt;/li&gt;
&lt;li&gt;Correctness and maintenance costs are justified&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;can-the-original-industrial-dataset-be-shared-&quot;&gt;Can the Original Industrial Dataset Be Shared?&lt;/h4&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;The original dataset contains industrial process information. A public reproduction would require synthetic or appropriately anonymised multivariate time-series data.&lt;/p&gt;
&lt;h4 id=&quot;are-these-benchmark-results-universal-&quot;&gt;Are These Benchmark Results Universal?&lt;/h4&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Performance depends on GPU architecture, CPU configuration, tensor dimensions, batch size, kernel implementation, memory layout, CUDA and PyTorch versions, compiler settings, and workload characteristics.&lt;/p&gt;
&lt;p&gt;The reported numbers apply to the specific experimental setup described in this article.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;limitations-and-data-privacy-considerations&quot;&gt;Limitations and Data-Privacy Considerations&lt;/h3&gt;
&lt;p&gt;The reported results were obtained on a specific hardware configuration and workload.&lt;/p&gt;
&lt;p&gt;Different GPUs, tensor dimensions, batch sizes, memory layouts, CUDA versions, and kernel configurations may produce different results.&lt;/p&gt;
&lt;p&gt;The original dataset cannot be published because it contains industrial process information. A public reproduction would therefore require synthetic or appropriately anonymised multivariate time-series data.&lt;/p&gt;
&lt;p&gt;This article presents aggregate benchmark measurements and technical methodology rather than the complete industrial dataset or restricted implementation.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;future-work&quot;&gt;Future Work&lt;/h3&gt;
&lt;p&gt;Future work could focus on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Profiling and optimising the ConvLSTM component&lt;/li&gt;
&lt;li&gt;Reducing intermediate memory allocation&lt;/li&gt;
&lt;li&gt;Reducing host-to-device and device-to-device memory movement&lt;/li&gt;
&lt;li&gt;Comparing the custom implementation with optimised CUDA libraries&lt;/li&gt;
&lt;li&gt;Evaluating additional tile and thread-block configurations&lt;/li&gt;
&lt;li&gt;Testing across different GPU architectures&lt;/li&gt;
&lt;li&gt;Reproducing the workflow using synthetic public data&lt;/li&gt;
&lt;li&gt;Adding automated correctness and regression tests&lt;/li&gt;
&lt;li&gt;Measuring kernel-level execution using GPU profiling tools&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This work was completed as part of my M.Tech thesis research at the &lt;strong&gt;Indian Institute of Technology Bhilai&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It demonstrated how low-level GPU optimisation can be integrated into a deep-learning anomaly-detection pipeline.&lt;/p&gt;
&lt;p&gt;The convolutional encoder benefited substantially from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CUDA parallelisation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;im2col&lt;/code&gt;-based lowering&lt;/li&gt;
&lt;li&gt;GEMM&lt;/li&gt;
&lt;li&gt;Shared-memory data reuse&lt;/li&gt;
&lt;li&gt;Custom PyTorch integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Encoder runtime decreased from &lt;strong&gt;300 seconds to 23.664 seconds&lt;/strong&gt; in the measured workload.&lt;/p&gt;
&lt;p&gt;The broader result also illustrated an important systems principle: once one stage is accelerated, another stage may become the new performance bottleneck.&lt;/p&gt;
&lt;p&gt;In this case, ConvLSTM limited the end-to-end improvement even after the encoder achieved a substantial speed-up.&lt;/p&gt;
&lt;p&gt;The work reinforced that successful performance engineering requires both low-level optimisation and system-level measurement.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Zhang, C., Song, D., Chen, Y., Feng, X., Lumezanu, C., Cheng, W., Ni, J., Zong, B., Chen, H., and Chawla, N. V. (2019). &lt;strong&gt;A Deep Neural Network for Unsupervised Anomaly Detection and Diagnosis in Multivariate Time Series Data.&lt;/strong&gt; &lt;em&gt;Proceedings of the AAAI Conference on Artificial Intelligence&lt;/em&gt;, 33(01), 1409–1416. &lt;a rel=&quot;nofollow&quot; href=&quot;https://doi.org/10.1609/aaai.v33i01.33011409&quot;&gt;https://doi.org/10.1609/aaai.v33i01.33011409&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shi, X., Chen, Z., Wang, H., Yeung, D.-Y., Wong, W.-K., and Woo, W.-C. (2015). &lt;strong&gt;Convolutional LSTM Network: A Machine Learning Approach for Precipitation Nowcasting.&lt;/strong&gt; &lt;em&gt;Advances in Neural Information Processing Systems 28&lt;/em&gt;, 802–810. &lt;a rel=&quot;nofollow&quot; href=&quot;https://proceedings.neurips.cc/paper_files/paper/2015/hash/07563a3fe3bbe7e3ba84431ad9d055af-Abstract.html&quot;&gt;https://proceedings.neurips.cc/paper_files/paper/2015/hash/07563a3fe3bbe7e3ba84431ad9d055af-Abstract.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NVIDIA. &lt;strong&gt;CUDA C++ Programming Guide.&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.nvidia.com/cuda/cuda-c-programming-guide/&quot;&gt;https://docs.nvidia.com/cuda/cuda-c-programming-guide/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PyTorch. &lt;strong&gt;Custom C++ and CUDA Operators.&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.pytorch.org/tutorials/advanced/cpp_custom_ops.html&quot;&gt;https://docs.pytorch.org/tutorials/advanced/cpp_custom_ops.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3 id=&quot;citation-and-feedback&quot;&gt;Citation and Feedback&lt;/h3&gt;
&lt;p&gt;If this article informs academic or technical work, please cite the original MSCRED and ConvLSTM papers above.&lt;/p&gt;
&lt;p&gt;To refer specifically to my thesis implementation, optimisation process, or reported benchmarks, you may cite this article as:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Vutnoor, R. (2026). “GPU-Accelerating MSCRED with CUDA, im2col, GEMM, and a Custom PyTorch Extension.” DEV Community.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you found the article useful, a reaction, comment, or constructive technical question on DEV would be appreciated.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I am &lt;strong&gt;Ranjith Vutnoor&lt;/strong&gt;, an AI/ML Software Engineer and IIT Bhilai alumnus working on production RAG systems, LLM evaluation, model fine-tuning, PyTorch, and GPU-accelerated machine learning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://ranjithvutnoor.github.io/portfolio/&quot;&gt;Portfolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ranjithvutnoor&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/ranjithvutnoor/&quot;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/26883/gpu-accelerating-mscred-with-cuda-im2col-gemm-and-a-custom-pytorch-extension</guid>
<pubDate>Fri, 11 Sep 2026 18:07:01 +0000</pubDate>
</item>
<item>
<title>Building a Real-Time Network Anomaly Detector with PyTorch and Go</title>
<link>https://coderlegion.com/18965/building-a-real-time-network-anomaly-detector-with-pytorch-and-go</link>
<description>&lt;hr&gt;
&lt;p&gt;description: &quot;4-service microservices architecture for live network intrusion detection: hybrid ML model, sub-second alerts, and an 11-page React operator dashboard.&quot;&lt;br&gt;
tags: pytorch, go, machinelearning, microservices&lt;br&gt;
series: engineering-deep-dives&lt;br&gt;
cover_image:&lt;/p&gt;
&lt;h3 id=&quot;canonical-url-https-satyasaikilaru-vercel-app-blog-network-anomaly-detector&quot;&gt;canonical_url: &lt;a rel=&quot;nofollow&quot; href=&quot;https://satyasaikilaru.vercel.app/blog/network-anomaly-detector&quot;&gt;https://satyasaikilaru.vercel.app/blog/network-anomaly-detector&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — I built a full-stack intrusion detection platform: a hybrid ML model (Focal Loss classifier + autoencoder for zero-days), a 4-service Go/Python backend, and an 11-page React dashboard. R2L recall doubled (14% → 29%), zero-day detection works via reconstruction error, and the whole pipeline runs in &amp;lt;2ms per prediction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-problem-no-one-talks-about&quot;&gt;The Problem No One Talks About&lt;/h3&gt;
&lt;p&gt;Every network security tutorial shows you how to train a classifier on NSL-KDD and call it done. But classifiers have a fatal blind spot: &lt;strong&gt;they can only detect attacks they've trained on.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The NSL-KDD test set alone contains 17 attack subtypes that don't appear in training. In production, this ratio is infinitely worse — every new CVE, every new botnet, every novel C2 protocol is invisible to a classifier until you retrain.&lt;/p&gt;
&lt;p&gt;I wanted to build something that catches &lt;em&gt;both&lt;/em&gt;: known attacks with high precision &lt;strong&gt;and&lt;/strong&gt; novel threats it's never seen before.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;architecture-at-a-glance&quot;&gt;Architecture at a Glance&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;┌─────────────────────────┐
│   React Dashboard :5173 │  11 pages, ECharts, AG Grid, Firebase Auth
│   Apollo Client (GQL+WS)│
└───────────┬─────────────┘
            │
┌───────────▼─────────────┐
│  GraphQL Gateway :4000  │  gqlgen, Firebase Admin SDK, SQLite
│  Auth · Persistence     │
└───────────┬─────────────┘
            │ HTTP proxy
┌───────────▼─────────────┐
│  Go API Backend :8080   │  REST, WebSocket broadcast, Simulation
│  Packet capture control │
└───────────┬─────────────┘
            │ HTTP /api/predict
┌───────────▼─────────────┐
│  FastAPI ML Server :8000│  PyTorch → ONNX inference, &amp;lt;2ms/sample
└─────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Why 4 services?&lt;/strong&gt; The ML server needs high memory and bursty CPU. The Go API needs low memory and high concurrency. Scaling them as one binary wastes money. Each service deploys and scales independently.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-hybrid-ml-model&quot;&gt;The Hybrid ML Model&lt;/h3&gt;
&lt;h4 id=&quot;problem-1-rare-attacks-are-invisible-to-standard-loss-functions&quot;&gt;Problem 1: Rare attacks are invisible to standard loss functions&lt;/h4&gt;
&lt;p&gt;NSL-KDD class distribution:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Class &lt;/th&gt;&lt;th&gt;Training % &lt;/th&gt;&lt;th&gt;What it is&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Normal &lt;/td&gt;&lt;td&gt;53% &lt;/td&gt;&lt;td&gt;Legitimate traffic&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;DoS &lt;/td&gt;&lt;td&gt;36% &lt;/td&gt;&lt;td&gt;Denial of service&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Probe &lt;/td&gt;&lt;td&gt;9.4% &lt;/td&gt;&lt;td&gt;Port scanning, reconnaissance&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;R2L &lt;/td&gt;&lt;td&gt;0.8% &lt;/td&gt;&lt;td&gt;Remote-to-Local exploits&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;U2R &lt;/td&gt;&lt;td&gt;0.04% &lt;/td&gt;&lt;td&gt;User-to-Root privilege escalation&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Standard CrossEntropy loss treats all samples equally — so the model essentially ignores R2L and U2R. Why learn to detect 0.04% of the data when you can boost accuracy by getting the 53% right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix: Focal Loss.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;FL(p_t) = -α_t (1 - p_t)^γ log(p_t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Focal Loss down-weights easy examples (the Normal traffic the model already handles) and forces it to focus on hard, rare samples. The γ parameter controls how aggressively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Metric &lt;/th&gt;&lt;th&gt;CrossEntropy (V1) &lt;/th&gt;&lt;th&gt;Focal Loss (V2) &lt;/th&gt;&lt;th&gt;Change&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Probe Recall &lt;/td&gt;&lt;td&gt;68% &lt;/td&gt;&lt;td&gt;88% &lt;/td&gt;&lt;td&gt;+20%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;R2L Recall &lt;/td&gt;&lt;td&gt;14% &lt;/td&gt;&lt;td&gt;29% &lt;/td&gt;&lt;td&gt;&lt;strong&gt;+15% (2x)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Macro F1 &lt;/td&gt;&lt;td&gt;0.558 &lt;/td&gt;&lt;td&gt;0.589 &lt;/td&gt;&lt;td&gt;+5.5%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;problem-2-zero-days-are-invisible-to-any-classifier&quot;&gt;Problem 2: Zero-days are invisible to any classifier&lt;/h4&gt;
&lt;p&gt;A classifier is a lookup table — &quot;I've seen this pattern before, it's DoS.&quot; For the 17 novel attack subtypes in the test set (and the infinite unknown attacks in the wild), we need something fundamentally different.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix: Autoencoder trained only on Normal traffic.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The autoencoder learns to compress and reconstruct &quot;what normal looks like.&quot; At inference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Low reconstruction error → looks normal → pass&lt;/li&gt;
&lt;li&gt;High reconstruction error → looks like &lt;em&gt;nothing I've ever seen&lt;/em&gt; → anomaly flag&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is zero-day detection by definition: it catches anything that deviates from normal, regardless of whether it matches any known signature.&lt;/p&gt;
&lt;h4 id=&quot;the-3-vote-consensus&quot;&gt;The 3-Vote Consensus&lt;/h4&gt;
&lt;p&gt;Two detectors means disagreements. Policy:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Classifier &lt;/th&gt;&lt;th&gt;Autoencoder &lt;/th&gt;&lt;th&gt;Action&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Attack &lt;/td&gt;&lt;td&gt;High error &lt;/td&gt;&lt;td&gt;&lt;strong&gt;High confidence&lt;/strong&gt; — auto-block above threshold&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Normal &lt;/td&gt;&lt;td&gt;High error &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Possible zero-day&lt;/strong&gt; — escalate to operator&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Attack &lt;/td&gt;&lt;td&gt;Low error &lt;/td&gt;&lt;td&gt;Known pattern — treat at face value&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Normal &lt;/td&gt;&lt;td&gt;Low error &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Green&lt;/strong&gt; — pass&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The second row is the gold: a connection that &lt;em&gt;looks normal per-feature&lt;/em&gt; but whose overall shape is anomalous. That's where zero-days hide.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-dashboard-11-pages&quot;&gt;The Dashboard — 11 Pages&lt;/h3&gt;
&lt;p&gt;Not just a prediction endpoint. Operators need context:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Page &lt;/th&gt;&lt;th&gt;Why it exists&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;World Map&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Animated attack routes with GeoIP — &quot;where is this coming from?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Traffic Feed&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;AG Grid, bulk select, CSV export — &quot;show me everything&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Incidents&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;AI threat summary + timeline by class — &quot;what's happening now?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Analytics&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Time-series, attack distribution — &quot;what's the trend?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Network Graph&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Force-directed IP topology — &quot;who's talking to whom?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Model Compare&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Radar chart, confusion matrix — &quot;how good are we?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SOAR&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Auto-block on confidence thresholds — &quot;respond automatically&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Settings&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Profile, theme, webhooks, Slack — &quot;configure everything&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;System Status&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Service health, latency sparklines — &quot;is the platform healthy?&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Firebase Auth handles Google Sign-In + Email/Password. First user = admin in SQLite; subsequent = viewers. RBAC enforced at the gateway, not just the UI.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Class &lt;/th&gt;&lt;th&gt;Precision &lt;/th&gt;&lt;th&gt;Recall &lt;/th&gt;&lt;th&gt;F1&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Normal &lt;/td&gt;&lt;td&gt;91.0% &lt;/td&gt;&lt;td&gt;88.9% &lt;/td&gt;&lt;td&gt;90.0%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;DoS &lt;/td&gt;&lt;td&gt;95.8% &lt;/td&gt;&lt;td&gt;85.6% &lt;/td&gt;&lt;td&gt;90.4%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Probe &lt;/td&gt;&lt;td&gt;60.4% &lt;/td&gt;&lt;td&gt;88.3% &lt;/td&gt;&lt;td&gt;71.7%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;R2L &lt;/td&gt;&lt;td&gt;53.9% &lt;/td&gt;&lt;td&gt;29.4% &lt;/td&gt;&lt;td&gt;38.0%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;U2R &lt;/td&gt;&lt;td&gt;2.2% &lt;/td&gt;&lt;td&gt;41.8% &lt;/td&gt;&lt;td&gt;4.2%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Overall: 80.0% accuracy · 0.589 Macro F1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;R2L/U2R are still the weakest — genuinely hard with &amp;lt;1% of training data. The autoencoder compensates by catching them as distribution anomalies even when the classifier misses.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-i-d-do-differently&quot;&gt;What I'd Do Differently&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a χ² frequency-distribution detector&lt;/strong&gt; — the same math that cracks a Caesar cipher (compare observed letter frequencies to English) applied to network feature distributions. Catches slow horizontal scans that per-packet models miss.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Per-host behavioral baselines&lt;/strong&gt; — a global Normal model doesn't notice &quot;this IP was quiet for 6 months and just started scanning port 445.&quot; A per-host baseline does.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adversarial training&lt;/strong&gt; — FGSM/PGD perturbations during training to harden against evasion. If someone discovers your model, they'll craft packets to slip past it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3 id=&quot;stack&quot;&gt;Stack&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Go&lt;/code&gt; · &lt;code&gt;Python&lt;/code&gt; · &lt;code&gt;PyTorch&lt;/code&gt; · &lt;code&gt;ONNX&lt;/code&gt; · &lt;code&gt;FastAPI&lt;/code&gt; · &lt;code&gt;React 19&lt;/code&gt; · &lt;code&gt;Vite&lt;/code&gt; · &lt;code&gt;Tailwind CSS&lt;/code&gt; · &lt;code&gt;ECharts&lt;/code&gt; · &lt;code&gt;AG Grid&lt;/code&gt; · &lt;code&gt;Apollo Client&lt;/code&gt; · &lt;code&gt;GraphQL (gqlgen)&lt;/code&gt; · &lt;code&gt;Firebase Auth&lt;/code&gt; · &lt;code&gt;SQLite&lt;/code&gt; · &lt;code&gt;scapy&lt;/code&gt; · &lt;code&gt;GeoIP2&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://satyasaikilaru.vercel.app/&quot;&gt;Portfolio&lt;/a&gt;&lt;/strong&gt; · &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/SatyaKilaru&quot;&gt;GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you're building something similar or want to discuss the architecture — connect with me on &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/satya-sai-kilaru-09634a1b7/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18965/building-a-real-time-network-anomaly-detector-with-pytorch-and-go</guid>
<pubDate>Tue, 26 May 2026 07:41:30 +0000</pubDate>
</item>
</channel>
</rss>