Ryan Kim commited on
Commit
835f5ec
1 Parent(s): 9d72e91

moved code from test.py to main.py

Browse files
Files changed (1) hide show
  1. src/main.py +265 -93
src/main.py CHANGED
@@ -1,105 +1,277 @@
1
- import streamlit as st
2
- from transformers import pipeline
3
- from transformers import AutoTokenizer, AutoModelForSequenceClassification
4
-
5
  import os
 
 
 
 
 
 
6
 
7
  # We'll be using Torch this time around
8
  import torch
9
  import torch.nn.functional as F
10
 
11
- model_names = {
12
- "emotion":[
13
- "cardiffnlp/twitter-roberta-base-sentiment",
14
- "finiteautomata/beto-sentiment-analysis",
15
- "bhadresh-savani/distilbert-base-uncased-emotion",
16
- "siebert/sentiment-roberta-large-english"
17
- ],
18
- "uspto":{
19
- "base":"distilbert-base-uncased",
20
- "abstracts":"./models/upsto_abstracts",
21
- "claims":"./models/upsto_claims"
22
- }
23
- }
24
-
25
- def label_dictionary(model_name):
26
- if model_name == "cardiffnlp/twitter-roberta-base-sentiment":
27
- def twitter_roberta(label):
28
- if label == "LABEL_0":
29
- return "Negative"
30
- elif label == "LABEL_2":
31
- return "Positive"
32
- else:
33
- return "Neutral"
34
- return twitter_roberta
35
- return lambda x: x
36
-
37
- @st.cache(allow_output_mutation=True)
38
- def load_model(model_name):
39
- model = AutoModelForSequenceClassification.from_pretrained(model_name)
40
- tokenizer = AutoTokenizer.from_pretrained(model_name)
41
- classifier = pipeline(task="sentiment-analysis", model=model, tokenizer=tokenizer)
42
- parser = label_dictionary(model_name)
43
- return model, tokenizer, classifier, parser
44
-
45
- # We first initialize a state. The state will include the following:
46
- # 1) the name of the model (default: cardiffnlp/twitter-roberta-base-sentiment)
47
- # 2) the model itself, and
48
- # 3) the parser for the outputs, in case we actually need to parse the output to something more sensible
49
- if "model" not in st.session_state:
50
- st.session_state.model_name = "cardiffnlp/twitter-roberta-base-sentiment"
51
- model, tokenizer, classifier, label_parser = load_model("cardiffnlp/twitter-roberta-base-sentiment")
52
- st.session_state.model = model
53
- st.session_state.tokenizer = tokenizer
54
- st.session_state.classifier = classifier
55
- st.session_state.label_parser = label_parser
56
- st.session_state.panel = "emotion"
57
-
58
- def model_change():
59
- model, tokenizer, classifier, label_parser = load_model(st.session_state.model_name)
60
- st.session_state.model = model
61
- st.session_state.tokenizer = tokenizer
62
- st.session_state.classifier = classifier
63
- st.session_state.label_parser = label_parser
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  # Title
66
- st.title("CSGY-6613 Sentiment Analysis")
67
  # Subtitle
68
- st.markdown("### Ryan Kim (rk2546)")
69
- st.markdown("")
70
-
71
- model_option = st.selectbox(
72
- "What sentiment analysis model do you want to use?",
73
- (
74
- "cardiffnlp/twitter-roberta-base-sentiment",
75
- "finiteautomata/beto-sentiment-analysis",
76
- "bhadresh-savani/distilbert-base-uncased-emotion",
77
- "siebert/sentiment-roberta-large-english"
78
- ),
79
- on_change=model_change,
80
- key="model_name"
81
- )
82
- placeholder="@AmericanAir just landed - 3hours Late Flight - and now we need to wait TWENTY MORE MINUTES for a gate! I have patience but none for incompetence."
83
- form = st.form(key='sentiment-analysis-form')
84
- text_input = form.text_area("Enter some text for sentiment analysis! If you just want to test it out without entering anything, just press the \"Submit\" button and the model will look at the placeholder.", placeholder=placeholder)
85
- submit = form.form_submit_button('Submit')
86
-
87
- if submit:
88
- if text_input is None or len(text_input.strip()) == 0:
89
- to_eval = placeholder
 
 
 
 
90
  else:
