gtech13 commited on
Commit
009c76c
·
verified ·
1 Parent(s): d7701a0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -34
app.py CHANGED
@@ -12,13 +12,19 @@ import pandas as pd
12
  import numpy as np
13
  import time
14
 
15
-
16
  # ==========================================
17
- # 1. PAGE CONFIG & UI SETUP
18
  # ==========================================
19
  st.set_page_config(page_title="Neural VAE Architecture", layout="wide")
20
 
21
- # (Make sure these two lines only appear ONCE in your entire file!)
 
 
 
 
 
 
 
22
  st.title("🧠 Variational Autoencoder (VAE): Inside the Black Box")
23
  st.markdown("Watch the mathematics of a Neural Network transform text into topics in real-time.")
24
 
@@ -35,7 +41,6 @@ st.divider()
35
  def load_bert():
36
  return SentenceTransformer("all-MiniLM-L6-v2")
37
 
38
-
39
  # --- SIDEBAR CONTROLS ---
40
  st.sidebar.header("1. Input & Text Prep")
41
  n_topics = st.sidebar.slider("Number of Topics (Latent Dimensions)", 2, 10, 3)
@@ -69,7 +74,6 @@ class ContextualVAE(nn.Module):
69
  super().__init__()
70
  act_fn = nn.ReLU() if activation == "ReLU" else nn.Softplus() if activation == "Softplus" else nn.GELU()
71
 
72
- # 1. ENCODER
73
  self.encoder = nn.Sequential(
74
  nn.Linear(input_dim, hidden_dim),
75
  act_fn,
@@ -78,8 +82,6 @@ class ContextualVAE(nn.Module):
78
  )
79
  self.fc_mu = nn.Linear(hidden_dim, latent_dim)
80
  self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
81
-
82
- # 2. DECODER
83
  self.decoder = nn.Linear(latent_dim, vocab_size, bias=False)
84
 
85
  def encode(self, x):
