Stairs vs. Non-Stairs Image Classifier
This model classifies photographs as non-stairs (0) or stairs (1). It fine-tunes a pretrained ResNet-18 with AutoGluon MultiModal.
Inputs and outputs
Supply a pandas DataFrame with an image column of local image-file paths. predict() returns 0 or 1, and predict_proba() returns class probabilities.
| Label | Meaning |
|---|---|
0 |
Non-stairs |
1 |
Stairs |
Input resolution and expected preprocessing
| Stage | Processing |
|---|---|
| Dataset (before the model) | RGB, 224 Γ 224, aspect ratio preserved with gray padding |
| Model, training | Resize shorter side to 224, center crop 224 Γ 224, TrivialAugment, ImageNet normalization |
| Model, inference | Resize shorter side to 224, center crop 224 Γ 224, ImageNet normalization |
Prepare new photos the same way as the dataset: convert to RGB and pad to a square before resizing. Otherwise, the center crop removes the edges of non-square photos, which may cut off the stairs.
Data and training
Source: Stairs vs. non-stairs photographs. Published splits were used unchanged.
| Partition | Original photos | Stored variants | Total | Non-stairs / stairs |
|---|---|---|---|---|
| Training | 22 | 352 | 374 | 187 / 187 |
| Validation | 5 | 0 | 5 | 2 / 3 |
| Test | 5 | 0 | 5 | 3 / 2 |
Augmentation pipeline. Augmentation happens at two stages. The dataset stores offline variants of each training original, listed below; the dataset card documents transform strengths. Variants stay in training, and no parent_id crosses splits. During fitting, AutoMM also applies TrivialAugment on the fly, choosing one random operation per image per batch. Validation and test receive neither.
| Stored augmentation | Training rows |
|---|---|
mild_brightness |
88 |
mild_contrast |
88 |
mild_gaussian_blur |
88 |
none (originals) |
22 |
small_rotation |
88 |
| Training setting | Recorded value |
|---|---|
| Framework | AutoGluon MultiModal 1.6.1 |
| Image backbone | timm resnet18, pretrained, fully fine-tuned (11.2 M parameters) |
| Preset and branch | medium_quality; model.names = ["timm_image"] |
| Search space | None; backbone fixed, other hyperparameters at preset defaults |
| Selection metric | Validation accuracy |
| Fit budget and seed | 900 s; 24679 |
| Precision | 16-bit automatic mixed precision (AMP) |
| Measured training | 56.7 s; early stopping in epoch 8 (26 steps) after 10 validation checks without improvement |
| Checkpoint selection | Greedy-soup fusion of top 3 checkpoints (steps 11, 13, 14; each 0.80 val accuracy) |
| Environment | Colab GPU runtime: 1 CUDA GPU (14.6 GB), 2 vCPU, 12.7 GB RAM; Linux; Python 3.13.15; PyTorch 2.11.0+cu128; CUDA 12.8 |
Evaluation
| Metric | Validation (5) | Test (5) |
|---|---|---|
| Accuracy | 0.800 (4/5) | 0.800 (4/5) |
| Weighted F1 | 0.800 | 0.781 |
| Baseline accuracy, always non-stairs | β | 0.600 |
Test confusion matrix:
| Actual / predicted | Non-stairs | Stairs |
|---|---|---|
| Non-stairs | 3 | 0 |
| Stairs | 1 | 1 |
Validation confusion matrix:
| Actual / predicted | Non-stairs | Stairs |
|---|---|---|
| Non-stairs | 2 | 0 |
| Stairs | 1 | 2 |
Validation accuracy reached 0.80 at step 11 and did not improve after epoch 4, so early stopping ended training at 56.7 s.
Known failure modes
- Missed stairs. The model leans toward non-stairs. The only validation error and the only test error are both stairs photos predicted as non-stairs.
- Few independent scenes. There are 22 training originals; the 352 variants alter lighting and geometry but add no new scenes. Backgrounds, lighting, and camera angle may act as shortcuts.
- Untested inputs. Performance is not established on unpadded or non-square photos, other buildings, or stair-like patterns such as ramps, railings, and striped floors.
Load and predict
import zipfile
import pandas as pd
from huggingface_hub import hf_hub_download
from autogluon.multimodal import MultiModalPredictor
archive = hf_hub_download("pcwoods/2026-24679-stairs-autogluon-predictor", "autogluon_image_predictor_dir.zip")
zipfile.ZipFile(archive).extractall("stairs_model")
predictor = MultiModalPredictor.load("stairs_model")
print(predictor.predict(pd.DataFrame({"image": ["/path/to/photo.png"]})))
Licensing and provenance
The model is released under Apache-2.0; the pretrained ResNet-18 weights keep their upstream terms. The dataset card specifies no license and states that images were reviewed to exclude people and identifying information.
AI usage disclosure
Claude was utilized to help modify an existing notebook template. Additionally, Claude was used to assist with model card creation.