91
- to_eval = text_input.strip()
92
- st.write("You entered:")
93
- st.markdown("> {}".format(to_eval))
94
- st.write("Using the NLP model:")
95
- st.markdown("> {}".format(st.session_state.model_name))
96
- result = st.session_state.classifier(to_eval)
97
- label = result[0]['label']
98
- score = result[0]['score']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- label = st.session_state.label_parser(label)
 
101
 
102
- st.markdown("#### Result:")
103
- st.markdown("**{}**: {}".format(label,score))
104
- st.write("")
105
- st.write("")
 
 
 
 
 
1
  import os
2
+ import json
3
+ import random
4
+
5
+ import streamlit as st
6
+ from transformers import TextClassificationPipeline, pipeline
7
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, DistilBertTokenizerFast, DistilBertForSequenceClassification
8
 
9
  # We'll be using Torch this time around
10
  import torch
11
  import torch.nn.functional as F
12
 
13
+ emotion_model_names = (
14
+ "cardiffnlp/twitter-roberta-base-sentiment",
15
+ "finiteautomata/beto-sentiment-analysis",
16
+ "bhadresh-savani/distilbert-base-uncased-emotion",
17
+ "siebert/sentiment-roberta-large-english"
18
+ )
19
+
20
+ class ModelImplementation(object):
21
+ def __init__(
22
+ self,
23
+ transformer_model_name,
24
+ model_transformer,
25
+ tokenizer_model_name,
26
+ tokenizer_func,
27
+ pipeline_func,
28
+ parser_func,
29
+ classifier_args={},
30
+ placeholders=[""]
31
+ ):
32
+ self.transformer_model_name = transformer_model_name
33
+ self.tokenizer_model_name = tokenizer_model_name
34
+ self.placeholders = placeholders
35
+
36
+ self.model = model_transformer.from_pretrained(self.transformer_model_name)
37
+ self.tokenizer = tokenizer_func.from_pretrained(self.tokenizer_model_name)
38
+ self.classifier = pipeline_func(model=self.model, tokenizer=self.tokenizer, padding=True, truncation=True, **classifier_args)
39
+ self.parser = parser_func
40
+
41
+ self.history = []
42
+
43
+ def predict(self, val):
44
+ result = self.classifier(val)
45
+ return self.parser(self, result)
46
+
47
+ def ParseEmotionOutput(self, result):
48
+ label = result[0]['label']
49
+ score = result[0]['score']
50
+ if self.transformer_model_name == "cardiffnlp/twitter-roberta-base-sentiment":
51
+ if label == "LABEL_0":
52
+ label = "Negative"
53
+ elif label == "LABEL_2":
54
+ label = "Positive"
55
+ else:
56
+ label = "Neutral"
57
+ return label, score
58
+
59
+ def ParsePatentOutput(self, result):
60
+ return result
61
+
62
+ def emotion_model_change():
63
+ st.session_state.emotion_model = ModelImplementation(
64
+ st.session_state.emotion_model_name,
65
+ AutoModelForSequenceClassification,
66
+ st.session_state.emotion_model_name,
67
+ AutoTokenizer,
68
+ pipeline,
69
+ ParseEmotionOutput,
70
+ classifier_args={ "task" : "sentiment-analysis" },
71
+ placeholders=["@AmericanAir just landed - 3hours Late Flight - and now we need to wait TWENTY MORE MINUTES for a gate! I have patience but none for incompetence."]
72
+ )
73
+
74
+ if "page" not in st.session_state:
75
+ st.session_state.page = "home"
76
+
77
+ if "emotion_model_name" not in st.session_state:
78
+ st.session_state.emotion_model_name = "cardiffnlp/twitter-roberta-base-sentiment"
79
+ emotion_model_change()
80
+
81
+ if "patent_data" not in st.session_state:
82
+ f = open('./data/val.json')
83
+ valData = json.load(f)
84
+ f.close()
85
+
86
+ patent_data = {}
87
+ for num, label, abstract, claim in zip(valData["patent_numbers"],valData["labels"], valData["abstracts"], valData["claims"]):
88
+ patent_data[num] = {"patent_number":num,"label":label,"abstract":abstract,"claim":claim}
89
+
90
+ st.session_state.patent_data = patent_data
91
+ st.session_state.patent_num = list(patent_data.keys())[0]
92
+ st.session_state.weight = 0.5
93
+ st.session_state.patent_abstract_model = ModelImplementation(
94
+ './models/uspto_abstracts',
95
+ DistilBertForSequenceClassification,
96
+ 'distilbert-base-uncased',
97
+ DistilBertTokenizerFast,
98
+ TextClassificationPipeline,
99
+ ParsePatentOutput,
100
+ classifier_args={"return_all_scores":True},
101
+ )
102
+ print("Patent abstracts model initialized")
103
+ st.session_state.patent_claim_model = ModelImplementation(
104
+ './models/uspto_claims',
105
+ DistilBertForSequenceClassification,
106
+ 'distilbert-base-uncased',
107
+ DistilBertTokenizerFast,
108
+ TextClassificationPipeline,
109
+ ParsePatentOutput,
110
+ classifier_args={"return_all_scores":True},
111
+ )
112
+ print("Patent claims model initialized")
113
 
