yava-code's picture
Configure EuroSAT Field Scout submission (#1)
84f1282
Raw
History Blame Contribute Delete
2.37 kB
from io import BytesIO
from pathlib import Path
import torch
import gradio as gr
from torchvision import transforms
from PIL import Image
from model import SimpleNet, CLASS_NAMES
WEIGHTS_DIR = Path("weights")
EXAMPLES = [
["examples/annualcrop_sample.jpg"],
["examples/forest_sample.jpg"],
["examples/highway_sample.jpg"],
["examples/industrial_sample.jpg"],
["examples/residential_sample.jpg"],
["examples/sealake_sample.jpg"],
]
def load_model():
model = SimpleNet(num_classes=10)
weight_bytes = b"".join(
path.read_bytes() for path in sorted(WEIGHTS_DIR.glob("simple_net_v1.part*"))
)
state_dict = torch.load(BytesIO(weight_bytes), map_location="cpu")
state_dict = {
name: tensor.float() if torch.is_floating_point(tensor) else tensor
for name, tensor in state_dict.items()
}
model.load_state_dict(state_dict)
model.eval()
return model
model = load_model()
preprocess = transforms.Compose([
transforms.Resize((64, 64)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
def predict(image: Image.Image) -> dict[str, float]:
if image is None:
return {}
image = image.convert("RGB")
tensor = preprocess(image).unsqueeze(0) # [1, 3, 64, 64]
with torch.no_grad():
logits = model(tensor)
probs = torch.nn.functional.softmax(logits, dim=1)[0]
return {CLASS_NAMES[i]: float(probs[i]) for i in range(len(CLASS_NAMES))}
demo = gr.Interface(
fn=predict,
inputs=gr.Image(type="pil", label="Upload a Sentinel-style land image"),
outputs=gr.Label(num_top_classes=5, label="Top land-use guesses"),
title="EuroSAT Field Scout",
description=(
"A small local-first Gradio classifier for quick land-use triage. "
"It runs a custom PyTorch CNN trained on EuroSAT and returns the closest scene class."
),
article=(
"Built for the Build Small Hackathon Backyard AI track. "
"No cloud inference API, no giant model: the Space loads local weights "
"and runs CPU inference inside the app."
),
examples=EXAMPLES,
cache_examples=False,
allow_flagging="never",
theme=gr.themes.Soft(),
)
if __name__ == "__main__":
demo.queue(default_concurrency_limit=2).launch()