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 |
| Measured training |
915.6 s; stopped by time limit in epoch 7 (22 steps) |
| Checkpoint selection |
Greedy-soup fusion of top 3 checkpoints (steps 11, 13, 14; each 0.80 val accuracy) |
| Environment |
Colab CPU (2 vCPU, 12.7 GB RAM, no GPU); Linux; Python 3.13.15; PyTorch 2.11.0+cpu |
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 |
A 900s run resulted in validation accuracy of 0.80 by step 11. It did not improve after epoch 4.
Known failure modes
- Missed stairs. The model leans toward non-stairs. The shorter run predicted it for every image, and the test error in this run is a stairs photo labeled 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"]})))
Both artifacts use pickle, so load only trusted files.
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.