Fola-lad commited on
Commit
3641ff7
Β·
1 Parent(s): b87f5fe

side-by-side FFN vs CNN comparison on every prediction

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +68 -52
src/streamlit_app.py CHANGED
@@ -4,8 +4,8 @@ import numpy as np
4
  import pandas as pd
5
 
6
  # Paths anchored to the repo root regardless of working directory
7
- _SRC_DIR = os.path.dirname(os.path.abspath(__file__)) # /app/src
8
- _REPO_ROOT = os.path.dirname(_SRC_DIR) # /app
9
  _SAMPLES_PATH = os.path.join(_REPO_ROOT, "data", "samples.csv")
10
 
11
  # ── Constants ──────────────────────────────────────────────────────────────
@@ -28,11 +28,6 @@ EXPLANATIONS = {
28
  "WALKING_UPSTAIRS": "Elevated vertical acceleration effort with upward body displacement β€” consistent with climbing stairs.",
29
  }
30
 
31
- MODEL_FILES = {
32
- "FFN (512β†’256β†’128)": "model.keras",
33
- "CNN (Conv1DΓ—3)": "har_cnn.keras",
34
- }
35
-
36
  # ── Model loader ────────────────────────────────────────────────────────────
37
 
38
  @st.cache_resource
@@ -40,7 +35,7 @@ def load_model(filename: str):
40
  try:
41
  from huggingface_hub import hf_hub_download
42
  import tensorflow as tf
43
- from model_def import FeedForwardNetwork, Conv1DNetwork # noqa: F401 β€” registers both classes
44
 
45
  model_path = hf_hub_download(
46
  repo_id="Group3DActRecog/actRecog",
@@ -63,7 +58,7 @@ def load_model(filename: str):
63
  st.set_page_config(
64
  page_title="Human Activity Recognition",
65
  page_icon="πŸƒ",
66
- layout="centered"
67
  )
68
 
69
  st.title("Human Activity Recognition")
@@ -86,21 +81,29 @@ with st.sidebar:
86
  **Classes:** 6 activities of daily living
87
  """)
88
  st.markdown("---")
89
- st.markdown("**Select model**")
90
- model_choice = st.radio(
91
- label="model",
92
- options=list(MODEL_FILES.keys()),
93
- label_visibility="collapsed",
94
- )
 
 
 
 
95
  st.markdown("---")
96
  st.caption("DAT606 Group Assignment Β· Pan-Atlantic University")
97
 
98
- # ── Load selected model ───────────────────────────────────────────────────────
99
 
100
- model, model_status = load_model(MODEL_FILES[model_choice])
 
101
 
102
- if model_status != "ready":
103
- st.warning(f"Model not loaded β€” {model_status}")
 
 
 
104
 
105
  # ── Tabs ─────────────────────────────────────────────────────────────────────
106
 
@@ -117,10 +120,7 @@ with tab1:
117
 
118
  try:
119
  samples_df = pd.read_csv(_SAMPLES_PATH)
120
- feature_cols = [
121
- c for c in samples_df.columns
122
- if c not in ["Activity", "subject"]
123
- ]
124
 
125
  sample_labels = [
126
  f"Sample {i+1} β€” {row['Activity']}"
@@ -140,39 +140,55 @@ with tab1:
140
  st.metric("Feature count", len(feature_vector))
141
 
142
  if st.button("Classify this sample", type="primary"):
143
- if model_status != "ready":
144
- st.error("Model not loaded β€” cannot predict yet.")
145
  else:
146
  arr = feature_vector.reshape(1, -1)
147
- probs = model.predict(arr, verbose=0)[0]
148
- pred_idx = int(np.argmax(probs))
149
- pred_label = LABEL_MAP[pred_idx]
150
- confidence = float(probs[pred_idx]) * 100
151
- correct = pred_label == true_label
 
 
 
 
 
152
 
153
  st.markdown("---")
154
- st.subheader("Result")
155
-
156
- if correct:
157
- st.success(
158
- f"**{pred_label}** Β· {confidence:.1f}% confidence Β· βœ“ Correct"
159
- )
160
- else:
161
- st.error(
162
- f"**{pred_label}** Β· {confidence:.1f}% confidence Β· "
163
- f"βœ— Incorrect (true: {true_label})"
164
- )
165
-
166
- st.markdown(f"_{EXPLANATIONS[pred_label]}_")
167
- st.markdown("**Confidence across all classes**")
168
-
169
- chart_data = pd.DataFrame({
170
- "Confidence (%)": [
171
- float(probs[i]) * 100 for i in range(6)
172
- ]
173
- }, index=[LABEL_MAP[i] for i in range(6)])
174
-
175
- st.bar_chart(chart_data)
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  except FileNotFoundError:
178
  st.error("Sample data file not found. Add `data/samples.csv` to the repo.")
 
4
  import pandas as pd
5
 
6
  # Paths anchored to the repo root regardless of working directory
7
+ _SRC_DIR = os.path.dirname(os.path.abspath(__file__))
8
+ _REPO_ROOT = os.path.dirname(_SRC_DIR)
9
  _SAMPLES_PATH = os.path.join(_REPO_ROOT, "data", "samples.csv")
10
 
11
  # ── Constants ──────────────────────────────────────────────────────────────
 
28
  "WALKING_UPSTAIRS": "Elevated vertical acceleration effort with upward body displacement β€” consistent with climbing stairs.",
29
  }
30
 
 
 
 
 
 
31
  # ── Model loader ────────────────────────────────────────────────────────────
32
 
33
  @st.cache_resource
 
35
  try:
36
  from huggingface_hub import hf_hub_download
37
  import tensorflow as tf
38
+ from model_def import FeedForwardNetwork, Conv1DNetwork # noqa: F401
39
 
40
  model_path = hf_hub_download(
41
  repo_id="Group3DActRecog/actRecog",
 
58
  st.set_page_config(
59
  page_title="Human Activity Recognition",
60
  page_icon="πŸƒ",
61
+ layout="wide",
62
  )
63
 
64
  st.title("Human Activity Recognition")
 
81
  **Classes:** 6 activities of daily living
82
  """)
