Spaces:
Runtime error
Runtime error
Joe Davison
commited on
Commit
·
a922691
0
Parent(s):
initial (again)
Browse files- app.py +167 -0
- huggingface_logo.png +0 -0
- requirements.txt +85 -0
- style.css +4 -0
- texts.json +21 -0
app.py
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from transformers import BartForSequenceClassification, BartTokenizer
|
3 |
+
import torch
|
4 |
+
import numpy as np
|
5 |
+
import contextlib
|
6 |
+
import plotly.express as px
|
7 |
+
import pandas as pd
|
8 |
+
from PIL import Image
|
9 |
+
import datetime
|
10 |
+
|
11 |
+
with open("hit_log.txt", mode='a') as file:
|
12 |
+
file.write(str(datetime.datetime.now()) + '\n')
|
13 |
+
|
14 |
+
MODEL_DESC = {
|
15 |
+
'Bart MNLI': """Bart with a classification head trained on MNLI.\n\nSequences are posed as NLI premises and topic labels are turned into premises, i.e. `business` -> `This text is about business.`""",
|
16 |
+
'Bart MNLI + Yahoo Answers': """Bart with a classification head trained on MNLI and then further fine-tuned on Yahoo Answers topic classification.\n\nSequences are posed as NLI premises and topic labels are turned into premises, i.e. `business` -> `This text is about business.`""",
|
17 |
+
}
|
18 |
+
|
19 |
+
ZSL_DESC = """Recently, the NLP science community has begun to pay increasing attention to zero-shot and few-shot applications, such as in the [paper from OpenAI](https://arxiv.org/abs/2005.14165) introducing GPT-3. This demo shows how 🤗 Transformers can be used for zero-shot topic classification, the task of predicting a topic that the model has not been trained on."""
|
20 |
+
|
21 |
+
CODE_DESC = """```python
|
22 |
+
# pose sequence as a NLI premise and label as a hypothesis
|
23 |
+
from transformers import BartForSequenceClassification, BartTokenizer
|
24 |
+
nli_model = BartForSequenceClassification.from_pretrained('bart-large-mnli')
|
25 |
+
tokenizer = BartTokenizer.from_pretrained('bart-large-mnli')
|
26 |
+
|
27 |
+
premise = sequence
|
28 |
+
hypothesis = f'This text is about {label}.'
|
29 |
+
|
30 |
+
# run through model pre-trained on MNLI
|
31 |
+
x = tokenizer.encode(premise, hypothesis, return_tensors='pt',
|
32 |
+
max_length=tokenizer.max_len,
|
33 |
+
truncation_strategy='only_first')
|
34 |
+
logits = nli_model(x.to(device))[0]
|
35 |
+
|
36 |
+
# we throw away "neutral" (dim 1) and take the probability of
|
37 |
+
# "entailment" (2) as the probability of the label being true
|
38 |
+
entail_contradiction_logits = logits[:,[0,2]]
|
39 |
+
probs = entail_contradiction_logits.softmax(1)
|
40 |
+
prob_label_is_true = probs[:,1]
|
41 |
+
```"""
|
42 |
+
|
43 |
+
model_ids = {
|
44 |
+
'Bart MNLI': 'bart-large-mnli',
|
45 |
+
'Bart MNLI + Yahoo Answers': './bart_mnli_topics'
|
46 |
+
}
|
47 |
+
|
48 |
+
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
|
49 |
+
|
50 |
+
@st.cache(allow_output_mutation=True)
|
51 |
+
def load_models():
|
52 |
+
return {id: BartForSequenceClassification.from_pretrained(id).to(device) for id in model_ids.values()}
|
53 |
+
|
54 |
+
models = load_models()
|
55 |
+
|
56 |
+
|
57 |
+
@st.cache(allow_output_mutation=True)
|
58 |
+
def load_tokenizer(tok_id):
|
59 |
+
return BartTokenizer.from_pretrained(tok_id)
|
60 |
+
|
61 |
+
@st.cache(allow_output_mutation=True, show_spinner=False)
|
62 |
+
def classify_candidate(nli_model_id, sequence, label, do_print_code):
|
63 |
+
nli_model = models[nli_model_id]
|
64 |
+
tokenizer = load_tokenizer('bart-large')
|
65 |
+
|
66 |
+
# pose sequence as a NLI premise and label as a hypothesis
|
67 |
+
premise = sequence
|
68 |
+
hypothesis = f'This text is about {label}.'
|
69 |
+
|
70 |
+
# run through model pre-trained on MNLI
|
71 |
+
x = tokenizer.encode(premise, hypothesis, return_tensors='pt',
|
72 |
+
max_length=tokenizer.max_len,
|
73 |
+
truncation_strategy='only_first')
|
74 |
+
with torch.no_grad():
|
75 |
+
logits = nli_model(x.to(device))[0]
|
76 |
+
|
77 |
+
# we throw away "neutral" (dim 1) and take the probability of
|
78 |
+
# "entailment" (2) as the probability of the label being true
|
79 |
+
entail_contradiction_logits = logits[:,[0,2]]
|
80 |
+
probs = entail_contradiction_logits.softmax(1)
|
81 |
+
prob_label_is_true = probs[:,1]
|
82 |
+
|
83 |
+
return prob_label_is_true.cpu()
|
84 |
+
|
85 |
+
def get_most_likely(nli_model_id, sequence, labels, do_print_code):
|
86 |
+
predictions = []
|
87 |
+
for label in labels:
|
88 |
+
predictions.append(classify_candidate(nli_model_id, sequence, label, do_print_code))
|
89 |
+
do_print_code = False #only print code once per run
|
90 |
+
predictions = torch.cat(predictions)
|
91 |
+
|
92 |
+
most_likely = predictions.argsort().numpy()
|
93 |
+
top_topics = np.array(labels)[most_likely]
|
94 |
+
scores = predictions[most_likely].detach().numpy()
|
95 |
+
return top_topics, scores
|
96 |
+
|
97 |
+
@st.cache(allow_output_mutation=True)
|
98 |
+
def get_sentence_model(model_id):
|
99 |
+
return SentenceTransformer(model_id)
|
100 |
+
|
101 |
+
def load_examples():
|
102 |
+
df = pd.read_json('texts.json')
|
103 |
+
names = df.name.values.tolist()
|
104 |
+
mapping = {df['name'].iloc[i]: (df['text'].iloc[i], df['labels'].iloc[i]) for i in range(len(names))}
|
105 |
+
names.append('Custom')
|
106 |
+
mapping['Custom'] = ('', '')
|
107 |
+
return names, mapping
|
108 |
+
|
109 |
+
def plot_result(top_topics, scores):
|
110 |
+
scores *= 100
|
111 |
+
fig = px.bar(x=scores, y=top_topics, orientation='h',
|
112 |
+
labels={'x': 'Confidence', 'y': 'Label'},
|
113 |
+
text=scores,
|
114 |
+
range_x=(0,115),
|
115 |
+
title='Top Predictions',
|
116 |
+
color=np.linspace(0,1,len(scores)),
|
117 |
+
color_continuous_scale='GnBu')
|
118 |
+
fig.update(layout_coloraxis_showscale=False)
|
119 |
+
fig.update_traces(texttemplate='%{text:0.1f}%', textposition='outside')
|
120 |
+
st.plotly_chart(fig)
|
121 |
+
|
122 |
+
|
123 |
+
|
124 |
+
def main():
|
125 |
+
with open("style.css") as f:
|
126 |
+
st.markdown('<style>{}</style>'.format(f.read()), unsafe_allow_html=True)
|
127 |
+
|
128 |
+
ex_names, ex_map = load_examples()
|
129 |
+
|
130 |
+
logo = Image.open('huggingface_logo.png')
|
131 |
+
st.sidebar.image(logo, width=120)
|
132 |
+
st.sidebar.markdown(ZSL_DESC)
|
133 |
+
model_desc = st.sidebar.selectbox('Model', list(MODEL_DESC.keys()), 0)
|
134 |
+
do_print_code = st.sidebar.checkbox('Show code snippet', False)
|
135 |
+
st.sidebar.markdown('#### Model Description')
|
136 |
+
st.sidebar.markdown(MODEL_DESC[model_desc])
|
137 |
+
st.sidebar.markdown('Originally proposed by [Yin et al. (2019)](https://arxiv.org/abs/1909.00161). Read more in our [blog post](https://joeddav.github.io/blog/2020/05/29/ZSL.html).')
|
138 |
+
|
139 |
+
st.title('Zero Shot Topic Classification')
|
140 |
+
example = st.selectbox('Choose an example', ex_names)
|
141 |
+
height = min((len(ex_map[example][0].split()) + 1) * 2, 200)
|
142 |
+
sequence = st.text_area('Text', ex_map[example][0], key='sequence', height=height)
|
143 |
+
labels = st.text_input('Possible topics (comma-separated)', ex_map[example][1], max_chars=1000)
|
144 |
+
|
145 |
+
labels = list(set([x.strip() for x in labels.strip().split(',') if len(x.strip()) > 0]))
|
146 |
+
if len(labels) == 0 or len(sequence) == 0:
|
147 |
+
st.write('Enter some text and at least one possible topic to see predictions.')
|
148 |
+
return
|
149 |
+
|
150 |
+
if do_print_code:
|
151 |
+
st.markdown(CODE_DESC)
|
152 |
+
|
153 |
+
model_id = model_ids[model_desc]
|
154 |
+
|
155 |
+
with st.spinner('Classifying...'):
|
156 |
+
top_topics, scores = get_most_likely(model_id, sequence, labels, do_print_code)
|
157 |
+
|
158 |
+
plot_result(top_topics[-10:], scores[-10:])
|
159 |
+
|
160 |
+
|
161 |
+
|
162 |
+
|
163 |
+
|
164 |
+
|
165 |
+
if __name__ == '__main__':
|
166 |
+
main()
|
167 |
+
|
huggingface_logo.png
ADDED
![]() |
requirements.txt
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
altair==4.1.0
|
2 |
+
appnope==0.1.0
|
3 |
+
astor==0.8.1
|
4 |
+
attrs==19.3.0
|
5 |
+
backcall==0.1.0
|
6 |
+
base58==2.0.0
|
7 |
+
bleach==3.1.5
|
8 |
+
blinker==1.4
|
9 |
+
boto3==1.13.12
|
10 |
+
botocore==1.16.12
|
11 |
+
cachetools==4.1.0
|
12 |
+
certifi==2020.4.5.1
|
13 |
+
chardet==3.0.4
|
14 |
+
click==7.1.2
|
15 |
+
decorator==4.4.2
|
16 |
+
defusedxml==0.6.0
|
17 |
+
docutils==0.15.2
|
18 |
+
entrypoints==0.3
|
19 |
+
enum-compat==0.0.3
|
20 |
+
filelock==3.0.12
|
21 |
+
future==0.18.2
|
22 |
+
idna==2.9
|
23 |
+
importlib-metadata==1.6.0
|
24 |
+
ipykernel==5.2.1
|
25 |
+
ipython==7.14.0
|
26 |
+
ipython-genutils==0.2.0
|
27 |
+
ipywidgets==7.5.1
|
28 |
+
jedi==0.17.0
|
29 |
+
Jinja2==2.11.2
|
30 |
+
jmespath==0.10.0
|
31 |
+
joblib==0.15.1
|
32 |
+
jsonschema==3.2.0
|
33 |
+
jupyter-client==6.1.3
|
34 |
+
jupyter-core==4.6.3
|
35 |
+
MarkupSafe==1.1.1
|
36 |
+
mistune==0.8.4
|
37 |
+
nbconvert==5.6.1
|
38 |
+
nbformat==5.0.6
|
39 |
+
notebook==6.0.3
|
40 |
+
numpy==1.18.4
|
41 |
+
packaging==20.3
|
42 |
+
pandas==1.0.3
|
43 |
+
pandocfilters==1.4.2
|
44 |
+
parso==0.7.0
|
45 |
+
pathtools==0.1.2
|
46 |
+
pexpect==4.8.0
|
47 |
+
pickleshare==0.7.5
|
48 |
+
Pillow==7.1.2
|
49 |
+
prometheus-client==0.7.1
|
50 |
+
prompt-toolkit==3.0.5
|
51 |
+
protobuf==3.12.0
|
52 |
+
ptyprocess==0.6.0
|
53 |
+
pydeck==0.3.1
|
54 |
+
Pygments==2.6.1
|
55 |
+
pyparsing==2.4.7
|
56 |
+
pyrsistent==0.16.0
|
57 |
+
python-dateutil==2.8.1
|
58 |
+
pytz==2020.1
|
59 |
+
pyzmq==19.0.1
|
60 |
+
regex==2020.5.14
|
61 |
+
requests==2.23.0
|
62 |
+
s3transfer==0.3.3
|
63 |
+
sacremoses==0.0.43
|
64 |
+
Send2Trash==1.5.0
|
65 |
+
sentencepiece==0.1.90
|
66 |
+
six==1.14.0
|
67 |
+
streamlit==0.60.0
|
68 |
+
terminado==0.8.3
|
69 |
+
testpath==0.4.4
|
70 |
+
tokenizers==0.7.0
|
71 |
+
toml==0.10.1
|
72 |
+
toolz==0.10.0
|
73 |
+
torch==1.5.0
|
74 |
+
tornado==5.1.1
|
75 |
+
tqdm==4.46.0
|
76 |
+
traitlets==4.3.3
|
77 |
+
transformers==2.9.1
|
78 |
+
tzlocal==2.1
|
79 |
+
urllib3==1.25.9
|
80 |
+
validators==0.15.0
|
81 |
+
watchdog==0.10.2
|
82 |
+
wcwidth==0.1.9
|
83 |
+
webencodings==0.5.1
|
84 |
+
widgetsnbextension==3.5.1
|
85 |
+
zipp==3.1.0
|
style.css
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.fullScreenFrame > div {
|
2 |
+
display: flex;
|
3 |
+
justify-content: center;
|
4 |
+
}
|
texts.json
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": {
|
3 |
+
"0":"\"Jupyter's Biggest Moons Started as Tiny Grains of Hail\"",
|
4 |
+
"1":"Who are you voting for in 2020?",
|
5 |
+
"2":"Attention is all you need",
|
6 |
+
"3":"IMDB Avengers Review",
|
7 |
+
"4":"Bose QuietComfort"
|
8 |
+
}, "text": {
|
9 |
+
"0":"Jupiter\u2019s Biggest Moons Started as Tiny Grains of Hail\n\nA new model offers an explanation for how the Galilean satellites formed around the solar system\u2019s largest world.\n\nKonstantin Batygin did not set out to solve one of the solar system\u2019s most puzzling mysteries when he went for a run up a hill in Nice, France. Dr. Batygin, a Caltech researcher, best known for his contributions to the search for the solar system\u2019s missing \u201cPlanet Nine,\u201d spotted a beer bottle. At a steep, 20 degree grade, he wondered why it wasn\u2019t rolling down the hill.\n\nHe realized there was a breeze at his back holding the bottle in place. Then he had a thought that would only pop into the mind of a theoretical astrophysicist: \u201cOh! This is how Europa formed.\u201d\n\nEuropa is one of Jupiter\u2019s four large Galilean moons. And in a paper published Monday in the Astrophysical Journal, Dr. Batygin and a co-author, Alessandro Morbidelli, a planetary scientist at the C\u00f4te d\u2019Azur Observatory in France, present a theory explaining how some moons form around gas giants like Jupiter and Saturn, suggesting that millimeter-sized grains of hail produced during the solar system\u2019s formation became trapped around these massive worlds, taking shape one at a time into the potentially habitable moons we know today.",
|
10 |
+
"1": "Who are you voting for in 2020?",
|
11 |
+
"2": "The dominant sequence transduction models are based on complex recurrent or convolutional neural networks in an encoder-decoder configuration. The best performing models also connect the encoder and decoder through an attention mechanism. We propose a new simple network architecture, the Transformer, based solely on attention mechanisms, dispensing with recurrence and convolutions entirely. Experiments on two machine translation tasks show these models to be superior in quality while being more parallelizable and requiring significantly less time to train. Our model achieves 28.4 BLEU on the WMT 2014 English-to-German translation task, improving over the existing best results, including ensembles by over 2 BLEU. On the WMT 2014 English-to-French translation task, our model establishes a new single-model state-of-the-art BLEU score of 41.8 after training for 3.5 days on eight GPUs, a small fraction of the training costs of the best models from the literature. We show that the Transformer generalizes well to other tasks by applying it successfully to English constituency parsing both with large and limited training data.",
|
12 |
+
"3": "Are you a fan of epic adventure movies? Then this is your dream come true! Truly this is the ultimate superhero mash-up and it's executed perfectly. Props to the filmmakers for taking the time to design it to be more than just a superhero film packed with action scenes and adding depth to each character.",
|
13 |
+
"4": "What happens when you clear away the noisy distractions of the world? Concentration goes to the next level. You get deeper into your music, your work, or whatever you want to focus on. That’s the power of Bose QuietComfort 35 wireless headphones II. Put them on and get closer to what you’re most passionate about. And that’s just the beginning. QuietComfort 35 wireless headphones II are now enabled with Bose AR — an innovative, audio-only take on augmented reality. Embedded inside your headphones is a multi-directional motion sensor. One that Bose AR can utilize to provide contextual audio based on where you are. Unlock Bose AR via a firmware update through the Bose Connect app. They’re Alexa-enabled, too, so you can enjoy entertainment, get information, and manage your day — all without looking at your phone. Adjust your level of noise cancelling between three settings using the Action button or the Bose Connect app. Volume-optimized EQ gives you balanced audio performance at any volume, and a noise-rejecting dual-microphone system provides clearer calls, even in noisy environments. And with easy Bluetooth pairing, 20 hours of battery life, and a durable, comfortable fit — you can keep the music or the quiet going all day long. Included: QuietComfort 35 II, carrying case, charging cable, audio cable for enjoying music without battery power."
|
14 |
+
}, "labels": {
|
15 |
+
"0":"space & cosmos, scientific discovery, microbiology, robots, archeology",
|
16 |
+
"1":"foreign policy, Europe, elections, business, 2020, outdoor recreation, politics",
|
17 |
+
"2":"machine learning, statistics, translation, vision",
|
18 |
+
"3":"films, action, superheroes, books",
|
19 |
+
"4":"electronics, headphones, health & wellness, furniture, software, pet supplies"
|
20 |
+
}
|
21 |
+
}
|