Sehastrajit's picture
Add EfficientNet-B2 defect classifier: weights, model card, eval artifacts
613d6a6 verified
|
Raw
History Blame Contribute Delete
5.93 kB
metadata
license: other
license_name: intel-challenge-dataset
license_link: LICENSE
tags:
  - pytorch
  - image-classification
  - efficientnet
  - defect-detection
  - defect-classification
  - semiconductor
  - wafer-inspection
  - manufacturing
  - few-shot-learning
  - small-sample-learning
  - computer-vision
library_name: pytorch
pipeline_tag: image-classification
metrics:
  - accuracy
  - f1
model-index:
  - name: defect-vision-efficientnet-b2
    results:
      - task:
          type: image-classification
        metrics:
          - type: accuracy
            value: 0.9556
            name: Test accuracy
          - type: accuracy
            value: 0.975
            name: Best validation accuracy

Defect Vision: EfficientNet-B2 Semiconductor Defect Classifier

Fine-tuned EfficientNet-B2 for small-sample wafer defect classification, built for the Intel Semiconductor Solutions Challenge 2026, Problem A: Small-Sample Learning for Defect Classification.

Classifies gray-scale wafer/die images into 8 defect classes + "no defect" (9-way), trained on a class-balanced, heavily-augmented small dataset rather than large-scale labeled data. The challenge's core constraint is that production defect data is scarce and imbalanced.

  • Code, FastAPI service, React demo UI, training notebook: https://github.com/Sehastrajit-S/defect-vision
  • Backbone: torchvision.models.efficientnet_b2 (ImageNet-pretrained), custom classifier head
  • Params: ~9.2M
  • Input: 260×260 RGB (gray-scale images converted to 3-channel), ImageNet normalization

Results

Metric Target (challenge brief) Achieved
Overall classification accuracy ~85% 95.6% (test, 360 held-out images)
Best validation accuracy n/a 97.5%
Inference latency ~1s/image ~40–500ms/image (GPU), ~0.1–1s (CPU)
Full per-class classification report (test set)
Test Loss : 0.6153  |  Test Accuracy : 0.9556

              precision    recall  f1-score   support

     defect1     0.9773    0.9556    0.9663        45
     defect2     0.9375    1.0000    0.9677        45
     defect3     1.0000    1.0000    1.0000        45
     defect4     1.0000    1.0000    1.0000        45
     defect5     0.9130    0.9333    0.9231        45
     defect8     0.8837    0.8444    0.8636        45
     defect9     0.9556    0.9556    0.9556        45
    defect10     0.9773    0.9556    0.9663        45
    new_good     0.0000    0.0000    0.0000         0

    accuracy                         0.9556       360
   macro avg     0.8494    0.8494    0.8492       360
weighted avg     0.9555    0.9556    0.9553       360

new_good (no defect) has zero held-out samples in this dataset revision. The 9th output neuron is reserved for future "no defect found" imagery without requiring re-architecture.

Confusion matrix Training curves

Handling class imbalance with few samples

  • Class-balanced dataset construction: equal train/val/test counts per class (210/45/45) via augmentation, instead of naive minority oversampling or loss reweighting, so the model never learns a majority-class prior.
  • Aggressive augmentation: random crop, flips, rotation, perspective warp, and color jitter multiply the small per-class sample count without duplicating exact pixels.
  • Label smoothing (0.1) on cross-entropy keeps the model from over-committing on visually similar defect types.
  • OneCycleLR + early stopping (patience 7) for fast, stable convergence on limited data. This checkpoint converged and early-stopped at epoch 16.

Usage

import torch
import torch.nn as nn
from torchvision import models, transforms
from PIL import Image
from huggingface_hub import hf_hub_download

CLASSES = ["defect1", "defect2", "defect3", "defect4", "defect5",
           "defect8", "defect9", "defect10", "new_good"]

def build_model(num_classes: int) -> nn.Module:
    model = models.efficientnet_b2(weights=None)
    in_f = model.classifier[1].in_features
    model.classifier = nn.Sequential(
        nn.Dropout(p=0.4),
        nn.Linear(in_f, 512),
        nn.SiLU(inplace=True),
        nn.Dropout(p=0.3),
        nn.Linear(512, num_classes),
    )
    return model

weights_path = hf_hub_download(repo_id="Sehastrajit/defect-vision-efficientnet-b2", filename="best_model.pth")
model = build_model(len(CLASSES))
ckpt = torch.load(weights_path, map_location="cpu", weights_only=False)
model.load_state_dict(ckpt["model_state"])
model.eval()

transform = transforms.Compose([
    transforms.Resize((260, 260)),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])

img = Image.open("wafer_sample.png").convert("RGB")
x = transform(img).unsqueeze(0)
with torch.no_grad():
    probs = torch.softmax(model(x), dim=1)[0]

pred = CLASSES[probs.argmax().item()]
print(pred, probs.max().item())

Training setup

GPU NVIDIA RTX 3060 12GB (fp16 AMP)
Optimizer AdamW, lr 2e-4, weight decay 1e-4
Schedule OneCycleLR, cosine anneal
Batch 64 × 2 grad-accum steps (effective 128)
Split 70% train / 15% val / 15% test
Epochs early-stopped at 16 (patience 7)

Full training script: h1.ipynb in the main repo.

Intended use & limitations

Built as a challenge submission demonstrating small-sample defect classification technique, not validated for production fab deployment. Trained on Intel-provided sample imagery for the Semiconductor Solutions Challenge 2026; new_good has no held-out evaluation samples in this dataset revision. Intel and the Intel logo are trademarks of Intel Corporation or its subsidiaries. This is an independent student project, not an Intel product.