Spaces:
Sleeping
Sleeping
| #this is the original processing.py file, but is being revised for Hugging Face. this works well locally with Streamlit and consider using if the other has issues. | |
| import numpy as np | |
| import os | |
| import json | |
| import tensorflow as tf | |
| from src.preprocess import audio_to_spectrograms | |
| from src.model import build_autoencoder | |
| from src.storage import upload_file, download_file | |
| TEMP_DIR = "temp_models" | |
| if not os.path.exists(TEMP_DIR): | |
| os.makedirs(TEMP_DIR) | |
| def train_mode_cloud(audio_path, mode_name, boat_id): | |
| # 1. Preprocess | |
| X_train = audio_to_spectrograms(audio_path) | |
| if X_train is None: return "❌ Audio too short (min 1 sec)." | |
| # 2. Train | |
| autoencoder = build_autoencoder(X_train.shape[1:]) | |
| autoencoder.fit(X_train, X_train, epochs=40, batch_size=4, verbose=0) | |
| # 3. Calculate Threshold (THE FIX) | |
| reconstructions = autoencoder.predict(X_train) | |
| mse = np.mean(np.power(X_train - reconstructions, 2), axis=(1, 2, 3)) | |
| threshold = float(np.mean(mse) + (2 * np.std(mse))) | |
| # 4. Save Locally | |
| model_filename = f"{mode_name}_model.h5" | |
| meta_filename = f"{mode_name}_meta.json" | |
| local_model_path = os.path.join(TEMP_DIR, model_filename) | |
| local_meta_path = os.path.join(TEMP_DIR, meta_filename) | |
| autoencoder.save(local_model_path, save_format='h5', include_optimizer=False) | |
| with open(local_meta_path, 'w') as f: | |
| json.dump({"threshold": threshold}, f) | |
| # 5. Upload | |
| u1 = upload_file(local_model_path, boat_id, model_filename) | |
| u2 = upload_file(local_meta_path, boat_id, meta_filename) | |
| if u1 and u2: | |
| return f"✅ Calibrated {mode_name.upper()} | Threshold: {threshold:.5f}" | |
| else: | |
| return "⚠️ Trained locally, but Cloud Upload Failed." | |
| def predict_health_cloud(audio_path, mode_name, boat_id): | |
| model_filename = f"{mode_name}_model.h5" | |
| meta_filename = f"{mode_name}_meta.json" | |
| local_model_path = os.path.join(TEMP_DIR, model_filename) | |
| local_meta_path = os.path.join(TEMP_DIR, meta_filename) | |
| # 1. Download | |
| d1 = download_file(boat_id, model_filename, local_model_path) | |
| d2 = download_file(boat_id, meta_filename, local_meta_path) | |
| if not (d1 and d2): | |
| return f"⚠️ No trained model found in cloud for Boat: {boat_id} (Mode: {mode_name})" | |
| # 2. Load | |
| with open(local_meta_path, 'r') as f: | |
| threshold = json.load(f)["threshold"] | |
| model = tf.keras.models.load_model(local_model_path, compile=False) | |
| # 3. Predict | |
| X_test = audio_to_spectrograms(audio_path) | |
| if X_test is None: return "Error: Audio too short." | |
| reconstructions = model.predict(X_test) | |
| # Calculate error for each second of audio | |
| mse = np.mean(np.power(X_test - reconstructions, 2), axis=(1, 2, 3)) | |
| # 4. Analysis | |
| anomalies = np.sum(mse > threshold) | |
| health_score = 100 * (1 - (anomalies / len(mse))) | |
| # 5. Debug Data (Shows you WHY it decided what it decided) | |
| avg_error = np.mean(mse) | |
| max_error = np.max(mse) | |
| status = "🟢 HEALTHY" if health_score > 85 else "🔴 ANOMALY DETECTED" | |
| # Return detailed report | |
| return f""" | |
| STATUS: {status} | |
| Confidence Score: {health_score:.1f}% | |
| --- TECHNICAL TELEMETRY --- | |
| Threshold Limit : {threshold:.5f} | |
| Your Avg Error : {avg_error:.5f} | |
| Your Max Error : {max_error:.5f} | |
| Anomalous Secs : {anomalies} / {len(mse)} | |
| """ |