File size: 7,301 Bytes
690d2e2 |
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
import streamlit as st
import numpy as np
import pandas as pd
import plotly.express as px
import pickle
from tensorflow.keras.models import load_model
# Streamlit page configuration
st.set_page_config(
page_title="Power Consumption Predictor",
layout="centered",
initial_sidebar_state="collapsed"
)
# Custom CSS for eye-catching design
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
.main {background-color: #ffffff;}
.stTitle {color: #003087; font-family: 'Roboto', sans-serif; text-align: center; margin-bottom: 10px; font-size: 32px; font-weight: 700;}
.stSubheader {color: #003087; font-family: 'Roboto', sans-serif; font-size: 22px; font-weight: 700; margin-top: 10px; margin-bottom: 10px;}
.stMarkdown {font-family: 'Roboto', sans-serif; color: #212529; font-size: 16px;}
.stDataFrame {
background-color: #ffffff;
border-radius: 12px;
padding: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.stButton>button {
background-color: #007bff;
color: white;
border-radius: 10px;
padding: 12px 30px;
font-size: 18px;
font-family: 'Roboto', sans-serif;
font-weight: 700;
display: block;
margin: 15px auto;
border: none;
transition: all 0.3s ease;
}
.stButton>button:hover {
background: linear-gradient(45deg, #0056b3, #007bff);
transform: scale(1.05);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.stNumberInput label {
color: #007bff;
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 16px;
}
.stNumberInput input {
background-color: #ffffff;
color: #212529;
border: 2px solid #007bff;
border-radius: 8px;
padding: 10px;
font-family: 'Roboto', sans-serif;
font-size: 14px;
caret-color: #212529;
}
.stNumberInput input:focus {
outline: none;
border-color: #003087;
box-shadow: 0 0 8px rgba(0,123,255,0.3);
}
</style>
""", unsafe_allow_html=True)
# Load model and scalers
try:
model = load_model('my_model.keras')
scaler_X = pickle.load(open('scaler_X.pkl', 'rb'))
scaler_y = pickle.load(open('scaler_y.pkl', 'rb'))
except Exception as e:
st.error(f"Failed to load model or scalers: {str(e)}. Ensure 'my_model.keras', 'scaler_X.pkl', and 'scaler_y.pkl' are in E:\\grid\\. "
"This error may occur if the TensorFlow version used to save the model differs from your installed version. "
"Try installing TensorFlow 2.17.0 or the version used to save the model (e.g., `pip install tensorflow==2.17.0`).")
st.stop()
# Main app layout
st.title("Power Consumption Predictor")
st.markdown("""
Enter values for one timestep to predict power consumption for Zone1, Zone2, and Zone3.
Results will be displayed as a vibrant bar plot and a clear table.
""")
# Input section
st.subheader("Enter Timestep Data")
st.markdown("""
**Instructions**:
- Enter values for the 8 features below (default values are provided).
- **Hour**: 0 to 23 (e.g., 14 for 2 PM).
- **DayOfWeek**: 0 to 6 (0 = Monday, 6 = Sunday).
- **Month**: 1 to 12 (e.g., 7 for July).
- **Other features**: Use reasonable values (e.g., Temperature in °C, Humidity as a fraction).
- Click "Predict" to see results.
""")
# Vertical form for input
with st.container():
feature_names = ['Hour', 'DayOfWeek', 'Month', 'Temperature', 'Humidity', 'WindSpeed', 'GeneralDiffuseFlows', 'DiffuseFlows']
default_values = [0, 6, 1, 6.559, 73.8, 0.083, 0.051, 0.119] # From dataset
user_input = []
for i, (name, default) in enumerate(zip(feature_names, default_values)):
if name in ['Hour', 'DayOfWeek', 'Month']:
value = st.number_input(
f"{name}",
min_value=0,
max_value=23 if name == 'Hour' else 6 if name == 'DayOfWeek' else 12,
value=int(default),
step=1,
key=f"input_{i}"
)
user_input.append(value)
else:
value = st.number_input(
f"{name}",
value=float(default),
step=0.01,
format="%.6f",
key=f"input_{i}"
)
user_input.append(value)
# Predict button
if st.button("Predict", key="predict_button"):
try:
# Replicate input for 24 timesteps
custom_raw_data = np.array([user_input] * 24).reshape(1, 24, 8)
# Selective scaling
features_to_scale = ['Temperature', 'Humidity', 'WindSpeed', 'GeneralDiffuseFlows', 'DiffuseFlows']
scale_indices = [3, 4, 5, 6, 7]
custom_scaled = custom_raw_data.copy()
custom_2d_to_scale = custom_raw_data[:, :, scale_indices].reshape(-1, len(scale_indices))
custom_scaled_2d = scaler_X.transform(custom_2d_to_scale)
custom_scaled[:, :, scale_indices] = custom_scaled_2d.reshape(1, 24, len(scale_indices))
# Predict
y_pred_scaled = model.predict(custom_scaled)
if isinstance(y_pred_scaled, list):
y_pred_combined = np.concatenate(y_pred_scaled, axis=1)
else:
y_pred_combined = y_pred_scaled
y_pred_original = scaler_y.inverse_transform(y_pred_combined)
# Store predictions
labels = ['PowerConsumption_Zone1', 'PowerConsumption_Zone2', 'PowerConsumption_Zone3']
st.session_state.pred_df = pd.DataFrame(y_pred_original, columns=labels, index=['User Input'])
st.session_state.predictions = y_pred_original
except Exception as e:
st.error(f"Error processing input: {str(e)}")
# Display predictions if available
if 'predictions' in st.session_state and st.session_state.predictions is not None:
st.markdown("### Predicted Power Consumption")
fig = px.bar(
st.session_state.pred_df.reset_index().melt(id_vars='index', value_vars=labels, var_name='Zone', value_name='Power Consumption'),
x='index', y='Power Consumption', color='Zone', barmode='group',
title='Predicted Power Consumption by Zone',
labels={'index': 'Sample', 'Power Consumption': 'Power Consumption (Original Scale)'},
color_discrete_sequence=['#007bff', '#28a745', '#dc3545']
)
fig.update_layout(
plot_bgcolor='white',
paper_bgcolor='white',
font=dict(family='Roboto', size=12, color='#212529'),
title_font=dict(size=18, family='Roboto', color='#003087'),
xaxis_title="Sample",
yaxis_title="Power Consumption (Original Scale)",
legend_title="Zones",
margin=dict(l=40, r=40, t=60, b=40)
)
st.plotly_chart(fig, use_container_width=True)
st.markdown("### Prediction Table")
st.dataframe(st.session_state.pred_df.style.format("{:.4f}").set_caption("Predicted Power Consumption (Original Scale)"))
# Footer
st.markdown("---")
st.markdown("**Made by Sadik Al Jarif**") |