Poneglyph Page Type Classifier
A MobileNetV3-Small classifier trained on full manga volumes (One Piece tomes 1 to 7) to automatically detect page types:
cover: Volume covers, inner covers, chapter cover/title pagesstory_page: Narrative manga reading pagesannexe: SBS (question/answer corners), fan art galleries, author notes, bonus pagessummary: Table of contents / volume summaries
Model Description
- Architecture: MobileNetV3-Small
- Input shape:
[1, 3, 224, 224](RGB) - Output shape:
[1, 4](logits) - Class order:
['cover', 'story_page', 'annexe', 'summary'] - Preprocessing:
- Resize shortest edge to 256
- Center crop 224x224
- ImageNet normalization: Mean
[0.485, 0.456, 0.406], Std[0.229, 0.224, 0.225]
- Formats provided:
page_type_classifier.onnx: Static FP32 ONNX model for browser (onnxruntime-web) and backend execution (onnxruntime)final.pt: PyTorch weights checkpointpage_type_classifier.metadata.json: Full preprocessing and class contractmetrics.json: Detailed training and evaluation metrics
Dataset Statistics
The dataset was directly extracted from authentic CBZ manga volumes (One Piece tomes 1 to 7) and 100% human-validated.
| Tome | Total Pages | Story Page | Annexe | Cover | Summary |
|---|---|---|---|---|---|
| One Piece T01 | 210 | 187 | 15 | 7 | 1 |
| One Piece T02 | 211 | 167 | 33 | 10 | 1 |
| One Piece T03 | 213 | 172 | 31 | 9 | 1 |
| One Piece T04 | 196 | 165 | 21 | 9 | 1 |
| One Piece T05 | 196 | 164 | 22 | 9 | 1 |
| One Piece T06 | 193 | 158 | 25 | 9 | 1 |
| One Piece T07 (Held-out Test) | 196 | 164 | 22 | 9 | 1 |
| TOTAL | 1 415 | 1 177 | 169 | 62 | 7 |
Evaluation Results (Held-out Tome 7)
Evaluation performed on One Piece Tome 7 (196 pages), completely held-out during training:
- Overall Accuracy: 99.49% (195 / 196 correct)
- Macro F1-Score: 0.9845
- Validation Loss: 0.0476
Detailed Per-Class Metrics
| Class | Support | Precision | Recall | F1-Score |
|---|---|---|---|---|
annexe |
22 | 100.0% | 100.0% | 1.000 |
summary |
1 | 100.0% | 100.0% | 1.000 |
story_page |
164 | 99.39% | 100.0% | 0.997 |
cover |
9 | 100.0% | 88.89% | 0.941 |
Confusion Matrix
Predicted
cover story_page annexe summary
cover 8 1 0 0
story_page 0 164 0 0
annexe 0 0 22 0
summary 0 0 0 1
Usage
Python (ONNX Runtime)
import numpy as np
import onnxruntime as ort
from PIL import Image
session = ort.InferenceSession("page_type_classifier.onnx", providers=["CPUExecutionProvider"])
classes = ["cover", "story_page", "annexe", "summary"]
image = Image.open("page.jpg").convert("RGB")
w, h = image.size
scale = 256.0 / min(w, h)
image = image.resize((int(round(w * scale)), int(round(h * scale))), Image.Resampling.BILINEAR)
left = (image.width - 224) // 2
top = (image.height - 224) // 2
image = image.crop((left, top, left + 224, top + 224))
arr = np.array(image, dtype=np.float32) / 255.0
mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
arr = (arr - mean) / std
arr = np.transpose(arr, (2, 0, 1))
tensor = np.expand_dims(arr, axis=0)
logits = session.run(None, {"input": tensor})[0][0]
probs = np.exp(logits - np.max(logits))
probs /= probs.sum()
predicted_class = classes[int(np.argmax(probs))]
print(predicted_class, probs)