VyntriVyntri
Notebooks

01 — Your First Vyntri Model

Core workflow tutorial covering fit, evaluate, predict, and save/load.

This tutorial covers the core workflow: fit a dataset, evaluate, predict, and save/load.

Setup

install
pip install vyntri
imports
from pathlib import Path
import numpy as np
from PIL import Image
from vyntri import Vyntri
from vyntri.data import split

1. Create a dataset

Vyntri expects one folder per class. Replace with your own photos — the layout is all Vyntri needs.

create_dataset
def make_solid(root, classes, per_class, seed=0):
    colors = {'cats': (200, 90, 40), 'dogs': (40, 180, 70), 'birds': (50, 80, 200)}
    root = Path(root)
    rng = np.random.default_rng(seed)
    for name in classes:
        folder = root / name
        folder.mkdir(parents=True, exist_ok=True)
        for j in range(per_class):
            noise = rng.normal(0, 6, (32, 32, 3))
            base = np.asarray(colors[name], dtype=np.float64).reshape(1, 1, 3)
            img = (base + noise).clip(0, 255).astype(np.uint8)
            Image.fromarray(img).save(folder / f'{name}_{j:02d}.png')
    return root

DATA = Path('cats_dogs')
train = make_solid(DATA / 'train', ['cats', 'dogs', 'birds'], per_class=12, seed=1)
test = make_solid(DATA / 'test', ['cats', 'dogs', 'birds'], per_class=8, seed=99)
print('train folder:', train)
print('test folder :', test)

2. Create split and fit

Use split() to create explicit train/validation partitions. Then fit extracts frozen MobileNetV3-Small features (cached on disk), fits the FK projection, and solves the analytic ridge classifier.

fit
# Create an explicit split from the folder-per-class training data
s = split(str(train), train=0.8, val=0.2, seed=42)

model = Vyntri(seed=42)
model.fit(train=s.train, val=s.val, progress=False)
print()
print(model.summary())

3. Evaluate

evaluate() is observational — it never changes the model. It reports accuracy, macro/weighted F1, balanced accuracy, and a confusion matrix.

evaluate
# Evaluate on the separate test set
from vyntri.data import FolderDataset
test_ds = FolderDataset(str(test))
result = model.evaluate(test_ds)
print(f'accuracy      = {result.accuracy:.3f}')
print(f'macro F1      = {result.macro_f1:.3f}')
print(f'weighted F1   = {result.weighted_f1:.3f}')
print(f'balanced acc  = {result.balanced_accuracy:.3f}')
print(f'samples       = {result.n_samples}')
print('confusion matrix (rows=true, cols=pred):')
print(result.confusion_matrix)

4. Predictions

A single image, or a whole folder — filenames are preserved and you can write a CSV.

predict
img = str(train / 'cats' / 'cats_00.png')
pred = model.predict(img)
print(f"{img}: {pred.label} ({pred.confidence:.3f})")
predict_batch
batch = model.predict_batch(str(test), out_path='predictions.csv')
print(f'{len(batch.paths)} predictions written to predictions.csv')
for p, label in list(zip(batch.paths, batch.labels))[:3]:
    print(f'  {Path(p).parent.name:>6} -> {label}')

5. Save and load

Predictions after loading match the original model within numerical tolerance.

save_load
model.save('model.vyntri')
loaded = Vyntri.load('model.vyntri')
print(loaded.predict(img))