File size: 5,934 Bytes
613d6a6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
---
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) |

<details>
<summary>Full per-class classification report (test set)</summary>

```text
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.

</details>

![Confusion matrix](confusion_matrix_test.png)
![Training curves](training_curves.png)

## 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

```python
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`](https://github.com/Sehastrajit-S/defect-vision/blob/main/src/app/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.