114
  # Title
115
+ st.title("CSGY-6613 Project")
116
  # Subtitle
117
+ st.markdown("_**Ryan Kim (rk2546)**_")
118
+ st.markdown("---")
119
+
120
+ def PageToHome():
121
+ st.session_state.page = "home"
122
+ def PageToEmotion():
123
+ st.session_state.page = "emotion"
124
+ def PageToPatent():
125
+ st.session_state.page = "patent"
126
+
127
+ with st.sidebar:
128
+ st.subheader("Toolbox")
129
+ home_selected = st.button("Home", on_click=PageToHome)
130
+ emotion_selected = st.button(
131
+ "Emotion Analysis [Milestone #2]",
132
+ on_click=PageToEmotion
133
+ )
134
+ patent_selected = st.button(
135
+ "Patent Prediction [Milestone #3]",
136
+ on_click=PageToPatent
137
+ )
138
+
139
+ if st.session_state.page == "emotion":
140
+ st.subheader("Sentiment Analysis")
141
+ if "emotion_model" not in st.session_state:
142
+ st.write("Loading model...")
143
  else:
144
+ model_option = st.selectbox(
145
+ "What sentiment analysis model do you want to use? NOTE: Lag may occur when loading a new model!",
146
+ emotion_model_names,
147
+ on_change=emotion_model_change,
148
+ key="emotion_model_name"
149
+ )
150
+ form = st.form(key='sentiment-analysis-form')
151
+ text_input = form.text_area(
152
+ "Enter some text for sentiment analysis! If you just want to test it out without entering anything, just press the \"Submit\" button and the model will look at the placeholder.",
153
+ placeholder=st.session_state.emotion_model.placeholders[0]
154
+ )
155
+ submit = form.form_submit_button('Submit')
156
+ if submit:
157
+ if text_input is None or len(text_input.strip()) == 0:
158
+ to_eval = st.session_state.emotion_model.placeholders[0]
159
+ else:
160
+ to_eval = text_input.strip()
161
+ st.write("You entered:")
162
+ st.markdown("> {}".format(to_eval))
163
+ st.write("Using the NLP model:")
164
+ st.markdown("> {}".format(st.session_state.emotion_model_name))
165
+ label, score = st.session_state.emotion_model.predict(to_eval)
166
+ st.markdown("#### Result:")
167
+ st.markdown("**{}**: {}".format(label,score))
168
+
169
+ elif st.session_state.page == "patent":
170
+ st.subheader("USPTO Patent Evaluation")
171
+ st.markdown("Below are two inputs - one for an **ABSTRACT** and another for a list of **CLAIMS**. Enter both and select the \"Submit\" button to evaluate the patenteability of your idea.")
172
+
173
+ patent_select_list = list(st.session_state.patent_data.keys())
174
+ patent_index_option = st.selectbox(
175
+ "Want to pre-populate with an existing patent? Select the index number of below.",
176
+ patent_select_list,
177
+ key="patent_num",
178
+ )
179
+
180
+ print(patent_index_option)
181
+
182
+ if "patent_abstract_model" not in st.session_state or "patent_claim_model" not in st.session_state:
183
+ st.write("Loading models...")
184
+ else:
185
+ with st.form(key='patent-form'):
186
+ col1, col2 = st.columns(2)
187
+ with col1:
188
+ abstract_input = st.text_area(
189
+ "Enter the abstract of the patent below",
190
+ placeholder=st.session_state.patent_data[st.session_state.patent_num]["abstract"],
191
+ height=400
192
+ )
193
+ with col2:
194
+ claim_input = st.text_area(
195
+ "Enter the claims of the patent below",
196
+ placeholder=st.session_state.patent_data[st.session_state.patent_num]["claim"],
197
+ height=400
198
+ )
199
+ weight_val = st.slider(
200
+ "How much do the abstract and claims weight when aggregating a total softmax score?",
201
+ min_value=-1.0,
202
+ max_value=1.0,
203
+ value=0.5,
204
+ )
205
+ submit = st.form_submit_button('Submit')
206
+
207
+ if submit:
208
+
209
+ is_custom = False
210
+ if abstract_input is None or len(abstract_input.strip()) == 0:
211
+ abstract_to_eval = st.session_state.patent_data[st.session_state.patent_num]["abstract"].strip()
212
+ else:
213
+ abstract_to_eval = abstract_input.strip()
214
+ is_custom = True
215
+
216
+ if claim_input is None or len(claim_input.strip()) == 0:
217
+ claim_to_eval = st.session_state.patent_data[st.session_state.patent_num]["claim"].strip()
218
+ else:
219
+ claim_to_eval = claim_input.strip()
220
+ is_custom = True
221
+
222
+ #tokenized_claim = st.session_state.patent_claim_model.tokenizer.encode(claim_to_eval, padding=True, truncation=True, max_length=512, add_special_tokens = True)
223
+ #untokenized_claim = st.session_state.patent_claim_model.tokenizer.decode(tokenized_claim)
224
+ #claim_to_eval2 = untokenized_claim.replace("[CLS]","")
225
+ #claim_to_eval2 = claim_to_eval2.replace("[SEP]","")
226
+ #print(claim_to_eval2)
227
+
228
+ abstract_response = st.session_state.patent_abstract_model.predict(abstract_to_eval)
229
+ claim_response = st.session_state.patent_claim_model.predict(claim_to_eval)
230
+ print(abstract_response[0])
231
+ print(claim_response[0])
232
+ print(weight_val)
233
+
234
+ claim_weight = (1+weight_val)/2
235
+ abstract_weight = 1-claim_weight
236
+ aggregate_score = [
237
+ {'label':'REJECTED','score':abstract_response[0][0]['score']*abstract_weight + claim_response[0][0]['score']*claim_weight},
238
+ {'label':'ACCEPTED','score':abstract_response[0][1]['score']*abstract_weight + claim_response[0][1]['score']*claim_weight}
239
+ ]
240
+ aggregate_score_sorted = sorted(aggregate_score, key=lambda d: d['score'], reverse=True)
241
+ print(aggregate_score_sorted)
242
+ print(f'Original Rating: {st.session_state.patent_data[st.session_state.patent_num]["label"]}')
243
+
244
+ st.markdown("---")
245
+ answerCol1, answerCol2 = st.columns(2)
246
+ with answerCol1:
247
+ st.markdown("### Abstract Ratings")
248
+ st.markdown("""
249
+ > **Reject**: {}
250
+ > **Accept**: {}
251
+ """.format(abstract_response[0][0]["score"], abstract_response[0][1]["score"]))
252
+ with answerCol2:
253
+ st.markdown("### Claims Ratings")
254
+ st.markdown("""
255
+ > **Reject**: {}
256
+ > **Accept**: {}
257
+ """.format(claim_response[0][0]["score"], claim_response[0][1]["score"]))
258
+
259
+ st.markdown(f'### Final Rating: **{aggregate_score_sorted[0]["label"]}**')
260
+ st.markdown("""
261
+ > **Reject**: {}
262
+ > **Accept**: {}
263
+ """.format(aggregate_score[0]['score'], aggregate_score[1]['score']))
264
+
265
+ #if not is_custom:
266
+ # st.markdown('**Original Score:**')
267
+ # st.markdown(st.session_state.patent_data[st.session_state.patent_num]["label"])
268
+
269
+
270
+
271
+
272
 
273
+ else:
274
+ st.write("To get started, access the sidebar on the left (click the arrow in the top-left corner of the screen) and select a tool.")
275
 
276
+ st.write("")
277
+ st.write("")