83 lines
2.7 KiB
Markdown
83 lines
2.7 KiB
Markdown
# Accidental Classifier
|
|
|
|
A small CNN that classifies musical accidentals — **sharp**, **flat**, and **natural** — from cropped grayscale images of engraved scores.
|
|
|
|
Trained on crops extracted from the [PrIMuS dataset](https://grfia.dlsi.ua.es/primus/) and achieves **100% accuracy** on a held-out test set (750 samples).
|
|
|
|
```
|
|
Confusion matrix (rows=true, cols=predicted):
|
|
flat natural sharp
|
|
flat 250 0 0
|
|
natural 0 250 0
|
|
sharp 0 0 250
|
|
```
|
|
|
|
## Architecture
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Input** | 1 × 40 × 40 grayscale |
|
|
| **Backbone** | 3 conv blocks (16 → 32 → 64 channels), each with BatchNorm + ReLU + MaxPool |
|
|
| **Head** | Dropout → FC(1600, 64) → ReLU → Dropout → FC(64, 3) |
|
|
| **Parameters** | ~115 k |
|
|
| **Output** | 3-class logits (flat / natural / sharp) |
|
|
|
|
A saved ONNX export is also produced by `train.py` for inference via OpenCV's `dnn` module.
|
|
|
|
## Repository layout
|
|
|
|
```
|
|
train.py Training pipeline (CNN + augmentation + weighted sampling)
|
|
eval.py Evaluate saved checkpoint on the held-out test set
|
|
extract_accidentals.py Extract accidental crops from PrIMuS MEI files via Verovio
|
|
extract_fast.py Faster single-font variant of the extractor
|
|
explore_dataset.py Explore PrIMuS agnostic encodings and image statistics
|
|
segment_test.py Connected-component symbol segmentation experiment
|
|
model/
|
|
accidental_classifier.pt Saved PyTorch weights (best validation accuracy)
|
|
```
|
|
|
|
## Pipeline
|
|
|
|
### 1. Extract crops
|
|
|
|
Render each PrIMuS MEI file with [Verovio](https://www.verovio.org/), locate accidental glyphs (SMuFL codepoints E260/E261/E262) in the SVG, rasterize with cairosvg, and crop each symbol into `crops/{flat,natural,sharp}/`.
|
|
|
|
```bash
|
|
python extract_fast.py
|
|
```
|
|
|
|
### 2. Train
|
|
|
|
Loads all crops into RAM, applies a stratified train/val/test split (seed 42), trains with data augmentation (random affine + erasing) and class-balanced sampling, and saves the best checkpoint.
|
|
|
|
```bash
|
|
python train.py
|
|
```
|
|
|
|
### 3. Evaluate
|
|
|
|
Reproduces the identical test split and reports accuracy, per-class metrics, the confusion matrix, and sample misclassifications.
|
|
|
|
```bash
|
|
python eval.py
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
- Python 3.10+
|
|
- PyTorch
|
|
- torchvision
|
|
- NumPy
|
|
- Pillow
|
|
- OpenCV (`cv2`) — for ONNX verification and segmentation experiments
|
|
- Verovio (Python bindings) — for crop extraction only
|
|
- cairosvg — for crop extraction only
|
|
|
|
## Data
|
|
|
|
Training data is derived from [PrIMuS](https://grfia.dlsi.ua.es/primus/) (Calvo-Zaragoza & Rizo, 2018). The extracted crops and raw dataset are not included in this repository due to size.
|
|
|
|
## License
|
|
|
|
This project is released into the public domain.
|