CahilCuhela's picture
graphics resolution increased
19b81a0
Raw
History Blame Contribute Delete
5.73 kB
import torch
import numpy as np
import pandas as pd
import gradio as gr
import matplotlib.pyplot as plt
from model import LSTMRegressor
from torch.utils.data import TensorDataset, DataLoader
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from pathlib import Path
# Taking datas
train_df = pd.read_csv("train_FD001.txt", sep = " ", header = None)
test_df = pd.read_csv("test_FD001.txt", sep = " ", header = None)
rul_df = pd.read_csv("RUL_FD001.txt", sep = " ", header = None)
# Drop empty columns
train_df.dropna(axis = 1, inplace = True)
test_df.dropna(axis = 1, inplace = True)
# Preparing the column names
columns = ["unit_number",
"time_in_cycles"] + [f"operational_setting_{i}" for i in range(1, 4)] + [f"sensor_measurement_{i}" for i in range(1, 22)]
train_df.columns = columns
test_df.columns = columns
rul_df = rul_df[[0]]
rul_df.columns = ["RUL"]
# Prepare RUL column for train set
rul_per_engine = train_df.groupby("unit_number")["time_in_cycles"].max().reset_index()
rul_per_engine.columns = ["unit_number", "max_cycle"]
train_df = train_df.merge(rul_per_engine, on = "unit_number", how = "left")
train_df["RUL"] = train_df["max_cycle"] - train_df["time_in_cycles"]
train_df.drop(columns = ["max_cycle"], axis = 1, inplace = True)
def generate_sequence(data, sequence_length, feature_cols):
sequences = []
targets = []
for engine_id in data["unit_number"].unique():
engine_data = data[data["unit_number"] == engine_id]
engine_data = engine_data.reset_index(drop = True)
for i in range(len(engine_data) - sequence_length + 1):
seq_x = engine_data.loc[i : i + sequence_length -1, feature_cols].values
seq_y = engine_data.loc[i + sequence_length - 1, "RUL"]
sequences.append(seq_x)
targets.append(seq_y)
return np.array(sequences), np.array(targets)
feature_columns = [f"operational_setting_{i}" for i in range(1, 4)] + [f"sensor_measurement_{i}" for i in range(1, 22)]
train_sequence_length = 160
X_train, y_train = generate_sequence(train_df, train_sequence_length, feature_columns)
X_flat = X_train.reshape(-1, X_train.shape[-1])
# Scale data between 1 - 0
feature_scaler = MinMaxScaler()
X_scaled_flat = feature_scaler.fit_transform(X_flat)
X_train_scaled = X_scaled_flat.reshape(X_train.shape)
y_train_reshaped = y_train.reshape(-1, 1)
target_scaler = MinMaxScaler()
y_train_scaled = target_scaler.fit_transform(y_train_reshaped)
# Prepare model
input_size = 24
hidden_size = 128
num_layers = 2
dropout = 0.3
model = LSTMRegressor(input_size = input_size, hidden_size = hidden_size, num_layers = num_layers, dropout = dropout)
# Load model
model.load_state_dict(torch.load(f = "LSTM_CMAPSS_with_test_and_rul_data_MAE_14.31_RMSE_18.22_r2_0.81.pth",
weights_only = True,
map_location=torch.device('cpu')))
# Prepare test datas
test_sequence_length = 150
X_test_list = []
y_test_list = []
for i, engine_id in enumerate(test_df["unit_number"].unique()):
engine_data = test_df[test_df["unit_number"] == engine_id].reset_index(drop = True)
if len(engine_data) >= test_sequence_length:
seq = engine_data.iloc[-test_sequence_length:][feature_columns].values
else:
padding = np.zeros((test_sequence_length - len(engine_data), len(feature_columns)))
seq = np.vstack((padding, engine_data[feature_columns].values))
X_test_list.append(seq)
y_test_list.append(rul_df.iloc[i].values[0])
X_test = np.array(X_test_list)
y_test = np.array(y_test_list).reshape(-1, 1)
# Scale test data
X_test_flat = X_test.reshape(-1, X_test.shape[-1])
X_test_scaled_flat = feature_scaler.transform(X_test_flat)
X_test_scaled = X_test_scaled_flat.reshape(X_test.shape)
y_test_scaled = target_scaler.transform(y_test)
# Make predictions
model.eval()
X_test_tensor = torch.tensor(X_test_scaled, dtype = torch.float32)
with torch.inference_mode():
y_pred_scaled = model(X_test_tensor).cpu().numpy()
y_pred = target_scaler.inverse_transform(y_pred_scaled)
y_pred = y_pred.flatten()
y_true = y_test.flatten()
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_true, y_pred)
def plot_all_engines():
fig, ax = plt.subplots(figsize = (12, 6), dpi = 300)
ax.plot(y_true, label = "Real RUL", marker = 'o', color = "green")
ax.plot(y_pred, label = "Predicted RUL", marker = 'x', color = "orange")
ax.set_title("RUL Predictions for All Motors")
ax.set_xlabel("Motor No")
ax.set_ylabel("RUL")
ax.legend()
ax.grid(True)
return fig
def analyze_engine(engine_id):
idx = int(engine_id.split()[-1]) - 1
true_rul = y_true[idx]
pred_rul = y_pred[idx]
return f"""
### πŸ” [INFO] {engine_id}
- Real RUL: **{true_rul:.2f}**
- Predicted RUL: **{pred_rul:.2f}**
- Error (MAE): **{abs(true_rul - pred_rul):.2f}**
"""
#Gradio UI
with gr.Blocks() as demo:
article = "Created by Ahmet Hakan Karadana"
gr.Markdown("## ✈️ Jet Engine RUL Prediction (CMAPSS)")
gr.Markdown(f"""
**Model Metrics:**
βœ… MAE: {mae:.2f}
βœ… RMSE: {rmse:.2f}
βœ… RΒ²: {r2:.2f}
""")
gr.Markdown("### πŸ“ˆ Actual & Predicted RUL Values of All Engines")
gr.Plot(plot_all_engines)
gr.Markdown("### πŸ” Select Engine for Numerical Values")
dropdown = gr.Dropdown(choices=[f"Engine {i}" for i in range(1, 101)], label="Select Motor")
output_text = gr.Markdown()
dropdown.change(analyze_engine, inputs=dropdown, outputs=output_text)
gr.Markdown(f"*{article}*")
demo.launch()