A high-performance FastAPI application for cat-dog image classification with six progressive model versions (v1-v6) using advanced neural network architectures including Kolmogorov-Arnold Networks (KAN).
- Overview
- Features
- Requirements
- Installation
- Configuration
- Running the Application
- API Endpoints
- Project Architecture
- Models
- Docker Deployment
- Troubleshooting
KAN-Fast-API is a production-ready FastAPI application that provides multiple endpoints for cat-dog image classification. The application features six different model architectures representing an evolution of approaches:
- v1: SimpleCNN - Traditional CNN-based classifier
- v2: KAN-based CNN - Kolmogorov-Arnold Network enhanced classifier
- v3: Advanced KAN CNN - Enhanced version with optimized preprocessing
- v4: Improved KAN Architecture - Refined KAN-CNN hybrid with better performance
- v5: Optimized KAN v5 - Production-optimized KAN model with checkpoint support
- v6: Latest KAN Model - State-of-the-art KAN implementation with best_kan_model_v6
Each version runs independently and can be accessed through its own API endpoint.
- Multiple Model Versions: Three independent model architectures for classification
- FastAPI Framework: High-performance, easy-to-use Python web framework
- CORS Support: Cross-Origin Resource Sharing enabled for all endpoints
- Image Upload Support: Direct image file uploads via multipart form data
- Batch Processing Ready: Supports multiple concurrent requests
- Model Caching: Efficient model loading and caching to reduce latency
- Dark Theme Swagger UI: Professional documentation interface
- Docker Support: Fully containerized deployment ready
- Error Handling: Comprehensive validation and error responses
- Python: 3.8 or higher
- pip: Latest version
- Virtual Environment: Recommended (venv, virtualenv, or conda)
- Disk Space: Minimum 2GB (for models and dependencies)
- RAM: Minimum 4GB (recommended 8GB for smooth operation)
fastapi - Web framework
uvicorn[standard] - ASGI server
torch - Deep learning framework
torchvision - Computer vision utilities
pillow - Image processing
pydantic-settings - Configuration management
fastapi-swagger-dark - Dark theme for Swagger UI
All dependencies are listed in requirements.txt.
git clone <repository-url>
cd KAN-Fast-APIUsing venv (Python 3.8+):
python -m venv .venvActivate the virtual environment:
-
Windows:
.venv\Scripts\activate
-
macOS/Linux:
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txtpython -c "import torch; print(f'PyTorch version: {torch.__version__}')"
python -c "import fastapi; print(f'FastAPI version: {fastapi.__version__}')"The application automatically resolves model paths relative to the project root. Configuration is managed in app/core/config.py:
MODEL_PATH = "models/simple_cnn_model.pth" # v1 model
MODEL_PATH_V2 = "models/cat_dog_cnn_kan_model.pth" # v2 model
MODEL_PATH_V3 = "models/checkpoint.pth" # v3 modelYou can override settings using a .env file:
IMAGE_WIDTH=150
IMAGE_HEIGHT=150
UPLOAD_FOLDER=static/images
ALLOWED_IMAGE_TYPES=["image/jpeg", "image/png", "image/jpg"]
- Image Dimensions:
- v1 & v2: 150x150 pixels
- v3: 224x224 pixels
- Supported Formats: JPEG, PNG, JPG
- Upload Folder:
static/images/
uvicorn app.main:app --reloadThe application will start at: http://localhost:8000
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4uvicorn app.main:app --port 9000- Swagger UI (Dark Theme):
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc(if enabled)
All endpoints follow RESTful conventions and return JSON responses.
URL: /api/v1/predict
Method: POST
Description: Predicts cat/dog classification using the SimpleCNN model.
Request:
curl -X POST "http://localhost:8000/api/v1/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response (Success - 200):
{
"prediction": "cat",
"probability": 0.8234,
"url": "http://localhost:8000/static/images/image_abc123.jpg"
}Response (Error - 400):
{
"message": "Only JPEG, PNG, and JPG images are allowed."
}URL: /api/v2/predict
Method: POST
Description: Predicts cat/dog classification using the KAN-based CNN model.
Request:
curl -X POST "http://localhost:8000/api/v2/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response:
{
"prediction": "dog",
"probability": 0.9156,
"url": "http://localhost:8000/static/images/image_xyz789.jpg"
}URL: /api/v3/predict
Method: POST
Description: Predicts cat/dog classification using the advanced KAN CNN model with enhanced preprocessing.
Request:
curl -X POST "http://localhost:8000/api/v3/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response:
{
"prediction": "cat",
"probability": 0.7845,
"url": "http://localhost:8000/static/images/image_def456.jpg"
}URL: /api/v4/predict
Method: POST
Description: Predicts cat/dog classification using the improved KAN architecture.
Request:
curl -X POST "http://localhost:8000/api/v4/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response:
{
"prediction": "dog",
"probability": 0.8923,
"url": "http://localhost:8000/static/images/image_ghi789.jpg"
}URL: /api/v5/predict
Method: POST
Description: Predicts cat/dog classification using the optimized KAN v5 model (20 epochs).
Request:
curl -X POST "http://localhost:8000/api/v5/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response:
{
"prediction": "cat",
"probability": 0.9234,
"url": "http://localhost:8000/static/images/image_jkl012.jpg"
}URL: /api/v6/predict
Method: POST
Description: Predicts cat/dog classification using the latest KAN model (v6) with state-of-the-art performance. Recommended for production use.
Request:
curl -X POST "http://localhost:8000/api/v6/predict" \
-H "accept: application/json" \
-F "file=@path/to/image.jpg"Response:
{
"prediction": "dog",
"probability": 0.9567,
"url": "http://localhost:8000/static/images/image_mno345.jpg"
}URL: /api/v1/
Method: GET
Description: Returns a simple health check response.
Response:
{
"Hello": "World"
}URL: /api/v1/upload-image
Method: POST
Description: Uploads an image and returns the public URL without running prediction.
Request:
curl -X POST "http://localhost:8000/api/v1/upload-image" \
-F "file=@path/to/image.jpg"Response:
{
"filename": "image.jpg",
"url": "http://localhost:8000/static/images/image_abc123.jpg"
}"probability": 0.7845, "url": "http://localhost:8000/static/images/image_def456.jpg" }
---
### Health Check Endpoint (v1)
**URL:** `/api/v1/`
**Method:** `GET`
**Description:** Returns a simple health check response.
**Response:**
```json
{
"Hello": "World"
}
URL: /api/v1/upload-image
Method: POST
Description: Uploads an image and returns the public URL without running prediction.
Request:
curl -X POST "http://localhost:8000/api/v1/upload-image" \
-F "file=@path/to/image.jpg"Response:
{
"filename": "image.jpg",
"url": "http://localhost:8000/static/images/image_abc123.jpg"
}KAN-Fast-API/
├── app/
│ ├── api/
│ │ ├── v1/ # v1 API routes
│ │ │ ├── api.py
│ │ │ └── endpoints/
│ │ │ ├── health.py
│ │ │ ├── prediction.py
│ │ │ └── upload.py
│ │ ├── v2/ # v2 API routes
│ │ │ ├── api.py
│ │ │ └── endpoints/
│ │ │ └── prediction.py
│ │ ├── v3/ # v3 API routes
│ │ │ ├── api.py
│ │ │ └── endpoints/
│ │ │ └── prediction.py
│ │ ├── v4/ # v4 API routes
│ │ │ ├── api.py
│ │ │ └── endpoints/
│ │ │ └── prediction.py
│ │ ├── v5/ # v5 API routes
│ │ │ ├── api.py
│ │ │ └── endpoints/
│ │ │ └── prediction.py
│ │ └── v6/ # v6 API routes
│ │ ├── api.py
│ │ └── endpoints/
│ │ └── prediction.py
│ ├── core/
│ │ └── config.py # Configuration settings
│ ├── ml/
│ │ ├── v1/ # v1 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ └── __init__.py
│ │ ├── v2/ # v2 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ └── __init__.py
│ │ ├── v3/ # v3 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ ├── preprocess.py
│ │ │ └── __init__.py
│ │ ├── v4/ # v4 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ ├── preprocess.py
│ │ │ └── __init__.py
│ │ ├── v5/ # v5 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ ├── preprocess.py
│ │ │ └── __init__.py
│ │ ├── v6/ # v6 models and preprocessing
│ │ │ ├── model.py
│ │ │ ├── predictor.py
│ │ │ ├── preprocess.py
│ │ │ └── __init__.py
│ │ └── preprocess.py # Shared preprocessing utilities
│ ├── schemas/
│ │ └── image.py # Pydantic models
│ ├── services/
│ │ └── image_service.py # Image handling utilities
│ ├── main.py # Application entry point
│ └── __init__.py
├── models/
│ ├── simple_cnn_model.pth # v1 model weights
│ ├── cat_dog_cnn_kan_model.pth # v2 model weights
│ ├── checkpoint.pth # v3 model weights
│ ├── kan_checkpoint_v4.pth # v4 model weights
│ ├── kan_checkpoint_20_v5.pth # v5 model weights (20 epochs)
│ ├── best_kan_model_v6.pth # v6 model weights (latest)
│ ├── cat_dog_cnn_kan_model_v3.pth # Alternative v3 weights
│ ├── cat_dog_classifier_100.pth # Alternative classifier (100 epochs)
│ └── (additional legacy checkpoints)
├── static/
│ └── images/ # Uploaded images directory
├── docs/
│ └── assets/
│ └── images/
│ └── banner.jpg # Banner image
├── requirements.txt # Python dependencies
├── Dockerfile # Docker configuration
└── README.md # This file
User Request
↓
FastAPI Router (v1/v2/v3)
↓
Endpoint Handler
↓
Image Validation
↓
Image Preprocessing
↓
Model Prediction
↓
Post-processing
↓
Response Generation
↓
Image Saved to Storage
↓
JSON Response to User
| Model | Version | Input Size | Architecture | Output | Weights File |
|---|---|---|---|---|---|
| SimpleCNN | v1 | 150x150 | Traditional CNN | Single logit | simple_cnn_model.pth |
| KAN CNN | v2 | 150x150 | CNN + KAN layers | 2-class logits | cat_dog_cnn_kan_model.pth |
| Advanced KAN | v3 | 224x224 | Enhanced CNN + KAN | 2-class logits | checkpoint.pth |
| Improved KAN | v4 | 224x224 | Refined CNN + KAN | 2-class logits | kan_checkpoint_v4.pth |
| Optimized KAN v5 | v5 | 224x224 | Production KAN | 2-class logits | kan_checkpoint_20_v5.pth |
| Latest KAN v6 | v6 | 224x224 | State-of-the-art KAN | 2-class logits | best_kan_model_v6.pth |
- Architecture: 3-layer CNN with FC layers
- Channels: 3 → 32 → 64 → 128
- Preprocessing: Resize to 150x150
- Normalization: Standard ImageNet normalization
- Output: Binary classification (sigmoid)
- Architecture: 3-layer CNN + KAN (Kolmogorov-Arnold Network)
- Channels: 3 → 32 → 64 → 128
- KAN Layers: [64, 32, 2] with 5 knots
- Preprocessing: Resize to 150x150
- Normalization: Standard ImageNet normalization
- Output: 2-class classification (softmax)
- Architecture: Enhanced 3-layer CNN + Advanced KAN
- Channels: 3 → 32 → 64 → 128
- KAN Layers: [64, 32, 2] with 5 knots
- Preprocessing: Resize to 224x224 (higher resolution)
- Normalization: Standard ImageNet normalization
- Output: 2-class classification (softmax)
- Architecture: Refined 3-layer CNN + Optimized KAN
- Channels: 3 → 32 → 64 → 128
- KAN Layers: Enhanced configuration for better generalization
- Preprocessing: Resize to 224x224
- Normalization: Standard ImageNet normalization
- Output: 2-class classification (softmax)
- Training: Checkpoint saved during optimization
- Architecture: Production-grade KAN model
- Training Epochs: 20 epochs (checkpoint at epoch 20)
- Preprocessing: Resize to 224x224
- Normalization: Standard ImageNet normalization
- Output: 2-class classification (softmax)
- Checkpoint:
kan_checkpoint_20_v5.pth(optimized weights)
- Architecture: State-of-the-art KAN implementation
- Model File:
best_kan_model_v6.pth(best performing) - Preprocessing: Resize to 224x224
- Normalization: Standard ImageNet normalization
- Output: 2-class classification (softmax)
- Status: Recommended for production use
- Training: Trained with latest improvements and optimizations
Models are automatically loaded on first use and cached in memory. Subsequent predictions use the cached model.
# Example: Direct model usage (for debugging)
from app.ml.v1.predictor import load_trained_model
from app.ml.v1.preprocess import preprocess_image
model = load_trained_model()
processed_image = preprocess_image(image_bytes)
prediction = model(processed_image)docker build -t kan-fast-api:latest .docker run -d \
--name kan-api \
-p 8000:8000 \
-v $(pwd)/static:/app/static \
kan-fast-api:latestError: FileNotFoundError: models/simple_cnn_model.pth
Solution:
- Ensure model files exist in the
models/directory - Verify file names match exactly (case-sensitive on Linux/macOS)
- Check file permissions
Error: RuntimeError: CUDA is not available
Solution:
- The app automatically falls back to CPU if CUDA isn't available
- For GPU support, install PyTorch with CUDA:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
Error: RuntimeError: CUDA out of memory
Solution:
- Use CPU by setting:
CUDA_VISIBLE_DEVICES=""before running - Reduce batch processing size
- Close other GPU-consuming applications
Error: Address already in use
Solution:
# Change port
uvicorn app.main:app --port 9000
# Or kill the process using port 8000
# On Windows:
netstat -ano | findstr :8000
taskkill /PID <PID> /F
# On macOS/Linux:
lsof -ti:8000 | xargs kill -9Error: 422 Unprocessable Entity
Solution:
- Verify image format is JPEG, PNG, or JPG
- Check image file is not corrupted
- Ensure file size is reasonable (< 50MB recommended)
Issue: First prediction is slow, subsequent ones are fast
Explanation: First request loads the model (5-15 seconds), subsequent requests use cached model (<1 second)
Solution:
- Call a warmup endpoint after startup
- Pre-load models on application initialization
Enable detailed logging:
# Set log level
LOGLEVEL=DEBUG uvicorn app.main:app --reload
# Or in Python
import logging
logging.basicConfig(level=logging.DEBUG)Monitor application performance:
# Check memory usage
watch -n 1 'ps aux | grep uvicorn'
# Check CPU usage
top | grep python
# Monitor network
netstat -an | grep ESTABLISHED | wc -limport requests
from pathlib import Path
# Path to your image
image_path = "path/to/cat_image.jpg"
# Prepare the request
with open(image_path, "rb") as f:
files = {"file": f}
# Test v1 endpoint
response = requests.post(
"http://localhost:8000/api/v1/predict",
files=files
)
result = response.json()
print(f"Prediction: {result['prediction']}")
print(f"Confidence: {result['probability']:.2%}")
print(f"Image URL: {result['url']}")# Using v2 endpoint
curl -X POST "http://localhost:8000/api/v2/predict" \
-H "accept: application/json" \
-F "file=@/path/to/image.jpg"
# Response
{
"prediction": "dog",
"probability": 0.95,
"url": "http://localhost:8000/static/images/image_abc123.jpg"
}const imageFile = document.getElementById('imageInput').files[0];
const formData = new FormData();
formData.append('file', imageFile);
fetch('http://localhost:8000/api/v3/predict', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(`Prediction: ${data.prediction}`);
console.log(`Probability: ${(data.probability * 100).toFixed(2)}%`);
console.log(`Image URL: ${data.url}`);
})
.catch(error => console.error('Error:', error));This project is provided as-is for research and educational purposes.
For issues, questions, or suggestions:
- Check the Troubleshooting section above
- Review the API documentation at
http://localhost:8000/docs - Check application logs for detailed error messages
Last Updated: May 2026 API Version: v1.0 (with v2 and v3 variants)
