Training Image Classification Models (ResNet, EfficientNet, ViT)

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
Training Image Classification Models (ResNet, EfficientNet, ViT)
Medium
~5 days
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1320
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1226
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    927
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1161
  • image_logo-advance_0.webp
    B2B Advance company logo design
    622
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    897

Our image classification model training services cover ResNet, EfficientNet, and ViT. We often encounter this scenario: a client brings a dataset of 500 images, split into 10 classes, and asks us to train a ResNet-50. It sounds like a typical task, but without the right strategy, the result is 65% accuracy with overfitting. Our experience shows that success hinges on three factors: choosing the right architecture for the data volume, addressing class imbalance, and preparing the model for production. Our approach yields 2x faster convergence compared to standard training. Here’s how we tackle these challenges and what our work includes.

Our team of certified engineers with over 5 years of experience in Computer Vision has completed more than 50 image classification projects, including medical and industrial applications. Timely defect detection using trained models saves clients up to 2 million rubles per year – a concrete saving of $20,000 annually.

Case Study: Casting Defect Classification in Manufacturing

We were approached by an aluminum casting plant. The goal: classify 12 defect types from conveyor camera images. Data: 15,000 images with severe imbalance — one class made up 60% of the sample, rare defects had fewer than 100 examples. We chose EfficientNet-B4 pretrained on ImageNet, applied Focal Loss (gamma=2.0), and aggressive augmentation (RandomErasing, CutMix). Macro F1 improved from 0.32 to 0.89 — a 2.8x improvement. Inference time on CPU with ONNX: 8 ms per image. The plant deployed the model in their quality control line, reducing manual inspection costs by 1.5 million rubles annually.

How to Choose an Architecture for Your Dataset

Dataset Size Recommendation Why
<500 examples/class EfficientNet-B0/B2 (frozen → partial unfreeze) Fewer parameters reduce overfitting
500–5000/class EfficientNet-B4, ConvNeXt-T, ResNet-50 Balance between accuracy and training speed
>5000/class ViT-B/16, ConvNeXt-S/B Transformers excel with large data
Medical, small data ResNet-50 with MedNet pretraining Domain-specific pretraining over raw architecture
Edge / mobile MobileNetV3-Large, EfficientNet-Lite Latency under 10ms on a phone

EfficientNet-B0 is 8x faster and 4x smaller than ResNet-50 while achieving comparable accuracy, making it ideal for small datasets.

Step-by-Step Model Training Process

  1. Dataset analysis — evaluate annotation quality, compute class distribution, identify noise.
  2. Strategy selection — choose architecture, augmentations, and loss function (e.g., Focal Loss for imbalance).
  3. Experiments — run a series of training sessions with different configs on Weights & Biases.
  4. Fine-tuning — two-phase training for ViT: train only the head first, then gradually unfreeze blocks.
  5. Testing — evaluate on validation with TTA, export to ONNX, and measure latency.
  6. Model delivery — documentation, inference scripts, containerization (Docker) for easy integration.

Two-Phase Training with ViT on Small Datasets

ViT trained on 300 examples without a proper strategy yields 65% accuracy, while EfficientNet scores 84%. The reason: attention heads overfit faster on small datasets than the convolutional inductive bias in ResNet. The solution: aggressive freezing + gradual unfreezing:

import timm
import torch
import torch.nn as nn
from torch.optim import AdamW
from torch.optim.lr_scheduler import CosineAnnealingLR

def train_vit_two_phase(
    num_classes: int,
    train_loader,
    val_loader,
    phase1_epochs: int = 20,
    phase2_epochs: int = 60,
    device: str = 'cuda'
) -> nn.Module:
    model = timm.create_model(
        'vit_base_patch16_224',
        pretrained=True,
        num_classes=num_classes,
        drop_rate=0.1,
        drop_path_rate=0.1
    ).to(device)

    # PHASE 1: train only the head
    for name, param in model.named_parameters():
        param.requires_grad = 'head' in name

    opt1 = AdamW(
        filter(lambda p: p.requires_grad, model.parameters()),
        lr=1e-3, weight_decay=0.05
    )
    sched1 = CosineAnnealingLR(opt1, T_max=phase1_epochs, eta_min=1e-5)

    for epoch in range(phase1_epochs):
        _train_epoch(model, train_loader, opt1, device)
        sched1.step()

    # PHASE 2: unfreeze the last 6 blocks (out of 12)
    for name, param in model.named_parameters():
        if any(f'blocks.{i}.' in name for i in range(6, 12)):
            param.requires_grad = True

    opt2 = AdamW([
        {'params': model.head.parameters(),        'lr': 5e-5},
        {'params': [p for n, p in model.named_parameters()
                    if 'blocks' in n and p.requires_grad], 'lr': 5e-6}
    ], weight_decay=0.05)
    sched2 = CosineAnnealingLR(opt2, T_max=phase2_epochs, eta_min=1e-7)

    for epoch in range(phase2_epochs):
        _train_epoch(model, train_loader, opt2, device)
        _validate(model, val_loader, device)
        sched2.step()

    return model

