🛰️ GalaxEye Satellite Tile Land-Use Classifier
A fine-tuned ResNet-18 model for classifying 64×64 RGB satellite tiles into 7 land-use categories, designed for offline, edge-deployable inference on CPU.
Built as part of the GalaxEye Backend Engineer (ML Systems) take-home assignment.
📊 Model Summary
| Property | Value |
|---|---|
| Architecture | ResNet-18 (ImageNet pretrained, fine-tuned) |
| Parameters | 11.19M (FP32) |
| Input | 64×64 RGB satellite tile (PNG) |
| Output | 7-class probability distribution |
| Format | Hugging Face safetensors (zero-copy, mmap-safe) |
| Framework | PyTorch 2.2+ |
| License | MIT |
🏷️ Supported Classes
| Label ID | Class | Description |
|---|---|---|
| 0 | AnnualCrop | Seasonal agricultural fields |
| 1 | Forest | Dense tree cover / woodland |
| 2 | Highway | Road infrastructure and corridors |
| 3 | Industrial | Factories, warehouses, industrial zones |
| 4 | Residential | Urban housing and neighborhoods |
| 5 | River | Waterways and river channels |
| 6 | SeaLake | Large water bodies (seas, lakes) |
📈 Performance
Evaluated on a 210-tile holdout set (30 tiles per class), unseen during training:
| Class | Accuracy |
|---|---|
| AnnualCrop | 29/30 (96.7%) |
| Forest | 28/30 (93.3%) |
| Highway | 28/30 (93.3%) |
| Industrial | 29/30 (96.7%) |
| Residential | 30/30 (100.0%) |
| River | 29/30 (96.7%) |
| SeaLake | 28/30 (93.3%) |
| Overall | 201/210 (95.71%) |
🚀 Quick Start
Using PyTorch + Safetensors (Recommended)
import torch
import torch.nn as nn
import json
from torchvision import models, transforms
from safetensors.torch import load_file
from PIL import Image
# Load config and model
with open("config.json") as f:
config = json.load(f)
classes = [config["id2label"][str(i)] for i in range(config["num_labels"])]
model = models.resnet18()
model.fc = nn.Linear(model.fc.in_features, len(classes))
model.load_state_dict(load_file("model.safetensors", device="cpu"))
model.eval()
# Preprocess and classify
transform = transforms.Compose([
transforms.Resize((64, 64)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
image = Image.open("tile.png").convert("RGB")
tensor = transform(image).unsqueeze(0)
with torch.no_grad():
probs = torch.softmax(model(tensor), dim=1)[0]
label = classes[probs.argmax().item()]
confidence = probs.max().item()
print(f"Prediction: {label} ({confidence:.2%})")
Download from Hugging Face Hub
from huggingface_hub import hf_hub_download
# Download model artifacts
safetensors_path = hf_hub_download("rishii100/galaxeye-tile-classifier", "model.safetensors")
config_path = hf_hub_download("rishii100/galaxeye-tile-classifier", "config.json")
🏗️ Training Details
| Property | Value |
|---|---|
| Base Model | torchvision.models.resnet18(pretrained=True) |
| Dataset | EuroSAT 7-class subset (1,050 tiles: 150 per class) |
| Train / Eval Split | 840 train / 210 holdout (80-20 stratified) |
| Optimizer | Adam (lr=1e-4) |
| Loss | CrossEntropyLoss |
| Epochs | 10 |
| Augmentation | RandomHorizontalFlip, RandomRotation(15), ColorJitter |
| Hardware | NVIDIA T4 GPU (Google Colab) |
| Training Time | ~2 minutes |
🔒 Why Safetensors?
This model uses the safetensors format instead of Python pickle (.pth) for critical safety and performance benefits:
- 🛡️ No Arbitrary Code Execution: Unlike
.pthfiles which usepickle(vulnerable to code injection),safetensorsis a pure tensor serialization format with zero deserialization attack surface. - ⚡ Zero-Copy Memory Mapping: Supports
mmapfor instant model loading without full deserialization — ideal for resource-constrained edge hardware. - 📦 Framework Agnostic: Compatible across PyTorch, TensorFlow, JAX, and ONNX ecosystems.
🌍 Intended Use
This model is designed for offline satellite tile classification in isolated, internet-free environments such as:
- Edge base stations and field laboratories
- Satellite ground segment compute modules
- Disaster response and environmental monitoring units
It is part of a complete FastAPI-based inference service — see the GitHub repository for the full backend implementation.
⚠️ Limitations
- Resolution: Trained exclusively on 64×64 pixel tiles. Performance on other resolutions is not guaranteed.
- Class Coverage: Limited to 7 EuroSAT land-use categories. Novel terrain types (e.g., desert, glacier, wetland) will be misclassified.
- Geographic Bias: EuroSAT tiles are sourced from European Sentinel-2 imagery. Accuracy may degrade on tiles from other geographic regions with different spectral characteristics.
- Small Training Set: Only 840 training tiles (120 per class). Production deployments should fine-tune on larger, domain-specific datasets.
📎 Links
- 🔗 GitHub Repository: rishii100/galaxeye-tile-classifier
- 🏢 GalaxEye Space: galaxeye.space
- 📄 EuroSAT Dataset: Helber et al., 2019
- Downloads last month
- 13
Evaluation results
- Holdout Accuracy on EuroSAT 7-Class Subset (64×64 RGB Tiles)self-reported95.710