Sina1138 commited on
Commit Β·
b3f059b
1
Parent(s): ea770c8
enhance GLIMPSE interface with polarity and topic analysis features
Browse files- interface/Demo.py +243 -132
interface/Demo.py
CHANGED
|
@@ -3,17 +3,20 @@ import numpy as np
|
|
| 3 |
import seaborn as sns
|
| 4 |
|
| 5 |
import sys, os.path
|
|
|
|
|
|
|
| 6 |
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))
|
| 7 |
|
| 8 |
from glimpse.rsasumm.rsa_reranker import RSAReranking
|
| 9 |
import gradio as gr
|
| 10 |
-
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
|
| 11 |
import seaborn as sns
|
| 12 |
import pandas as pd
|
| 13 |
import matplotlib.pyplot as plt
|
| 14 |
|
| 15 |
from scored_reviews_builder import load_scored_reviews
|
| 16 |
from glimpse.glimpse.data_loading.Glimpse_tokenizer import glimpse_tokenizer
|
|
|
|
| 17 |
|
| 18 |
# Load scored reviews
|
| 19 |
years, all_scored_reviews_df = load_scored_reviews()
|
|
@@ -31,21 +34,47 @@ def get_preprocessed_scores(year):
|
|
| 31 |
# Interactive Tab
|
| 32 |
# -----------------------------------
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
-
|
| 37 |
-
tokenizer = AutoTokenizer.from_pretrained(MODEL)
|
| 38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
|
| 40 |
EXAMPLES = [
|
| 41 |
"The paper gives really interesting insights on the topic of transfer learning. It is well presented and the experiment are extensive. I believe the authors missed Jane and al 2021. In addition, I think, there is a mistake in the math.",
|
| 42 |
"The paper gives really interesting insights on the topic of transfer learning. It is well presented and the experiment are extensive. Some parts remain really unclear and I would like to see a more detailed explanation of the proposed method.",
|
| 43 |
"The paper gives really interesting insights on the topic of transfer learning. It is not well presented and lack experiments. Some parts remain really unclear and I would like to see a more detailed explanation of the proposed method.",
|
| 44 |
]
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
def summarize(text1, text2, text3, focus, mode, rationality, iterations=2):
|
| 49 |
|
| 50 |
print(focus, mode, rationality, iterations)
|
| 51 |
|
|
@@ -61,6 +90,63 @@ def summarize(text1, text2, text3, focus, mode, rationality, iterations=2):
|
|
| 61 |
text3_sentences = [sentence for sentence in text3_sentences if sentence != ""]
|
| 62 |
|
| 63 |
sentences = list(set(text1_sentences + text2_sentences + text3_sentences))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
rsa_reranker = RSAReranking(
|
| 66 |
model,
|
|
@@ -100,7 +186,6 @@ def summarize(text1, text2, text3, focus, mode, rationality, iterations=2):
|
|
| 100 |
|
| 101 |
# normalize consensuality scores between -1 and 1
|
| 102 |
consensuality_scores = (consensuality_scores - (consensuality_scores.max() - consensuality_scores.min()) / 2) / (consensuality_scores.max() - consensuality_scores.min()) / 2
|
| 103 |
-
consensuality_scores_01 = (consensuality_scores - consensuality_scores.min()) / (consensuality_scores.max() - consensuality_scores.min())
|
| 104 |
|
| 105 |
# get most and least consensual sentences
|
| 106 |
# most consensual --> most common; least consensual --> most unique
|
|
@@ -119,50 +204,51 @@ def summarize(text1, text2, text3, focus, mode, rationality, iterations=2):
|
|
| 119 |
text_2_consensuality = [(sentence, text_2_consensuality[sentence]) for sentence in text2_sentences]
|
| 120 |
text_3_consensuality = [(sentence, text_3_consensuality[sentence]) for sentence in text3_sentences]
|
| 121 |
|
| 122 |
-
text_1_consensuality_ = consensuality_scores_01.loc[text1_sentences]
|
| 123 |
-
text_2_consensuality_ = consensuality_scores_01.loc[text2_sentences]
|
| 124 |
-
text_3_consensuality_ = consensuality_scores_01.loc[text3_sentences]
|
| 125 |
-
|
| 126 |
-
text_1_consensuality_ = [(sentence, text_1_consensuality_[sentence]) for sentence in text1_sentences]
|
| 127 |
-
text_2_consensuality_ = [(sentence, text_2_consensuality_[sentence]) for sentence in text2_sentences]
|
| 128 |
-
text_3_consensuality_ = [(sentence, text_3_consensuality_[sentence]) for sentence in text3_sentences]
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
-
#
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
|
| 136 |
print(type(text_1_consensuality))
|
| 137 |
-
return
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
Unlike traditional summarization methods that focus on consensus opinions, GLIMPSE emphasizes **both alignment and divergence** in reviewer feedback. This approach provides a **balanced and transparent representation** of the review content, supporting informed decision-making processes.
|
| 147 |
-
|
| 148 |
-
---
|
| 149 |
-
|
| 150 |
-
## **Key Features**
|
| 151 |
-
- **Discriminative Summarization:** Highlights both shared insights and unique arguments across reviews.
|
| 152 |
-
- **RSA-Based Scoring:** Prioritizes key statements based on informativeness and uniqueness metrics.
|
| 153 |
-
- **Balanced Summaries:** Ensures clarity and coverage of diverse reviewer perspectives.
|
| 154 |
-
- **Traceability and Transparency:** Maintains clear attribution of summarized points to their original sources.
|
| 155 |
-
|
| 156 |
-
GLIMPSE is designed to **streamline the review synthesis process**, offering an effective and reliable method for extracting meaningful insights from complex review datasets.
|
| 157 |
|
| 158 |
-
---
|
| 159 |
|
| 160 |
-
For more information and to begin using GLIMPSE, please proceed with the interface.
|
| 161 |
-
You can choose between the **Interactive** mode for real-time summarization or the **Pre-processed** mode for batch processing of review data.
|
| 162 |
-
"""
|
| 163 |
|
| 164 |
|
| 165 |
-
with gr.Blocks(title="
|
| 166 |
gr.Markdown("# GlimpSys Interface")
|
| 167 |
|
| 168 |
with gr.Tab("Introduction"):
|
|
@@ -189,18 +275,21 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 189 |
state = gr.State(initial_state)
|
| 190 |
|
| 191 |
def update_review_display(state, score_type):
|
| 192 |
-
|
|
|
|
|
|
|
|
|
|
| 193 |
# First clear all components
|
| 194 |
clear_updates = [gr.update(value=[]) for _ in range(8)]
|
| 195 |
-
|
| 196 |
review_ids = state["review_ids"]
|
| 197 |
current_index = state["current_review_index"]
|
| 198 |
current_review = state["scored_reviews_for_year"][review_ids[current_index]]
|
| 199 |
|
| 200 |
show_polarity = score_type == "Polarity"
|
| 201 |
-
show_consensuality = score_type == "
|
| 202 |
-
show_topic = score_type == "
|
| 203 |
-
|
| 204 |
if show_polarity:
|
| 205 |
color_map = {"β": "#d4fcd6", "β": "#fcd6d6"}
|
| 206 |
elif show_topic:
|
|
@@ -210,7 +299,6 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 210 |
else:
|
| 211 |
color_map = {}
|
| 212 |
|
| 213 |
-
|
| 214 |
new_review_id = (
|
| 215 |
f"### Submission Link:\n\n{review_ids[current_index]}<br>"
|
| 216 |
f"(Showing {current_index + 1} of {len(state['review_ids'])} reviews)"
|
|
@@ -239,6 +327,9 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 239 |
highlighted = []
|
| 240 |
for sentence, metadata in review_item:
|
| 241 |
score = metadata.get("consensuality", 0.0)
|
|
|
|
|
|
|
|
|
|
| 242 |
consensuality_dict[sentence] = score
|
| 243 |
highlighted.append((sentence, score))
|
| 244 |
elif show_topic:
|
|
@@ -260,7 +351,7 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 260 |
visible=True,
|
| 261 |
value=highlighted,
|
| 262 |
color_map=color_map or {},
|
| 263 |
-
show_legend=False,
|
| 264 |
)
|
| 265 |
)
|
| 266 |
else:
|
|
@@ -284,21 +375,24 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 284 |
most_common_visibility = gr.update(visible=True, value=most_common_text)
|
| 285 |
most_unique_visibility = gr.update(visible=True, value=most_unique_text)
|
| 286 |
else:
|
|
|
|
|
|
|
|
|
|
| 287 |
most_common_visibility = gr.update(visible=False, value="")
|
| 288 |
most_unique_visibility = gr.update(visible=False, value="")
|
| 289 |
|
| 290 |
return (
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
# Precompute the initial outputs so something is shown on load.
|
| 301 |
-
init_display = update_review_display(initial_state, score_type="
|
| 302 |
# init_display returns: (review_id, review1, review2, review3, review4, review5, review6, review7, review8, state)
|
| 303 |
|
| 304 |
with gr.Row():
|
|
@@ -306,7 +400,7 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 306 |
# Input controls.
|
| 307 |
year = gr.Dropdown(choices=years, label="Select Year", interactive=True, value=initial_year)
|
| 308 |
score_type = gr.Radio(
|
| 309 |
-
choices=["Original", "
|
| 310 |
label="Score Type to Display",
|
| 311 |
value="Original",
|
| 312 |
interactive=True
|
|
@@ -319,17 +413,18 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 319 |
next_button = gr.Button("Next", variant="primary", interactive=True)
|
| 320 |
|
| 321 |
# Output display.
|
| 322 |
-
|
| 323 |
-
|
|
|
|
| 324 |
label="Most Common Sentences",
|
| 325 |
visible=False,
|
| 326 |
-
|
| 327 |
)
|
| 328 |
-
|
| 329 |
-
lines=
|
| 330 |
label="Most Unique Sentences",
|
| 331 |
visible=False,
|
| 332 |
-
|
| 333 |
)
|
| 334 |
|
| 335 |
review1 = gr.HighlightedText(
|
|
@@ -428,15 +523,7 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 428 |
# -----------------------------------
|
| 429 |
# Interactive Tab
|
| 430 |
# -----------------------------------
|
| 431 |
-
with gr.Tab("Interactive", interactive=True):
|
| 432 |
-
gr.Markdown("""
|
| 433 |
-
This is an interactive demo of the GLIMPSE Method.\n
|
| 434 |
-
After pressing the 'Process' button, the model will generate the requested outputs based on the selected parameters.
|
| 435 |
-
The 'Output Mode' parameter allows you to choose between in-line highlighting and summary generation.
|
| 436 |
-
- In case of **In-Line Highlighting** mode, the 'Focus on' parameter allows you to choose between uniqueness and commonality.
|
| 437 |
-
- For **Summary Generation**, you can choose between having extractive or abstractive (TBA) summaries.
|
| 438 |
-
""")
|
| 439 |
-
|
| 440 |
with gr.Row():
|
| 441 |
with gr.Column():
|
| 442 |
|
|
@@ -444,9 +531,9 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 444 |
|
| 445 |
# review_count = gr.Slider(minimum=1, maximum=3, step=1, value=3, label="Number of Reviews", interactive=True)
|
| 446 |
|
| 447 |
-
review1_textbox = gr.Textbox(lines=
|
| 448 |
-
review2_textbox = gr.Textbox(lines=
|
| 449 |
-
review3_textbox = gr.Textbox(lines=
|
| 450 |
|
| 451 |
with gr.Row():
|
| 452 |
submit_button = gr.Button("Process", variant="primary", interactive=True)
|
|
@@ -463,10 +550,11 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 463 |
choices=[("In-line Highlighting", "highlight"), ("Generate Summaries", "summary")],
|
| 464 |
value="highlight",
|
| 465 |
label="Output Mode:",
|
| 466 |
-
interactive=
|
|
|
|
| 467 |
)
|
| 468 |
focus_radio = gr.Radio(
|
| 469 |
-
choices=[("
|
| 470 |
value="unique",
|
| 471 |
label="Focus on:",
|
| 472 |
interactive=True
|
|
@@ -481,35 +569,51 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 481 |
|
| 482 |
# Fixed rationality (3.0) and iterations (2) to be consistent with the compute_rsa.py script
|
| 483 |
#iterations_slider = gr.Slider(minimum=1, maximum=10, step=1, value=2, label="Iterations", interactive=False, visible=False)
|
| 484 |
-
rationality_slider = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=2.0, label="Rationality", interactive=False, visible=False)
|
| 485 |
-
|
| 486 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
uniqueness_score_text1 = gr.HighlightedText(
|
| 488 |
-
show_legend=True, label="
|
| 489 |
)
|
| 490 |
uniqueness_score_text2 = gr.HighlightedText(
|
| 491 |
-
show_legend=True, label="
|
| 492 |
)
|
| 493 |
uniqueness_score_text3 = gr.HighlightedText(
|
| 494 |
-
show_legend=True, label="
|
| 495 |
)
|
| 496 |
-
|
| 497 |
-
|
|
|
|
|
|
|
|
|
|
| 498 |
)
|
| 499 |
-
|
| 500 |
-
show_legend=True, label="
|
|
|
|
| 501 |
)
|
| 502 |
-
|
| 503 |
-
show_legend=True, label="
|
|
|
|
| 504 |
)
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 513 |
|
| 514 |
|
| 515 |
# Connect summarize function to submit button
|
|
@@ -517,12 +621,14 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 517 |
fn=summarize,
|
| 518 |
inputs=[
|
| 519 |
review1_textbox, review2_textbox, review3_textbox,
|
| 520 |
-
focus_radio, mode_radio
|
| 521 |
],
|
| 522 |
outputs=[
|
| 523 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 524 |
-
|
| 525 |
-
|
|
|
|
|
|
|
| 526 |
]
|
| 527 |
)
|
| 528 |
|
|
@@ -533,43 +639,47 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 533 |
outputs=[
|
| 534 |
review1_textbox, review2_textbox, review3_textbox,
|
| 535 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 536 |
-
|
| 537 |
-
most_consensual_sentences, most_unique_sentences
|
| 538 |
]
|
| 539 |
)
|
| 540 |
|
| 541 |
# Update visibility of generation_method_radio based on mode_radio value
|
| 542 |
-
def toggle_generation_method(mode):
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
|
| 548 |
-
mode_radio.change(
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
|
| 552 |
-
)
|
| 553 |
|
| 554 |
# Update visibility of output textboxes based on mode_radio and focus_radio values
|
| 555 |
def toggle_output_textboxes(mode, focus):
|
| 556 |
if mode == "highlight" and focus == "unique":
|
| 557 |
return (
|
| 558 |
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), # in-line uniqueness highlights
|
| 559 |
-
gr.update(visible=
|
| 560 |
-
gr.update(visible=False), gr.update(visible=False) #
|
|
|
|
| 561 |
)
|
| 562 |
-
|
|
|
|
| 563 |
return (
|
| 564 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # in-line uniqueness highlights
|
| 565 |
-
gr.update(visible=
|
| 566 |
-
gr.update(visible=
|
|
|
|
| 567 |
)
|
| 568 |
-
|
|
|
|
| 569 |
return (
|
| 570 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # in-line uniqueness highlights
|
| 571 |
-
gr.update(visible=False), gr.update(visible=False),
|
| 572 |
-
gr.update(visible=
|
|
|
|
| 573 |
)
|
| 574 |
|
| 575 |
focus_radio.change(
|
|
@@ -577,19 +687,20 @@ with gr.Blocks(title="GLIMPSE") as demo:
|
|
| 577 |
inputs=[mode_radio, focus_radio],
|
| 578 |
outputs=[
|
| 579 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
)
|
| 584 |
-
mode_radio.change(
|
| 585 |
-
fn=toggle_output_textboxes,
|
| 586 |
-
inputs=[mode_radio, focus_radio],
|
| 587 |
-
outputs=[
|
| 588 |
-
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 589 |
-
consensuality_score_text1, consensuality_score_text2, consensuality_score_text3,
|
| 590 |
-
most_consensual_sentences, most_unique_sentences
|
| 591 |
]
|
| 592 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 593 |
|
| 594 |
# TODO: Configure the slider for the number of review boxes
|
| 595 |
|
|
|
|
| 3 |
import seaborn as sns
|
| 4 |
|
| 5 |
import sys, os.path
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))
|
| 9 |
|
| 10 |
from glimpse.rsasumm.rsa_reranker import RSAReranking
|
| 11 |
import gradio as gr
|
| 12 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForSequenceClassification
|
| 13 |
import seaborn as sns
|
| 14 |
import pandas as pd
|
| 15 |
import matplotlib.pyplot as plt
|
| 16 |
|
| 17 |
from scored_reviews_builder import load_scored_reviews
|
| 18 |
from glimpse.glimpse.data_loading.Glimpse_tokenizer import glimpse_tokenizer
|
| 19 |
+
# from scibert.scibert_polarity.scibert_polarity import predict_polarity
|
| 20 |
|
| 21 |
# Load scored reviews
|
| 22 |
years, all_scored_reviews_df = load_scored_reviews()
|
|
|
|
| 34 |
# Interactive Tab
|
| 35 |
# -----------------------------------
|
| 36 |
|
| 37 |
+
RSA_model = "facebook/bart-large-cnn"
|
| 38 |
+
|
| 39 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(RSA_model)
|
| 40 |
+
tokenizer = AutoTokenizer.from_pretrained(RSA_model)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
# GLIMPSE Home/Description Page
|
| 44 |
+
glimpse_description = """
|
| 45 |
+
# GLIMPSE: Pragmatically Informative Multi-Document Summarization of Scholarly Reviews
|
| 46 |
+
|
| 47 |
+
GLIMPSE is a summarization tool designed to assist **area chairs** and **researchers** in efficiently analyzing and synthesizing scholarly peer reviews. Utilizing the **Rational Speech Act (RSA)** framework, GLIMPSE identifies both **common themes** and **unique perspectives** across multiple reviews, ensuring a comprehensive overview of the evaluation landscape.
|
| 48 |
|
| 49 |
+
Unlike traditional summarization methods that focus on consensus opinions, GLIMPSE emphasizes **both alignment and divergence** in reviewer feedback. This approach provides a **balanced and transparent representation** of the review content, supporting informed decision-making processes.
|
|
|
|
| 50 |
|
| 51 |
+
---
|
| 52 |
+
|
| 53 |
+
## **Key Features**
|
| 54 |
+
- **Discriminative Summarization:** Highlights both shared insights and unique arguments across reviews.
|
| 55 |
+
- **RSA-Based Scoring:** Prioritizes key statements based on informativeness and uniqueness metrics.
|
| 56 |
+
- **Balanced Summaries:** Ensures clarity and coverage of diverse reviewer perspectives.
|
| 57 |
+
- **Traceability and Transparency:** Maintains clear attribution of summarized points to their original sources.
|
| 58 |
+
|
| 59 |
+
GLIMPSE is designed to **streamline the review synthesis process**, offering an effective and reliable method for extracting meaningful insights from complex review datasets.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
For more information and to begin using GLIMPSE, please proceed with the interface.
|
| 64 |
+
You can choose between the **Interactive** mode for real-time summarization or the **Pre-processed** mode for batch processing of review data.
|
| 65 |
+
"""
|
| 66 |
|
| 67 |
EXAMPLES = [
|
| 68 |
"The paper gives really interesting insights on the topic of transfer learning. It is well presented and the experiment are extensive. I believe the authors missed Jane and al 2021. In addition, I think, there is a mistake in the math.",
|
| 69 |
"The paper gives really interesting insights on the topic of transfer learning. It is well presented and the experiment are extensive. Some parts remain really unclear and I would like to see a more detailed explanation of the proposed method.",
|
| 70 |
"The paper gives really interesting insights on the topic of transfer learning. It is not well presented and lack experiments. Some parts remain really unclear and I would like to see a more detailed explanation of the proposed method.",
|
| 71 |
]
|
| 72 |
+
|
| 73 |
+
def amplify(score, power=0.5, scale=1.0):
|
| 74 |
+
return min(1.0, scale * (score ** power))
|
| 75 |
|
| 76 |
+
# Function to summarize the input texts using the RSAReranking model in interactive mode
|
| 77 |
+
def summarize(text1, text2, text3, focus, mode, rationality=1.0, iterations=1):
|
|
|
|
| 78 |
|
| 79 |
print(focus, mode, rationality, iterations)
|
| 80 |
|
|
|
|
| 90 |
text3_sentences = [sentence for sentence in text3_sentences if sentence != ""]
|
| 91 |
|
| 92 |
sentences = list(set(text1_sentences + text2_sentences + text3_sentences))
|
| 93 |
+
|
| 94 |
+
# Load polarity model and tokenizer (SciBERT)
|
| 95 |
+
polarity_model_path = "scibert/scibert_polarity/final_model"
|
| 96 |
+
polarity_tokenizer = AutoTokenizer.from_pretrained(polarity_model_path)
|
| 97 |
+
polarity_model = AutoModelForSequenceClassification.from_pretrained(polarity_model_path)
|
| 98 |
+
polarity_model.eval()
|
| 99 |
+
polarity_device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 100 |
+
polarity_model.to(polarity_device)
|
| 101 |
+
|
| 102 |
+
def predict_polarity(sent_list):
|
| 103 |
+
inputs = polarity_tokenizer(
|
| 104 |
+
sent_list, return_tensors="pt", padding=True, truncation=True, max_length=512
|
| 105 |
+
).to(polarity_device)
|
| 106 |
+
with torch.no_grad():
|
| 107 |
+
logits = polarity_model(**inputs).logits
|
| 108 |
+
preds = torch.argmax(logits, dim=1).cpu().tolist()
|
| 109 |
+
emoji_map = {0: "β", 1: None, 2: "β"}
|
| 110 |
+
return dict(zip(sent_list, [emoji_map[p] for p in preds]))
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
# Run polarity prediction
|
| 114 |
+
polarity_map = predict_polarity(sentences)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
# Load topic model and tokenizer (SciBERT)
|
| 118 |
+
topic_model_path = "scibert/scibert_topic/final_model"
|
| 119 |
+
topic_tokenizer = AutoTokenizer.from_pretrained(topic_model_path)
|
| 120 |
+
topic_model = AutoModelForSequenceClassification.from_pretrained(topic_model_path)
|
| 121 |
+
topic_model.eval()
|
| 122 |
+
topic_device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 123 |
+
topic_model.to(topic_device)
|
| 124 |
+
|
| 125 |
+
def predict_topic(sent_list):
|
| 126 |
+
inputs = topic_tokenizer(
|
| 127 |
+
sent_list, return_tensors="pt", padding=True, truncation=True, max_length=512
|
| 128 |
+
).to(topic_device)
|
| 129 |
+
with torch.no_grad():
|
| 130 |
+
logits = topic_model(**inputs).logits
|
| 131 |
+
preds = torch.argmax(logits, dim=1).cpu().tolist()
|
| 132 |
+
|
| 133 |
+
# Topic ID to label and emoji
|
| 134 |
+
id2label = {
|
| 135 |
+
0: "Substance",
|
| 136 |
+
1: "Clarity",
|
| 137 |
+
2: "Correctness",
|
| 138 |
+
3: "Originality",
|
| 139 |
+
4: "Impact",
|
| 140 |
+
5: "Comparison",
|
| 141 |
+
6: "Replicability",
|
| 142 |
+
7: None # This is used for sentences that do not match any specific topic,
|
| 143 |
+
}
|
| 144 |
+
return dict(zip(sent_list, [id2label[p] for p in preds]))
|
| 145 |
+
|
| 146 |
+
# Run topic prediction
|
| 147 |
+
topic_map = predict_topic(sentences)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
|
| 151 |
rsa_reranker = RSAReranking(
|
| 152 |
model,
|
|
|
|
| 186 |
|
| 187 |
# normalize consensuality scores between -1 and 1
|
| 188 |
consensuality_scores = (consensuality_scores - (consensuality_scores.max() - consensuality_scores.min()) / 2) / (consensuality_scores.max() - consensuality_scores.min()) / 2
|
|
|
|
| 189 |
|
| 190 |
# get most and least consensual sentences
|
| 191 |
# most consensual --> most common; least consensual --> most unique
|
|
|
|
| 204 |
text_2_consensuality = [(sentence, text_2_consensuality[sentence]) for sentence in text2_sentences]
|
| 205 |
text_3_consensuality = [(sentence, text_3_consensuality[sentence]) for sentence in text3_sentences]
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
+
def highlight_reviews(text_sentences, consensuality_scores, threshold_common=0.0, threshold_unique=0.0):
|
| 209 |
+
highlighted = []
|
| 210 |
+
for sentence in text_sentences:
|
| 211 |
+
print(f"Processing sentence: {sentence}", "score:", consensuality_scores.loc[sentence])
|
| 212 |
+
score = consensuality_scores.loc[sentence]
|
| 213 |
+
score = score*2 if score > 0 else score # amplify unique scores for better visibility
|
| 214 |
+
|
| 215 |
+
# common sentences --> positive consensuality scores
|
| 216 |
+
# unique sentences --> negative consensuality scores
|
| 217 |
+
|
| 218 |
+
score *= -1 # invert the score for highlighting
|
| 219 |
+
|
| 220 |
+
highlighted.append((sentence, score))
|
| 221 |
+
return highlighted
|
| 222 |
|
| 223 |
+
# Apply highlighting to each review
|
| 224 |
+
text_1_agreement = highlight_reviews(text1_sentences, consensuality_scores)
|
| 225 |
+
text_2_agreement = highlight_reviews(text2_sentences, consensuality_scores)
|
| 226 |
+
text_3_agreement = highlight_reviews(text3_sentences, consensuality_scores)
|
| 227 |
+
|
| 228 |
+
# Add polarity outputs
|
| 229 |
+
text_1_polarity = [(s, polarity_map[s]) for s in text1_sentences]
|
| 230 |
+
text_2_polarity = [(s, polarity_map[s]) for s in text2_sentences]
|
| 231 |
+
text_3_polarity = [(s, polarity_map[s]) for s in text3_sentences]
|
| 232 |
+
|
| 233 |
+
# Add topic outputs
|
| 234 |
+
text_1_topic = [(s, topic_map[s]) for s in text1_sentences]
|
| 235 |
+
text_2_topic = [(s, topic_map[s]) for s in text2_sentences]
|
| 236 |
+
text_3_topic = [(s, topic_map[s]) for s in text3_sentences]
|
| 237 |
|
| 238 |
print(type(text_1_consensuality))
|
| 239 |
+
return (
|
| 240 |
+
# text_1_summaries, text_2_summaries, text_3_summaries,
|
| 241 |
+
# text_1_consensuality, text_2_consensuality, text_3_consensuality,
|
| 242 |
+
text_1_agreement, text_2_agreement, text_3_agreement,
|
| 243 |
+
most_consensual, least_consensual,
|
| 244 |
+
text_1_polarity, text_2_polarity, text_3_polarity,
|
| 245 |
+
text_1_topic, text_2_topic, text_3_topic,
|
| 246 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
|
|
|
|
| 248 |
|
|
|
|
|
|
|
|
|
|
| 249 |
|
| 250 |
|
| 251 |
+
with gr.Blocks(title="GlimpSys") as demo:
|
| 252 |
gr.Markdown("# GlimpSys Interface")
|
| 253 |
|
| 254 |
with gr.Tab("Introduction"):
|
|
|
|
| 275 |
state = gr.State(initial_state)
|
| 276 |
|
| 277 |
def update_review_display(state, score_type):
|
| 278 |
+
|
| 279 |
+
# Debugging statement to check the score_type
|
| 280 |
+
# print(f"Score type: {score_type}")
|
| 281 |
+
|
| 282 |
# First clear all components
|
| 283 |
clear_updates = [gr.update(value=[]) for _ in range(8)]
|
| 284 |
+
|
| 285 |
review_ids = state["review_ids"]
|
| 286 |
current_index = state["current_review_index"]
|
| 287 |
current_review = state["scored_reviews_for_year"][review_ids[current_index]]
|
| 288 |
|
| 289 |
show_polarity = score_type == "Polarity"
|
| 290 |
+
show_consensuality = score_type == "Agreement"
|
| 291 |
+
show_topic = score_type == "Topic"
|
| 292 |
+
|
| 293 |
if show_polarity:
|
| 294 |
color_map = {"β": "#d4fcd6", "β": "#fcd6d6"}
|
| 295 |
elif show_topic:
|
|
|
|
| 299 |
else:
|
| 300 |
color_map = {}
|
| 301 |
|
|
|
|
| 302 |
new_review_id = (
|
| 303 |
f"### Submission Link:\n\n{review_ids[current_index]}<br>"
|
| 304 |
f"(Showing {current_index + 1} of {len(state['review_ids'])} reviews)"
|
|
|
|
| 327 |
highlighted = []
|
| 328 |
for sentence, metadata in review_item:
|
| 329 |
score = metadata.get("consensuality", 0.0)
|
| 330 |
+
|
| 331 |
+
# score *= 1.5 # Amplify unique scores for better visibility
|
| 332 |
+
|
| 333 |
consensuality_dict[sentence] = score
|
| 334 |
highlighted.append((sentence, score))
|
| 335 |
elif show_topic:
|
|
|
|
| 351 |
visible=True,
|
| 352 |
value=highlighted,
|
| 353 |
color_map=color_map or {},
|
| 354 |
+
show_legend=True if show_consensuality else False,
|
| 355 |
)
|
| 356 |
)
|
| 357 |
else:
|
|
|
|
| 375 |
most_common_visibility = gr.update(visible=True, value=most_common_text)
|
| 376 |
most_unique_visibility = gr.update(visible=True, value=most_unique_text)
|
| 377 |
else:
|
| 378 |
+
# Debugging statements to check visibility settings
|
| 379 |
+
# print("Hiding most common and unique sentences")
|
| 380 |
+
|
| 381 |
most_common_visibility = gr.update(visible=False, value="")
|
| 382 |
most_unique_visibility = gr.update(visible=False, value="")
|
| 383 |
|
| 384 |
return (
|
| 385 |
+
new_review_id,
|
| 386 |
+
*review_updates,
|
| 387 |
+
most_common_visibility,
|
| 388 |
+
most_unique_visibility,
|
| 389 |
+
state
|
| 390 |
+
)
|
| 391 |
|
| 392 |
|
| 393 |
|
| 394 |
# Precompute the initial outputs so something is shown on load.
|
| 395 |
+
init_display = update_review_display(initial_state, score_type="Original")
|
| 396 |
# init_display returns: (review_id, review1, review2, review3, review4, review5, review6, review7, review8, state)
|
| 397 |
|
| 398 |
with gr.Row():
|
|
|
|
| 400 |
# Input controls.
|
| 401 |
year = gr.Dropdown(choices=years, label="Select Year", interactive=True, value=initial_year)
|
| 402 |
score_type = gr.Radio(
|
| 403 |
+
choices=["Original", "Agreement", "Polarity", "Topic"],
|
| 404 |
label="Score Type to Display",
|
| 405 |
value="Original",
|
| 406 |
interactive=True
|
|
|
|
| 413 |
next_button = gr.Button("Next", variant="primary", interactive=True)
|
| 414 |
|
| 415 |
# Output display.
|
| 416 |
+
with gr.Row():
|
| 417 |
+
most_common_sentences = gr.Textbox(
|
| 418 |
+
lines=8,
|
| 419 |
label="Most Common Sentences",
|
| 420 |
visible=False,
|
| 421 |
+
value=[]
|
| 422 |
)
|
| 423 |
+
most_unique_sentences = gr.Textbox(
|
| 424 |
+
lines=8,
|
| 425 |
label="Most Unique Sentences",
|
| 426 |
visible=False,
|
| 427 |
+
value=[]
|
| 428 |
)
|
| 429 |
|
| 430 |
review1 = gr.HighlightedText(
|
|
|
|
| 523 |
# -----------------------------------
|
| 524 |
# Interactive Tab
|
| 525 |
# -----------------------------------
|
| 526 |
+
with gr.Tab("Interactive", interactive=True):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 527 |
with gr.Row():
|
| 528 |
with gr.Column():
|
| 529 |
|
|
|
|
| 531 |
|
| 532 |
# review_count = gr.Slider(minimum=1, maximum=3, step=1, value=3, label="Number of Reviews", interactive=True)
|
| 533 |
|
| 534 |
+
review1_textbox = gr.Textbox(lines=5, value=EXAMPLES[0], label="Review 1", interactive=True)
|
| 535 |
+
review2_textbox = gr.Textbox(lines=5, value=EXAMPLES[1], label="Review 2", interactive=True)
|
| 536 |
+
review3_textbox = gr.Textbox(lines=5, value=EXAMPLES[2], label="Review 3", interactive=True)
|
| 537 |
|
| 538 |
with gr.Row():
|
| 539 |
submit_button = gr.Button("Process", variant="primary", interactive=True)
|
|
|
|
| 550 |
choices=[("In-line Highlighting", "highlight"), ("Generate Summaries", "summary")],
|
| 551 |
value="highlight",
|
| 552 |
label="Output Mode:",
|
| 553 |
+
interactive=False,
|
| 554 |
+
visible=False # Initially hidden, will be shown based on mode selection
|
| 555 |
)
|
| 556 |
focus_radio = gr.Radio(
|
| 557 |
+
choices=[("Agreement", "unique"), "Polarity", "Topic",],
|
| 558 |
value="unique",
|
| 559 |
label="Focus on:",
|
| 560 |
interactive=True
|
|
|
|
| 569 |
|
| 570 |
# Fixed rationality (3.0) and iterations (2) to be consistent with the compute_rsa.py script
|
| 571 |
#iterations_slider = gr.Slider(minimum=1, maximum=10, step=1, value=2, label="Iterations", interactive=False, visible=False)
|
| 572 |
+
# rationality_slider = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=2.0, label="Rationality", interactive=False, visible=False)
|
|
|
|
| 573 |
|
| 574 |
+
with gr.Row():
|
| 575 |
+
unique_sentences = gr.Textbox(
|
| 576 |
+
lines=6, label="Most unique sentences", visible=True, value=None, container=True
|
| 577 |
+
)
|
| 578 |
+
common_sentences = gr.Textbox(
|
| 579 |
+
lines=6, label="Most common sentences", visible=True, value=None, container=True
|
| 580 |
+
)
|
| 581 |
+
|
| 582 |
uniqueness_score_text1 = gr.HighlightedText(
|
| 583 |
+
show_legend=True, label="Agreement in Input 1", visible=True, value=None,
|
| 584 |
)
|
| 585 |
uniqueness_score_text2 = gr.HighlightedText(
|
| 586 |
+
show_legend=True, label="Agreement in Input 2", visible=True, value=None,
|
| 587 |
)
|
| 588 |
uniqueness_score_text3 = gr.HighlightedText(
|
| 589 |
+
show_legend=True, label="Agreement in Input 3", visible=True, value=None,
|
| 590 |
)
|
| 591 |
+
|
| 592 |
+
|
| 593 |
+
polarity_score_text1 = gr.HighlightedText(
|
| 594 |
+
show_legend=True, label="Polarity in Input 1", visible=False, value=None,
|
| 595 |
+
color_map={"β": "#d4fcd6", "β": "#fcd6d6" }
|
| 596 |
)
|
| 597 |
+
polarity_score_text2 = gr.HighlightedText(
|
| 598 |
+
show_legend=True, label="Polarity in Input 2", visible=False, value=None,
|
| 599 |
+
color_map={"β": "#d4fcd6", "β": "#fcd6d6" }
|
| 600 |
)
|
| 601 |
+
polarity_score_text3 = gr.HighlightedText(
|
| 602 |
+
show_legend=True, label="Polarity in Input 3", visible=False, value=None,
|
| 603 |
+
color_map={"β": "#d4fcd6", "β": "#fcd6d6" }
|
| 604 |
)
|
| 605 |
+
|
| 606 |
+
aspect_score_text1 = gr.HighlightedText(
|
| 607 |
+
show_legend=False, label="Topic in Input 1", visible=False, value=None,
|
| 608 |
+
)
|
| 609 |
+
aspect_score_text2 = gr.HighlightedText(
|
| 610 |
+
show_legend=False, label="Topic in Input 2", visible=False, value=None,
|
| 611 |
+
)
|
| 612 |
+
aspect_score_text3 = gr.HighlightedText(
|
| 613 |
+
show_legend=False, label="Topic in Input 3", visible=False, value=None,
|
| 614 |
+
)
|
| 615 |
+
|
| 616 |
+
|
| 617 |
|
| 618 |
|
| 619 |
# Connect summarize function to submit button
|
|
|
|
| 621 |
fn=summarize,
|
| 622 |
inputs=[
|
| 623 |
review1_textbox, review2_textbox, review3_textbox,
|
| 624 |
+
focus_radio, mode_radio
|
| 625 |
],
|
| 626 |
outputs=[
|
| 627 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 628 |
+
common_sentences, unique_sentences,
|
| 629 |
+
polarity_score_text1, polarity_score_text2, polarity_score_text3,
|
| 630 |
+
aspect_score_text1, aspect_score_text2, aspect_score_text3
|
| 631 |
+
|
| 632 |
]
|
| 633 |
)
|
| 634 |
|
|
|
|
| 639 |
outputs=[
|
| 640 |
review1_textbox, review2_textbox, review3_textbox,
|
| 641 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 642 |
+
common_sentences, unique_sentences
|
|
|
|
| 643 |
]
|
| 644 |
)
|
| 645 |
|
| 646 |
# Update visibility of generation_method_radio based on mode_radio value
|
| 647 |
+
# def toggle_generation_method(mode):
|
| 648 |
+
# if mode == "summary":
|
| 649 |
+
# return gr.update(visible=True), gr.update(visible=False) # show generation method radio, hide focus radio
|
| 650 |
+
# else:
|
| 651 |
+
# return gr.update(visible=False), gr.update(visible=True) # show focus radio, hide generation method radio
|
| 652 |
|
| 653 |
+
# mode_radio.change(
|
| 654 |
+
# fn=toggle_generation_method,
|
| 655 |
+
# inputs=mode_radio,
|
| 656 |
+
# outputs=[generation_method_radio, focus_radio]
|
| 657 |
+
# )
|
| 658 |
|
| 659 |
# Update visibility of output textboxes based on mode_radio and focus_radio values
|
| 660 |
def toggle_output_textboxes(mode, focus):
|
| 661 |
if mode == "highlight" and focus == "unique":
|
| 662 |
return (
|
| 663 |
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), # in-line uniqueness highlights
|
| 664 |
+
gr.update(visible=True), gr.update(visible=True), # summary highlights
|
| 665 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # polarity highlights
|
| 666 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # aspect highlights
|
| 667 |
)
|
| 668 |
+
|
| 669 |
+
elif focus == "Polarity":
|
| 670 |
return (
|
| 671 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # in-line uniqueness highlights
|
| 672 |
+
gr.update(visible=False), gr.update(visible=False), # summary highlights
|
| 673 |
+
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), # polarity highlights
|
| 674 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) # aspect highlights
|
| 675 |
)
|
| 676 |
+
|
| 677 |
+
elif focus == "Topic":
|
| 678 |
return (
|
| 679 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # in-line uniqueness highlights
|
| 680 |
+
gr.update(visible=False), gr.update(visible=False), # summary highlights
|
| 681 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), # polarity highlights
|
| 682 |
+
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True) # aspect highlights
|
| 683 |
)
|
| 684 |
|
| 685 |
focus_radio.change(
|
|
|
|
| 687 |
inputs=[mode_radio, focus_radio],
|
| 688 |
outputs=[
|
| 689 |
uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 690 |
+
common_sentences, unique_sentences,
|
| 691 |
+
polarity_score_text1, polarity_score_text2, polarity_score_text3,
|
| 692 |
+
aspect_score_text1, aspect_score_text2, aspect_score_text3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 693 |
]
|
| 694 |
)
|
| 695 |
+
# mode_radio.change(
|
| 696 |
+
# fn=toggle_output_textboxes,
|
| 697 |
+
# inputs=[mode_radio, focus_radio],
|
| 698 |
+
# outputs=[
|
| 699 |
+
# uniqueness_score_text1, uniqueness_score_text2, uniqueness_score_text3,
|
| 700 |
+
# consensuality_score_text1, consensuality_score_text2, consensuality_score_text3,
|
| 701 |
+
# most_consensual_sentences, most_unique_sentences
|
| 702 |
+
# ]
|
| 703 |
+
# )
|
| 704 |
|
| 705 |
# TODO: Configure the slider for the number of review boxes
|
| 706 |
|