def _train_epoch(model, loader, optimizer, device):
    model.train()
    criterion = nn.CrossEntropyLoss(label_smoothing=0.1)
    for images, labels in loader:
        images, labels = images.to(device), labels.to(device)
        optimizer.zero_grad()
        loss = criterion(model(images), labels)
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
        optimizer.step()

How to Handle Class Imbalance?

94% accuracy with a 1:200 imbalance usually means the model predicts only the majority class. Metrics for imbalance: macro F1, balanced accuracy, per-class recall. Lin et al. proposed Focal Loss, which we adapt to the task.

import torch
import torch.nn.functional as F

class FocalLoss(nn.Module):
    def __init__(self, alpha: float = 1.0, gamma: float = 2.0,
                 class_weights: torch.Tensor = None):
        super().__init__()
        self.alpha = alpha
        self.gamma = gamma
        self.class_weights = class_weights

    def forward(self, inputs: torch.Tensor,
                targets: torch.Tensor) -> torch.Tensor:
        ce_loss = F.cross_entropy(
            inputs, targets, weight=self.class_weights, reduction='none'
        )
        pt = torch.exp(-ce_loss)
        focal_loss = self.alpha * (1 - pt) ** self.gamma * ce_loss
        return focal_loss.mean()

# Class weights inversely proportional to frequency
class_counts = torch.tensor([10000, 500, 80], dtype=torch.float)
class_weights = (1.0 / class_counts).to(device)
criterion = FocalLoss(gamma=2.0, class_weights=class_weights)

How to Speed Up Inference Without Losing Accuracy?

Test Time Augmentation (TTA) is a simple way to boost accuracy by 1–3% without retraining: run several augmented versions of an image and average the predictions.

import torchvision.transforms as T

class TTAClassifier:
    def __init__(self, model: nn.Module, n_augments: int = 5):
        self.model = model.eval()
        self.n_augments = n_augments
        self.base_transform = T.Compose([
            T.Resize(256), T.CenterCrop(224),
            T.ToTensor(),
            T.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
        ])
        self.tta_transforms = [
            T.Compose([T.Resize(256), T.CenterCrop(224),
                       T.RandomHorizontalFlip(p=1.0),
                       T.ToTensor(),
                       T.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),
            T.Compose([T.Resize(224), T.ToTensor(),
                       T.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),
        ]

    @torch.no_grad()
    def predict(self, image) -> torch.Tensor:
        preds = [
            torch.softmax(self.model(self.base_transform(image).unsqueeze(0)), dim=1)
        ]
        for transform in self.tta_transforms:
            preds.append(
                torch.softmax(self.model(transform(image).unsqueeze(0)), dim=1)
            )
        return torch.stack(preds).mean(dim=0)

Export for Production

# ONNX export — for CPU/TensorRT deployment
dummy = torch.randn(1, 3, 224, 224, device='cpu')
torch.onnx.export(
    model.cpu().eval(),
    dummy,
    'classifier.onnx',
    opset_version=17,
    input_names=['image'],
    output_names=['logits'],
    dynamic_axes={'image': {0: 'batch'}, 'logits': {0: 'batch'}}
)

Using ONNX can reduce GPU costs by up to 40% due to optimized CPU inference.

What’s Included in Our Work

  • Dataset analysis: quality assessment, imbalance, augmentation selection.
  • Architecture and training strategy tailored to your data.
  • Pipeline implementation in PyTorch / Hugging Face.
  • Hyperparameter tuning, metric logging (Weights & Biases).
  • Testing with TTA and export to ONNX / TensorRT.
  • Documentation, model files, and inference scripts.
  • Access to model, training scripts, and 30-day support.
  • Consultation for integration by your developers.

Typical project investment ranges from $5,000 to $50,000, depending on complexity.

Timelines

Task Timeline
Fine-tuning a ready architecture (data prepared) 1–3 weeks
Training from scratch + augmentations + optimization 4–7 weeks
Developing a custom architecture for a domain 8–14 weeks

Want a similar model for your project? Contact us to discuss your dataset and find the optimal solution. Order model training and get a consultation with a precise timeline estimate.