willwim commited on
Commit
6f713b7
·
verified ·
1 Parent(s): ee7258b

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +142 -0
  2. requirements.txt +11 -0
app.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import shap
3
+ import numpy as np
4
+ import scipy as sp
5
+ import torch
6
+ import tensorflow as tf
7
+ import transformers
8
+ from transformers import pipeline
9
+ from transformers import RobertaTokenizer, RobertaModel
10
+ from transformers import AutoModelForSequenceClassification
11
+ from transformers import AutoTokenizer, AutoModelForTokenClassification
12
+ import matplotlib.pyplot as plt
13
+ import sys
14
+ import csv
15
+ import os
16
+
17
+ HF_TOKEN = os.getenv("hf_token")
18
+
19
+ csv.field_size_limit(sys.maxsize)
20
+ device = "cuda:0" if torch.cuda.is_available() else "cpu"
21
+
22
+ # Load models and tokenizer
23
+ tokenizer = AutoTokenizer.from_pretrained("paragon-analytics/ADRv1", token=HF_TOKEN)
24
+ model = AutoModelForSequenceClassification.from_pretrained("paragon-analytics/ADRv1", token=HF_TOKEN).to(device)
25
+
26
+ # Build a pipeline object for predictions
27
+ pred = transformers.pipeline("text-classification", model=model, tokenizer=tokenizer, top_k=None, device=device)
28
+
29
+ # SHAP explainer
30
+ explainer = shap.Explainer(pred)
31
+
32
+ # NER pipeline
33
+ ner_tokenizer = AutoTokenizer.from_pretrained("d4data/biomedical-ner-all")
34
+ ner_model = AutoModelForTokenClassification.from_pretrained("d4data/biomedical-ner-all")
35
+ ner_pipe = pipeline("ner", model=ner_model, tokenizer=ner_tokenizer, aggregation_strategy="simple") # pass device=0 if using gpu
36
+
37
+ # def adr_predict(x):
38
+ def adr_predict(x):
39
+ # Ensure input is treated as a string
40
+ text_input = str(x).lower()
41
+
42
+ encoded_input = tokenizer(text_input, return_tensors='pt').to(device) # Move input to device
43
+ output = model(**encoded_input)
44
+
45
+ scores = torch.softmax(output.logits, dim=-1)[0].detach().cpu().numpy() # Apply softmax on logits, move to cpu and convert to numpy
46
+
47
+ try:
48
+ shap_values = explainer([text_input])
49
+
50
+ local_plot = shap.plots.text(shap_values[0], display=False)
51
+
52
+ except Exception as e:
53
+ print(f"SHAP explanation failed: {e}")
54
+ local_plot = "<p>SHAP explanation not available.</p>" # Provide a fallback
55
+
56
+ # NER processing
57
+ try:
58
+ res = ner_pipe(text_input)
59
+
60
+ entity_colors = {
61
+ 'Severity': 'red',
62
+ 'Sign_symptom': 'green',
63
+ 'Medication': 'lightblue',
64
+ 'Age': 'yellow',
65
+ 'Sex':'yellow',
66
+ 'Diagnostic_procedure':'gray',
67
+ 'Biological_structure':'silver'
68
+ }
69
+ htext = ""
70
+ prev_end = 0
71
+
72
+ res = sorted(res, key=lambda x: x['start'])
73
+
74
+ for entity in res:
75
+ start = entity['start']
76
+ end = entity['end']
77
+ word = text_input[start:end] # Extract original text segment
78
+ entity_type = entity['entity_group']
79
+ color = entity_colors.get(entity_type, 'lightgray') # Use get with a default color
80
+
81
+ # Append text before the entity
82
+ htext += f"{text_input[prev_end:start]}"
83
+ # Append the highlighted entity
84
+ htext += f"<mark style='background-color:{color};'>{word}</mark>"
85
+ prev_end = end
86
+ # Append any remaining text after the last entity
87
+ htext += text_input[prev_end:]
88
+ except Exception as e:
89
+ print(f"NER processing failed: {e}")
90
+ htext = "<p>NER processing not available.</p>" # Provide a fallback
91
+
92
+ label_output = {"Severe Reaction": float(scores[1]), "Non-severe Reaction": float(scores[0])}
93
+
94
+ return label_output, local_plot, htext
95
+
96
+ def main(prob1):
97
+ return adr_predict(prob1)
98
+
99
+ title = "Welcome to **ADR Detector** 🪐"
100
+ description1 = """This app takes text (up to a few sentences) and predicts to what extent the text describes severe (or non-severe) adverse reaction to medicaitons. Please do NOT use for medical diagnosis."""
101
+
102
+ # Use the 'with' syntax for Blocks
103
+ with gr.Blocks(title=title) as demo:
104
+ gr.Markdown(f"## {title}")
105
+ gr.Markdown(description1)
106
+ gr.Markdown("""---""")
107
+
108
+ # Define input and output components
109
+ prob1 = gr.Textbox(label="Enter Your Text Here:",lines=2, placeholder="Type it here ...")
110
+
111
+ # Output components matching the return values of the main function
112
+ label = gr.Label(label = "Predicted Label")
113
+ local_plot = gr.HTML(label = 'Shap Explanation')
114
+ htext = gr.HTML(label="Named Entity Recognition")
115
+
116
+ submit_btn = gr.Button("Analyze")
117
+
118
+ submit_btn.click(
119
+ fn=main, # The function to call
120
+ inputs=[prob1], # The input components
121
+ outputs=[label, local_plot, htext], # The output components
122
+ api_name="adr" # Keep the api_name if you intend to use the API
123
+ )
124
+
125
+ # Examples section
126
+ gr.Markdown("### Click on any of the examples below to see how it works:")
127
+ # Gradio 4.0+ Examples usage. Pass inputs and outputs components directly.
128
+ # cache_examples is recommended for faster loading of examples.
129
+ gr.Examples(
130
+ examples=[
131
+ ["A 35 year-old male had severe headache after taking Aspirin. The lab results were normal."],
132
+ ["A 35 year-old female had minor pain in upper abdomen after taking Acetaminophen."]
133
+ ],
134
+ inputs=[prob1],
135
+ outputs=[label, local_plot, htext],
136
+ fn=main, # Provide the function to run for caching examples
137
+ cache_examples=False,
138
+ run_on_click=True
139
+ )
140
+
141
+ # Launch the demo
142
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ torchvision
3
+ transformers==4.51.3
4
+ gradio==5.27.0
5
+ shap==0.47.2
6
+ tensorflow_hub
7
+ Pillow
8
+ matplotlib
9
+ spacy_streamlit
10
+ streamlit
11
+ scipy