-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
116 lines (94 loc) · 3.73 KB
/
Copy pathapp.py
File metadata and controls
116 lines (94 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from flask import Flask, request, jsonify
import numpy as np
import tensorflow as tf
import pickle
import logging
import os
from tensorflow.keras.models import load_model
from tensorflow.keras.losses import MeanSquaredError
from sklearn.preprocessing import StandardScaler
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize Flask app
app = Flask(__name__)
# Load the model and scalers
try:
logger.info("Loading model and scalers...")
model = load_model(
"CNN_LSTM_Model_256.h5", custom_objects={"mse": MeanSquaredError()}
)
with open("scaler_X.pkl", "rb") as f:
scaler_X = pickle.load(f)
with open("scaler_y.pkl", "rb") as f:
scaler_y = pickle.load(f)
logger.info("Model and scalers loaded successfully")
except Exception as e:
logger.error(f"Error loading model or scalers: {str(e)}")
raise
@app.route("/", methods=["GET"])
def home():
return jsonify(
{
"status": "API is running",
"endpoints": {
"/predict": {
"method": "POST",
"description": "Predict ABP values from PPG and ECG data",
"input_format": {
"ppg": "List of 250 PPG signal values",
"ecg": "List of 250 ECG signal values",
},
}
},
}
)
# Define a route for the prediction
@app.route("/predict", methods=["POST"])
def predict():
try:
# Get data from the client
data = request.get_json()
logger.info("Received request data")
if not data:
logger.error("No data provided in request")
return jsonify({"error": "No data provided"}), 400
if "ppg" not in data or "ecg" not in data:
logger.error("Missing ppg or ecg data in request")
return jsonify({"error": "Missing ppg or ecg data"}), 400
# Assuming data contains 'ppg' and 'ecg' as lists
ppg = np.array(data["ppg"])
ecg = np.array(data["ecg"])
logger.info(f"Input shapes - PPG: {ppg.shape}, ECG: {ecg.shape}")
# Ensure the data is in the right shape (add any necessary preprocessing)
sample_size = 250 # As in your model input size
if len(ppg) != sample_size or len(ecg) != sample_size:
print("error")
logger.error(
f"Invalid input size. Expected {sample_size}, got PPG: {len(ppg)}, ECG: {len(ecg)}"
)
return jsonify(
{"error": f"Input data must be {sample_size} samples long"}
), 400
ppg = ppg.reshape(1, sample_size)
ecg = ecg.reshape(1, sample_size)
# Stack PPG and ECG as the model expects 2 input channels
X_input = np.stack((ppg, ecg), axis=-1)
logger.info(f"Stacked input shape: {X_input.shape}")
# Scale the input data
X_scaled = scaler_X.transform(X_input.reshape(1, -1)).reshape(1, sample_size, 2)
logger.info(f"Scaled input shape: {X_scaled.shape}")
# Predict using the model
prediction = model.predict(X_scaled)
logger.info(f"Raw prediction shape: {prediction.shape}")
# Inverse transform the prediction
prediction_orig = scaler_y.inverse_transform(prediction)
logger.info(f"Final prediction shape: {prediction_orig.shape}")
return jsonify({"predicted_abp": prediction_orig.tolist()})
except Exception as e:
logger.error(f"Error in prediction: {str(e)}", exc_info=True)
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
logger.info("Starting Flask server...")
port = int(os.environ.get("PORT", 5000))
app.run(host="0.0.0.0", port=port)