CoolFace
Apppublic

RuinedOustrich/DebertaTextClassify

sourceHugging Faceupdated 1y agoView on Hugging Face
1likes
app.py151 linesDownload Raw Back to root
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""4@author: gleb diakonov5"""6 7import streamlit as st8import numpy as np9import torch10import torch.nn as nn11import torch.nn.functional as F12from transformers import AutoTokenizer, AutoModel, AutoConfig13from huggingface_hub import PyTorchModelHubMixin14import re15 16MAX_LEN = 25617 18target_idxs =  ['Astrophysics', 'Condensed Matter', 'Computer Science',19                    'Economics', 'Electrical Engineering and Systems Science',20                    'General Relativity and Quantum Cosmology', 'High Energy Physics - Experiment', 21                    'High Energy Physics - Lattice', 'High Energy Physics - Phenomenology', 22                    'High Energy Physics - Theory', 'Mathematics', 'Mathematical Physics', 23                    'Nonlinear Sciences', 'Nuclear Experiment', 'Nuclear Theory',24                    'Physics', 'Quantitative Biology', 'Quantitative Finance', 'Quantum Physics', 'Statistics']25 26def is_ok(text):27    if not text:28        match = True29    else:30        match = re.match("[a-z]+\d*", text)31                         32    return bool(match)33 34@st.cache_data35def define_tokenizer():36    tokenizer = AutoTokenizer.from_pretrained('./token')37    return tokenizer38 39def preprocess(text):40    41    tokenizer = define_tokenizer()42    43    encoded_text = tokenizer.encode_plus(44        text,45        max_length=MAX_LEN,46        add_special_tokens=True,47        return_token_type_ids=False,48        padding='max_length',49        truncation = True,50        return_attention_mask=True,51        return_tensors='pt',52        )53 54    input_ids = encoded_text['input_ids']55    attention_mask = encoded_text['attention_mask']56    57    return input_ids, attention_mask58 59class MeanPooling(nn.Module):60    def __init__(self):61        super(MeanPooling, self).__init__()62        63    def forward(self, last_hidden_state, attention_mask):64        input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float()65        sum_embeddings = torch.sum(last_hidden_state * input_mask_expanded, 1)66        sum_mask = input_mask_expanded.sum(1)67        sum_mask = torch.clamp(sum_mask, min=1e-9)68        mean_embeddings = sum_embeddings / sum_mask69        return mean_embeddings70 71class BERTClass(torch.nn.Module, PyTorchModelHubMixin):72    def __init__(self, num_classes = 20):73        super(BERTClass, self).__init__()74        config = AutoConfig.from_pretrained("./bert/config.json")75        self.bert_model = AutoModel.from_config(config)76        self.dropout = torch.nn.Dropout(0.3)77        self.batchnorm = nn.BatchNorm1d(768)78        self.pooler = MeanPooling()79        self.linear = torch.nn.Linear(768, num_classes)80 81    def forward(self, input_ids, attn_mask):82        output = self.bert_model(83            input_ids, 84            attention_mask=attn_mask,85        )86        output = self.pooler(output.last_hidden_state, attn_mask)87        output_dropout = self.dropout(output)88        output = self.linear(output_dropout)89        return output90 91@st.cache_data92def configure_model():93    model = BERTClass.from_pretrained("./deberta-arxiv-model")94    return model95 96def predict(text):97    98    model = configure_model()99    100    model.eval()101    102    with torch.no_grad():103    104        input_ids, attention_mask = preprocess(text)105        preds = model(input_ids, attention_mask)106        output = F.softmax(preds, dim = 1).detach()107        output = output.flatten().numpy()108        output = {tag: round(float(prob)*100, 2) for tag, prob in zip(target_idxs, output)}109        outputs = {k: v for k, v in sorted(output.items(), reverse = True, key = lambda x: x[1])}110    return outputs111 112 113if __name__ == '__main__':114    115    st.markdown("<h1 style='text-align: center;'>Find out the topic of the article</h1>", unsafe_allow_html=True)116    st.markdown("<h2 style='text-align: center;'>Please enter title or summary</h2>", unsafe_allow_html=True)117    st.markdown("<h4 style='text-align: center;'>(enter both for better result)</h4>", unsafe_allow_html=True)118    form = st.form("my_form")119    title = form.text_input("TITLE")120    summary = form.text_area("SUMMARY")121    button = form.form_submit_button("Submit")122    summary = summary.lower()123    title = title.lower()124    if button:125        if not title and not summary:126            st.write("**PLEASE ENTER SOMETHING!**")127        else:128            text = title + ". " + summary129            if not is_ok(summary) and is_ok(title):130                st.write("**INCORRECT INPUT FORMAT: SUMMARY**")131            if is_ok(summary) and not is_ok(title):132                st.write("**INCORRECT INPUT FORMAT: TITLE**")133            elif not is_ok(title) and not is_ok(summary):134                st.write("**INCORRECT INPUT FORMAT: TITLE, SUMMARY**")135            elif len(summary.split()) in (1,2,3) and not title:136                st.write("**There are too few words in summary, result can be bad. Make shure you enter full text**")137            elif len(title.split()) in (1,2,3) and not summary:138                st.write("**There are too few words in title, result can be bad. Make shure you enter full text**")139            elif len(title.split()) in (1,2,3) and len(summary.split()) == 1:140                st.write("**There are too few words in title and summary, result can be bad. Make shure you enter full text**")141            else:142                outputs = predict(text)143                sums_probs = []144                for k, v in outputs.items(): 145                    st.write(f'**:blue[{k}]** - **:green[{v}%]**')146                    sums_probs.append(v)147                    if sum(sums_probs) >= 95:148                        break149                150                151