@@ -150,7 +152,6 @@ if st.sidebar.button("🚀 Start Backpropagation", type="primary", use_container
150
 
151
  sentences = [s.strip() for s in raw_data.split('.') if len(s.strip()) > 10]
152
 
153
- # Data Prep
154
  stop_w = list(CountVectorizer(stop_words='english').get_stop_words()) + ['students', 'course']
155
  vectorizer = CountVectorizer(stop_words=stop_w)
156
  bow_matrix = vectorizer.fit_transform(sentences).toarray()
@@ -167,11 +168,7 @@ if st.sidebar.button("🚀 Start Backpropagation", type="primary", use_container
167
  optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
168
 
169
  recon_hist, kl_hist = [], []
170
-
171
- # Trackers for the expanding history tables
172
- history_encoder = []
173
- history_latent = []
174
- history_decoder = []
175
 
176
  # --- PYTORCH TRAINING LOOP ---
177
  for epoch in range(1, epochs + 1):
@@ -189,20 +186,15 @@ if st.sidebar.button("🚀 Start Backpropagation", type="primary", use_container
189
  total_loss.backward()
190
  optimizer.step()
191
 
192
- # ==========================================
193
- # 1. RECORD DATA EVERY SINGLE EPOCH
194
- # ==========================================
195
  # Grab math for Sentence 1
196
  s1_mu = np.round(mu[0].detach().numpy(), 3).tolist()
197
  s1_var = np.round(torch.exp(0.5 * logvar[0]).detach().numpy(), 3).tolist()
198
  s1_z = np.round(z[0].detach().numpy(), 3).tolist()
199
  s1_soft = np.round(F.softmax(z[0], dim=-1).detach().numpy(), 3).tolist()
200
 
201
- # Save to Encoder & Latent History
202
  history_encoder.append({"Epoch": epoch, "Mean (μ)": str(s1_mu), "Variance (σ)": str(s1_var)})
203
  history_latent.append({"Epoch": epoch, "Sampled Vector (Z)": str(s1_z), "Topic Probs": str(s1_soft)})
204
 
205
- # Dynamically create separate columns for EACH topic in the Decoder history!
206
  weights = model.decoder.weight.T
207
  dec_dict = {"Epoch": epoch}
208
  dec_text = ""
@@ -210,10 +202,7 @@ if st.sidebar.button("🚀 Start Backpropagation", type="primary", use_container
210
  for i in range(n_topics):
211
  top_idx = torch.argsort(weights[i], descending=True)[:words_per_theme]
212
  theme_words = [vocab[j] for j in top_idx]
213
-
214
- # Format for the UI Box
215
  dec_text += f"**T{i+1}:** {', '.join(theme_words)}\n\n"
216
- # Format for the DataFrame (Separate column for Topic 1, Topic 2, etc.)
217
  dec_dict[f"Topic {i+1}"] = ", ".join(theme_words)
218
 
219
  history_decoder.append(dec_dict)
@@ -222,34 +211,28 @@ if st.sidebar.button("🚀 Start Backpropagation", type="primary", use_container
222
  kl_hist.append((current_beta * kl_loss).item())
223
 
224
  # ==========================================
225
- # 2. SAFE UI RENDER (Draws the accumulated data every 20 epochs)
226
  # ==========================================
227
  if epoch % 20 == 0 or epoch == epochs:
228
 
229
- # Update Live Values
230
  ui_mu.info(f"**Mean (μ) for Sentence 1:**\n`{s1_mu}`")
231
  ui_var.warning(f"**Variance (σ) for Sentence 1:**\n`{s1_var}`")
232
  ui_z.success(f"**Sampled 'Z' for Sentence 1:**\n`{s1_z}`")
233
  ui_softmax.error(f"**Topic Probabilities:**\n`{s1_soft}`")
234
  ui_decoder.info(dec_text)
235
 
236
- # Update Tables (These now contain ALL epochs up to this point!)
237
- ui_encoder_table.dataframe(pd.DataFrame(history_encoder), hide_index=True, use_container_width=True)
238
- ui_latent_table.dataframe(pd.DataFrame(history_latent), hide_index=True, use_container_width=True)
239
- ui_decoder_table.dataframe(pd.DataFrame(history_decoder), hide_index=True, use_container_width=True)
240
 
241
- # Update Optimization Metrics
242
  ui_beta.metric("Current Beta (Annealing)", f"{current_beta:.4f}")
243
  ui_recon_loss.metric("Reconstruction Loss", f"{recon_loss.item():.4f}")
244
  ui_kl_loss.metric("KL Penalty", f"{(current_beta * kl_loss).item():.4f}")
245
 
246
- # Update Graph
247
- chart_df = pd.DataFrame({
248
- "Recon Loss": recon_hist,
249
- "KL Penalty": kl_hist
250
- })
251
  loss_chart_placeholder.line_chart(chart_df)
252
 
253
- time.sleep(0.05)
254
 
255
  st.success("Neural Network Training Complete!")
 
12
  import numpy as np
13
  import time
14
 
 
15
  # ==========================================
16
+ # 1. PAGE CONFIG & UI SETUP (WITH ANTI-GLITCH CSS)
17
  # ==========================================
18
  st.set_page_config(page_title="Neural VAE Architecture", layout="wide")
19
 
20
+ # FIX: CSS injection to permanently lock the scrollbar and prevent horizontal jumping!
21
+ st.markdown("""
22
+ <style>
23
+ html { overflow-y: scroll; }
24
+ .block-container { overflow-x: hidden; }
25
+ </style>
26
+ """, unsafe_allow_html=True)
27
+
28
  st.title("🧠 Variational Autoencoder (VAE): Inside the Black Box")
29
  st.markdown("Watch the mathematics of a Neural Network transform text into topics in real-time.")
30
 
 
41
  def load_bert():
42
  return SentenceTransformer("all-MiniLM-L6-v2")
43
 
 
44
  # --- SIDEBAR CONTROLS ---
45
  st.sidebar.header("1. Input & Text Prep")
46
  n_topics = st.sidebar.slider("Number of Topics (Latent Dimensions)", 2, 10, 3)
 
74
  super().__init__()
75
  act_fn = nn.ReLU() if activation == "ReLU" else nn.Softplus() if activation == "Softplus" else nn.GELU()
76
 
 
77
  self.encoder = nn.Sequential(
78
  nn.Linear(input_dim, hidden_dim),
79
  act_fn,
 
82
  )
83
  self.fc_mu = nn.Linear(hidden_dim, latent_dim)
84
  self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
 
 
85
  self.decoder = nn.Linear(latent_dim, vocab_size, bias=False)
86
 
87
  def encode(self, x):
 
152
 
153
  sentences = [s.strip() for s in raw_data.split('.') if len(s.strip()) > 10]
154
 
 
155
  stop_w = list(CountVectorizer(stop_words='english').get_stop_words()) + ['students', 'course']
156
  vectorizer = CountVectorizer(stop_words=stop_w)
157
  bow_matrix = vectorizer.fit_transform(sentences).toarray()
 
168
  optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
169
 
170
  recon_hist, kl_hist = [], []
171
+ history_encoder, history_latent, history_decoder = [], [], []
 
 
 
 
172
 
173
  # --- PYTORCH TRAINING LOOP ---
174
  for epoch in range(1, epochs + 1):
 
186
  total_loss.backward()
187
  optimizer.step()
188
 
 
 
 
189
  # Grab math for Sentence 1
190
  s1_mu = np.round(mu[0].detach().numpy(), 3).tolist()
191
  s1_var = np.round(torch.exp(0.5 * logvar[0]).detach().numpy(), 3).tolist()
192
  s1_z = np.round(z[0].detach().numpy(), 3).tolist()
193
  s1_soft = np.round(F.softmax(z[0], dim=-1).detach().numpy(), 3).tolist()
194
 
 
195
  history_encoder.append({"Epoch": epoch, "Mean (μ)": str(s1_mu), "Variance (σ)": str(s1_var)})
196
  history_latent.append({"Epoch": epoch, "Sampled Vector (Z)": str(s1_z), "Topic Probs": str(s1_soft)})
197
 
 
198
  weights = model.decoder.weight.T
199
  dec_dict = {"Epoch": epoch}
200
  dec_text = ""
 
202
  for i in range(n_topics):
203
  top_idx = torch.argsort(weights[i], descending=True)[:words_per_theme]
204
  theme_words = [vocab[j] for j in top_idx]
 
 
205
  dec_text += f"**T{i+1}:** {', '.join(theme_words)}\n\n"
 
206
  dec_dict[f"Topic {i+1}"] = ", ".join(theme_words)
207
 
208
  history_decoder.append(dec_dict)
 
211
  kl_hist.append((current_beta * kl_loss).item())
212
 
213
  # ==========================================
214
+ # 2. SAFE UI RENDER (Every 20 epochs)
215
  # ==========================================
216
  if epoch % 20 == 0 or epoch == epochs:
217
 
 
218
  ui_mu.info(f"**Mean (μ) for Sentence 1:**\n`{s1_mu}`")
219
  ui_var.warning(f"**Variance (σ) for Sentence 1:**\n`{s1_var}`")
220
  ui_z.success(f"**Sampled 'Z' for Sentence 1:**\n`{s1_z}`")
221
  ui_softmax.error(f"**Topic Probabilities:**\n`{s1_soft}`")
222
  ui_decoder.info(dec_text)
223
 
224
+ # FIX: Added `height=200` to prevent the dataframe from stretching the webpage!
225
+ ui_encoder_table.dataframe(pd.DataFrame(history_encoder), hide_index=True, use_container_width=True, height=200)
226
+ ui_latent_table.dataframe(pd.DataFrame(history_latent), hide_index=True, use_container_width=True, height=200)
227
+ ui_decoder_table.dataframe(pd.DataFrame(history_decoder), hide_index=True, use_container_width=True, height=200)
228
 
 
229
  ui_beta.metric("Current Beta (Annealing)", f"{current_beta:.4f}")
230
  ui_recon_loss.metric("Reconstruction Loss", f"{recon_loss.item():.4f}")
231
  ui_kl_loss.metric("KL Penalty", f"{(current_beta * kl_loss).item():.4f}")
232
 
233
+ chart_df = pd.DataFrame({"Recon Loss": recon_hist, "KL Penalty": kl_hist})
 
 
 
 
234
  loss_chart_placeholder.line_chart(chart_df)
235
 
236
+ time.sleep(0.01) # Slightly faster sleep to prevent HF WebSocket timeouts
237
 
238
  st.success("Neural Network Training Complete!")