83
  st.markdown("---")
84
+ st.markdown("**Models**")
85
+ st.markdown("""
86
+ **FFN** β€” Feedforward Network
87
+ Dense(512) β†’ Dense(256) β†’ Dense(128)
88
+ BatchNorm + Dropout(0.3) per layer
89
+
90
+ **CNN** β€” 1D Convolutional Network
91
+ Conv1D(64) β†’ Conv1D(128) β†’ Conv1D(256)
92
+ GlobalAvgPool β†’ Dense(128)
93
+ """)
94
  st.markdown("---")
95
  st.caption("DAT606 Group Assignment Β· Pan-Atlantic University")
96
 
97
+ # ── Load both models at startup ───────────────────────────────────────────────
98
 
99
+ ffn_model, ffn_status = load_model("model.keras")
100
+ cnn_model, cnn_status = load_model("har_cnn.keras")
101
 
102
+ if ffn_status != "ready" or cnn_status != "ready":
103
+ if ffn_status != "ready":
104
+ st.warning(f"FFN not loaded β€” {ffn_status}")
105
+ if cnn_status != "ready":
106
+ st.warning(f"CNN not loaded β€” {cnn_status}")
107
 
108
  # ── Tabs ─────────────────────────────────────────────────────────────────────
109
 
 
120
 
121
  try:
122
  samples_df = pd.read_csv(_SAMPLES_PATH)
123
+ feature_cols = [c for c in samples_df.columns if c not in ["Activity", "subject"]]
 
 
 
124
 
125
  sample_labels = [
126
  f"Sample {i+1} β€” {row['Activity']}"
 
140
  st.metric("Feature count", len(feature_vector))
141
 
142
  if st.button("Classify this sample", type="primary"):
143
+ if ffn_status != "ready" or cnn_status != "ready":
144
+ st.error("One or both models not loaded β€” cannot predict yet.")
145
  else:
146
  arr = feature_vector.reshape(1, -1)
147
+
148
+ ffn_probs = ffn_model.predict(arr, verbose=0)[0]
149
+ cnn_probs = cnn_model.predict(arr, verbose=0)[0]
150
+
151
+ ffn_idx = int(np.argmax(ffn_probs))
152
+ cnn_idx = int(np.argmax(cnn_probs))
153
+ ffn_label = LABEL_MAP[ffn_idx]
154
+ cnn_label = LABEL_MAP[cnn_idx]
155
+ ffn_conf = float(ffn_probs[ffn_idx]) * 100
156
+ cnn_conf = float(cnn_probs[cnn_idx]) * 100
157
 
158
  st.markdown("---")
159
+ st.subheader("Model comparison")
160
+
161
+ left, right = st.columns(2)
162
+
163
+ # ── FFN column ──────────────────────────────────────────────
164
+ with left:
165
+ st.markdown("#### Feedforward Network")
166
+ if ffn_label == true_label:
167
+ st.success(f"**{ffn_label}** Β· {ffn_conf:.1f}% confidence Β· βœ“ Correct")
168
+ else:
169
+ st.error(f"**{ffn_label}** Β· {ffn_conf:.1f}% confidence Β· βœ— Incorrect (true: {true_label})")
170
+
171
+ st.markdown(f"_{EXPLANATIONS[ffn_label]}_")
172
+ st.markdown("**Confidence across all classes**")
173
+ st.bar_chart(pd.DataFrame(
174
+ {"Confidence (%)": [float(ffn_probs[i]) * 100 for i in range(6)]},
175
+ index=[LABEL_MAP[i] for i in range(6)]
176
+ ))
177
+
178
+ # ── CNN column ──────────────────────────────────────────────
179
+ with right:
180
+ st.markdown("#### 1D Convolutional Network")
181
+ if cnn_label == true_label:
182
+ st.success(f"**{cnn_label}** Β· {cnn_conf:.1f}% confidence Β· βœ“ Correct")
183
+ else:
184
+ st.error(f"**{cnn_label}** Β· {cnn_conf:.1f}% confidence Β· βœ— Incorrect (true: {true_label})")
185
+
186
+ st.markdown(f"_{EXPLANATIONS[cnn_label]}_")
187
+ st.markdown("**Confidence across all classes**")
188
+ st.bar_chart(pd.DataFrame(
189
+ {"Confidence (%)": [float(cnn_probs[i]) * 100 for i in range(6)]},
190
+ index=[LABEL_MAP[i] for i in range(6)]
191
+ ))
192
 
193
  except FileNotFoundError:
194
  st.error("Sample data file not found. Add `data/samples.csv` to the repo.")