CoolFace
Apppublic

CouchPotato101/space_network_pred

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
app.py165 linesDownload Raw Back to root
1from fastapi import FastAPI, Query2from models import LightweightTelecomNet3from schemas import PredictionResponse4import torch5import os6 7# 1. Initialize FastAPI8app = FastAPI()9 10# 2. Determine computation device11device = "cuda" if torch.cuda.is_available() else "cpu"12 13# 3. Load the pre-trained model14MODEL_PATH = "model/best_lightweight_model.pt"  # Update this path for HuggingFace Spaces15print(os.path.exists(MODEL_PATH))16try:17    model = LightweightTelecomNet().to(device)18    model.load_state_dict(torch.load(MODEL_PATH, map_location=device))19    model.eval()20    print(f"Model loaded successfully on {device}.")21except FileNotFoundError:22    print(f"Error: Model file not found. Please ensure '{MODEL_PATH}' is present.")23    model = None24except Exception as e:25    print(f"An error occurred while loading the model: {e}")26    model = None27 28 29# 4. Define class_map30class_map = {0: "Normal", 1: "Scintillation", 2: "Congestion", 3: "Rain Fade"}31 32# 5. Load synthetic data33SYNTHETIC_DATA_PATH = os.path.join("data", "synthetic_data.pt")34# try:35#     synthetic_data = torch.load(SYNTHETIC_DATA_PATH, map_location=device)36#     # Expecting dict with keys: 'temporal', 'spatial', 'operator_id' or similar37#     print(f"Synthetic data loaded: {list(synthetic_data.keys())}")38# except Exception as e:39#     print(f"Error loading synthetic data: {e}")40#     synthetic_data = None41 42try:43    synthetic_data = torch.load(SYNTHETIC_DATA_PATH, map_location=device)44 45    if isinstance(synthetic_data, dict):46        print("Synthetic data loaded (dict keys):", list(synthetic_data.keys()))47    elif isinstance(synthetic_data, list):48        print("Synthetic data loaded (list length):", len(synthetic_data))49    else:50        print("Synthetic data loaded:", type(synthetic_data))51 52except Exception as e:53    print("Error loading synthetic data:", e)54    synthetic_data = None55 56 57# Use the first available sample from synthetic_data for prediction58def get_synthetic_sample():59    if synthetic_data is None:60        return None, None, None61    # Try to support both dict of lists and list of dicts62    if isinstance(synthetic_data, dict):63        temporal = synthetic_data.get('temporal')64        spatial = synthetic_data.get('spatial')65        operator_id = synthetic_data.get('operator_id', 0)66        # If these are lists, use the first sample67        if isinstance(temporal, list) and len(temporal) > 0 and isinstance(temporal[0], list):68            temporal = temporal[0]69        if isinstance(spatial, list) and len(spatial) > 0 and isinstance(spatial[0], list):70            spatial = spatial[0]71        if isinstance(operator_id, list):72            operator_id = operator_id[0]73        return temporal, spatial, operator_id74    elif isinstance(synthetic_data, list) and len(synthetic_data) > 0:75        sample = synthetic_data[0]76        return sample.get('temporal'), sample.get('spatial'), sample.get('operator_id', 0)77    return None, None, None78 79@app.get("/ping")80def ping():81    return {"status": "alive"}82    83@app.get("/predict_segment", response_model=PredictionResponse)84async def predict_segment(85    sample_idx: int = Query(200, description="Index of the sample in the validation dataset"),86    start_time_idx: int = Query(0, description="Starting 10-min interval (0-143)"),87    duration_in_10min_intervals: int = Query(1, description="Number of consecutive 10-min intervals (1-144)")88):89    if model is None or synthetic_data is None:90        return {"predicted_event": "Model not loaded", "predicted_vulnerability": 0.0}91 92    # Try to treat synthetic_data as a list of tuples or dicts like a dataset93    val_dataset = synthetic_data94    try:95        # Try to index as a list/tuple96        sample = val_dataset[sample_idx]97        # Support tuple or dict98        if isinstance(sample, dict):99            temporal_full = torch.tensor(sample['temporal'])100            spatial_full = torch.tensor(sample['spatial'])101            operator_id = torch.tensor(sample['operator_id'])102            true_label = torch.tensor(sample.get('true_label', 0))103            true_vuln = torch.tensor(sample.get('true_vuln', 0.0))104        else:105            # Assume tuple: (temporal, spatial, operator_id, true_label, true_vuln)106            temporal_full, spatial_full, operator_id, true_label, true_vuln = sample107        # Extract the temporal segment108        temporal_segment = temporal_full[start_time_idx : start_time_idx + duration_in_10min_intervals]109        temporal_input_configured = temporal_segment.unsqueeze(0).to(device) # [1, duration, 5]110        spatial_input_configured = spatial_full.unsqueeze(0).to(device) # [1, 50, 50]111        operator_input_configured = torch.tensor([operator_id.item() if hasattr(operator_id, 'item') else int(operator_id)], device=device)112 113        with torch.no_grad():114            class_out_configured, vuln_out_configured = model(temporal_input_configured, spatial_input_configured, operator_input_configured)115        pred_label_configured = torch.argmax(class_out_configured, dim=1).item()116        pred_vuln_configured = vuln_out_configured.item()117        predicted_event_label = class_map[pred_label_configured]118 119        # Optionally, return true label/vuln for comparison120        return {121            "predicted_event": predicted_event_label,122            "predicted_vulnerability": pred_vuln_configured,123            # "true_event": class_map[true_label.item() if hasattr(true_label, 'item') else int(true_label)],124            # "true_vulnerability": float(true_vuln.item() if hasattr(true_vuln, 'item') else float(true_vuln))125        }126    except Exception as e:127        return {"predicted_event": f"Error: {e}", "predicted_vulnerability": 0.0}128 129@app.get("/predict_moment", response_model=PredictionResponse)130async def predict_moment(131    sample_idx: int = Query(200, description="Index of the sample in the validation dataset"),132    moment_idx: int = Query(0, description="Index of the moment in the temporal sequence (0-143)")133):134    if model is None or synthetic_data is None:135        return {"predicted_event": "Model not loaded", "predicted_vulnerability": 0.0}136 137    val_dataset = synthetic_data138    try:139        sample = val_dataset[sample_idx]140        if isinstance(sample, dict):141            temporal = torch.tensor(sample['temporal'])142            spatial = torch.tensor(sample['spatial'])143            operator_id = torch.tensor(sample['operator_id'])144        else:145            temporal, spatial, operator_id = sample[:3]146 147        # Select the single moment148        single_moment_temporal = temporal[moment_idx] # [5]149        single_moment_temporal_input = single_moment_temporal.unsqueeze(0).unsqueeze(0).to(device) # [1, 1, 5]150        spatial_input = spatial.unsqueeze(0).to(device)151        operator_input = torch.tensor([operator_id.item() if hasattr(operator_id, 'item') else int(operator_id)], device=device)152 153        with torch.no_grad():154            class_out_single_moment, vuln_out_single_moment = model(single_moment_temporal_input, spatial_input, operator_input)155        pred_label_single_moment = torch.argmax(class_out_single_moment, dim=1).item()156        pred_vuln_single_moment = vuln_out_single_moment.item()157        predicted_event_label = class_map[pred_label_single_moment]158 159        return {160            "predicted_event": predicted_event_label,161            "predicted_vulnerability": pred_vuln_single_moment162        }163    except Exception as e:164        return {"predicted_event": f"Error: {e}", "predicted_vulnerability": 0.0}165