Linaya commited on
Commit
f5d1e47
·
verified ·
1 Parent(s): cae8700

Final final updates to app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -29
app.py CHANGED
@@ -207,20 +207,6 @@ def read_input(file, text):
207
  return open(path, encoding="utf-8", errors="replace").read()
208
 
209
 
210
- def bar(k, n, colour):
211
- #count + a thin bar showing what share of the segments got flagged
212
- return (f"<td><div class='cell'><b>{k}</b><span class='bar'>"
213
- f"<span style='width:{k / n * 100:.0f}%;background:{colour}'></span></span></div></td>")
214
-
215
-
216
- def meter(p, thr):
217
- #track from 0 to 1, fill = top bert score, white tick = threshold
218
- colour = "#818cf8" if p >= thr else "#4b5370"
219
- return (f"<div class='cell'><span class='meter'><span class='fill' style='width:{p * 100:.0f}%;background:{colour}'></span>"
220
- f"<span class='tick' style='left:{thr * 100:.0f}%'></span></span>"
221
- f"<span class='small'>{p:.2f} / {thr:.2f}</span></div>")
222
-
223
-
224
  @GPU
225
  def analyse(file, text):
226
  raw = read_input(file, text)
@@ -274,15 +260,14 @@ def analyse(file, text):
274
  v = np.array([vader_flags(s) for s in segs])
275
  t = tfidf_probs(segs)
276
  b = bert_probs(segs)
277
- n = len(segs)
278
  rows = ""
279
  for i, c in enumerate(CATEGORIES):
280
- counts = [int(v[:, i].sum()), int((t[:, i] >= 0.5).sum()), int((b[:, i] >= BERT_THRESHOLDS[c]).sum())]
281
- cells = "".join(bar(k, n, col) for k, col in zip(counts, ["#f472b6", "#a78bfa", "#34d399"]))
282
- rows += f"<tr><td>{NAMES[c]}</td>{cells}<td>{meter(b[:, i].max(), BERT_THRESHOLDS[c])}</td></tr>"
283
- s5 = (f"<h4>5. Classification: all three models</h4>"
284
- f"<table><tr><th>Category</th><th>VADER</th><th>TF-IDF</th><th>BERT + LoRA</th><th>BERT top score vs threshold</th></tr>{rows}</table>"
285
- f"<p class='small'>Segments flagged out of {n}. White line = BERT threshold, the bar fills to the top segment score </p>")
286
 
287
  order = np.argsort(-b.max(axis=1)) #strongest segments first for shap
288
  choices = [f"#{k + 1} (BERT max {b[k].max():.2f}) {segs[k][:60]}..." for k in order]
@@ -311,21 +296,37 @@ def explain(state, choice, category):
311
  f"<div class='seg' style='line-height:1.9'>{spans}</div>")
312
 
313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  # the page
315
 
316
  CSS = """
317
  .gradio-container {background: radial-gradient(ellipse at top, #141b33 0%, #05070f 70%) !important;}
318
  * {box-shadow: none !important;}
319
  .seg {border: 1px solid #ffffff44; border-radius: 12px; padding: 8px 12px; margin: 6px 0; color: #e6ebff;}
320
- table {width: 100%; border-collapse: collapse; border: none !important; color: #e6ebff;}
321
- th, td {border: none !important; border-bottom: 1px solid #ffffff33 !important; padding: 6px 8px; text-align: left;}
322
  .small {color: #9aa4c4; font-size: 13px;}
323
- .cell {display: flex; align-items: center; gap: 8px;}
324
- .bar {flex: 1; min-width: 40px; height: 6px; background: #ffffff14; border-radius: 3px; overflow: hidden;}
325
- .bar span {display: block; height: 100%;}
326
- .meter {position: relative; flex: 1; min-width: 80px; height: 8px; background: #ffffff14; border-radius: 4px;}
327
- .meter .fill {position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px;}
328
- .meter .tick {position: absolute; top: -4px; bottom: -4px; width: 2px; background: #fff;}
329
  """
330
 
331
  with gr.Blocks(title="SPACEMIND") as demo:
@@ -340,6 +341,16 @@ with gr.Blocks(title="SPACEMIND") as demo:
340
  clearButton = gr.ClearButton()
341
  runButton = gr.Button("Run the pipeline", variant="primary")
342
 
 
 
 
 
 
 
 
 
 
 
343
  #right side: the stages
344
  with gr.Column():
345
  out1 = gr.Textbox(label="1. Input (word count)")
 
207
  return open(path, encoding="utf-8", errors="replace").read()
208
 
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  @GPU
211
  def analyse(file, text):
212
  raw = read_input(file, text)
 
260
  v = np.array([vader_flags(s) for s in segs])
