import numpy as np import pandas as pd import gradio as gr import tensorflow as tf MODEL_PATH = "activity_model.keras" CLASS_NAMES = ["Stationary", "Walking", "Running"] EXPECTED_STEPS = 100 model = tf.keras.models.load_model(MODEL_PATH) def read_signal(file_path): if file_path is None: raise gr.Error("Please upload a CSV file.") df = pd.read_csv(file_path) # Accept either a column named sensor_value or the first numeric column. if "sensor_value" in df.columns: values = df["sensor_value"].to_numpy(dtype=np.float32) else: numeric = df.select_dtypes(include=["number"]) if numeric.shape[1] == 0: raise gr.Error("CSV must contain a numeric sensor column.") values = numeric.iloc[:, 0].to_numpy(dtype=np.float32) if len(values) != EXPECTED_STEPS: raise gr.Error(f"Expected exactly {EXPECTED_STEPS} sensor readings, found {len(values)}.") return values def predict_activity(file_path): values = read_signal(file_path) x = values.reshape(1, EXPECTED_STEPS, 1) probs = model.predict(x, verbose=0)[0] return {name: float(prob) for name, prob in zip(CLASS_NAMES, probs)} with gr.Blocks() as demo: gr.Markdown("# Wearable Activity Classifier") gr.Markdown("Upload a CSV containing exactly 100 sensor readings. The student-trained model predicts Stationary, Walking, or Running.") file_input = gr.File(label="Sensor CSV", file_types=[".csv"], type="filepath") output = gr.Label(label="Prediction", num_top_classes=3) button = gr.Button("Predict activity", variant="primary") button.click(predict_activity, inputs=file_input, outputs=output) gr.Examples( examples=[["sample_stationary.csv"], ["sample_walking.csv"], ["sample_running.csv"]], inputs=file_input, label="Sample files" ) demo.launch()