261
  t = tfidf_probs(segs)
262
  b = bert_probs(segs)
 
263
  rows = ""
264
  for i, c in enumerate(CATEGORIES):
265
+ rows += (f"<tr><td>{NAMES[c]}</td><td>{int(v[:, i].sum())}</td><td>{int((t[:, i] >= 0.5).sum())}</td>"
266
+ f"<td><b>{int((b[:, i] >= BERT_THRESHOLDS[c]).sum())}</b></td><td>{b[:, i].max():.2f} / {BERT_THRESHOLDS[c]:.2f}</td></tr>")
267
+ s5 = (f"<h4>5. Classification: all three models</h4><table><tr><th>Category</th><th>VADER</th><th>TF-IDF</th><th>BERT + LoRA</th>"
268
+ f"<th>BERT top prob / threshold</th></tr>{rows}</table>"
269
+ f"<p class='small'>Numbers are segments flagged out of {len(segs)}. BERT is my final model. "
270
+ f"A research prototype, it flags passages for a person to read and does not diagnose anyone.</p>")
271
 
272
  order = np.argsort(-b.max(axis=1)) #strongest segments first for shap
273
  choices = [f"#{k + 1} (BERT max {b[k].max():.2f}) {segs[k][:60]}..." for k in order]
 
296
  f"<div class='seg' style='line-height:1.9'>{spans}</div>")
297
 
298
 
299
+ #files for the examiners to try (loose in the space or inside a test_set folder)
300
+ TEST_SET = [("ridesk-12-6-02.txt", "Sally Ride, Shuttle"), ("crippenrl-10-16-12.txt", "Robert Crippen, Shuttle"),
301
+ ("whitsonpa-9-6-12.txt", "Peggy Whitson, ISS"), ("pettitdr-8-17-15.pdf", "Donald Pettit, ISS (PDF)"),
302
+ ("harttj-4-10-03.txt", "Terry Hart, Shuttle"), ("rossjl-12-4-03.txt", "Jerry Ross, Shuttle"),
303
+ ("mullanerm-1-24-03.txt", "Mike Mullane, Shuttle"), ("armstrongna-9-19-01.txt", "Neil Armstrong, Apollo")]
304
+ PIPELINE_TESTS = [("1_WORKS_cover_page_transcript.txt", "Works: transcript with cover page"),
305
+ ("2_TEST_one_short_sentence.txt", "Test: one short sentence"),
306
+ ("3_TEST_speaker_names_not_in_capitals.txt", "Test: speaker names not in capitals"),
307
+ ("4_TEST_curly_apostrophe_in_name.txt", "Test: curly apostrophe in a name"),
308
+ ("5_TEST_technical_no_strain.txt", "Test: technical, no strain")]
309
+
310
+
311
+ def find_files(pairs):
312
+ found = []
313
+ for name, label in pairs:
314
+ for folder in [os.path.join(HERE, "test_set"), HERE]:
315
+ if os.path.exists(os.path.join(folder, name)):
316
+ found.append((os.path.join(folder, name), label))
317
+ break
318
+ return found
319
+
320
+
321
  # the page
322
 
323
  CSS = """
324
  .gradio-container {background: radial-gradient(ellipse at top, #141b33 0%, #05070f 70%) !important;}
325
  * {box-shadow: none !important;}
326
  .seg {border: 1px solid #ffffff44; border-radius: 12px; padding: 8px 12px; margin: 6px 0; color: #e6ebff;}
327
+ table {width: 100%; border-collapse: collapse; color: #e6ebff;}
328
+ th, td {border-bottom: 1px solid #ffffff33; padding: 6px 8px; text-align: left;}
329
  .small {color: #9aa4c4; font-size: 13px;}
 
 
 
 
 
 
330
  """
331
 
332
  with gr.Blocks(title="SPACEMIND") as demo:
 
341
  clearButton = gr.ClearButton()
342
  runButton = gr.Button("Run the pipeline", variant="primary")
343
 
344
+ #held out test astronauts --> the model never saw them in training
345
+ heldOut = find_files(TEST_SET)
346
+ if heldOut:
347
+ gr.Examples([[p] for p, _ in heldOut], inputs=fileInput, example_labels=[l for _, l in heldOut],
348
+ label="Load a transcript from my held-out test set")
349
+ tests = find_files(PIPELINE_TESTS)
350
+ if tests:
351
+ gr.Examples([[p] for p, _ in tests], inputs=fileInput, example_labels=[l for _, l in tests],
352
+ label="Pipeline tests (where it works and where it breaks)")
353
+
354
  #right side: the stages
355
  with gr.Column():
356
  out1 = gr.Textbox(label="1. Input (word count)")