Spaces:
Sleeping
Sleeping
Upload 9 files
Browse files- app.py +344 -0
- lstm/lstm_model.pth +3 -0
- lstm/rnn_preprocessing.py +80 -0
- lstm/vocab_to_int.json +0 -0
- lstm/word2vec.model +3 -0
- rubert/logistic_regression_model.pkl +3 -0
- tf-idf/tf-idf.pkl +3 -0
- tf-idf/tf-idf_vectorizer.pkl +3 -0
- toxic/logistic_regression_model_toxic.pkl +3 -0
app.py
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import streamlit as st
|
4 |
+
import pickle
|
5 |
+
import time
|
6 |
+
from typing import Tuple
|
7 |
+
from sklearn.feature_extraction.text import TfidfVectorizer
|
8 |
+
import transformers
|
9 |
+
import numpy as np
|
10 |
+
from sklearn.model_selection import train_test_split
|
11 |
+
from sklearn.linear_model import LogisticRegression
|
12 |
+
from sklearn.metrics import f1_score
|
13 |
+
import torch
|
14 |
+
from transformers import AutoTokenizer, AutoModel
|
15 |
+
from torch.utils.data import TensorDataset, DataLoader
|
16 |
+
from sklearn.preprocessing import LabelEncoder
|
17 |
+
import re
|
18 |
+
import string
|
19 |
+
import numpy as np
|
20 |
+
import torch.nn as nn
|
21 |
+
import json
|
22 |
+
import gensim
|
23 |
+
import torch.nn.functional as F
|
24 |
+
from transformers import GPT2LMHeadModel, GPT2Tokenizer
|
25 |
+
from transformers import AutoModelForSequenceClassification
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
st.title('10-я неделя DS. Классификация отзывов, определение токсичности и генерация текста')
|
30 |
+
|
31 |
+
st.sidebar.header('Выберите страницу')
|
32 |
+
page = st.sidebar.radio("Выберите страницу", ["Вводная информация", "Классификация отзывов", "Зоопарк моделей и F1-score", "Определение токсичности", "Генерация текста"])
|
33 |
+
|
34 |
+
if page == "Вводная информация":
|
35 |
+
|
36 |
+
st.subheader('*Задача №1*: Классификация отзывов на медицинские учреждения')
|
37 |
+
st.write('Задача в двух словах: необходимо дать классификацию отзыва тремя моделями, время, за которое происходит классификаци отзыва, а также таблицу сравнения моделей по F-1 macro для моделей')
|
38 |
+
|
39 |
+
st.subheader('*Задача №2*: Определение токсичности')
|
40 |
+
st.write('Задача в двух словах: Оценка степени токсичности пользовательского сообщения ')
|
41 |
+
|
42 |
+
st.subheader('*Задача №3*: Генерация текста')
|
43 |
+
st.write('Задача в двух словах: Генерация текста GPT-моделью по пользовательскому prompt')
|
44 |
+
|
45 |
+
st.subheader('☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️☀️')
|
46 |
+
|
47 |
+
st.subheader('Выполнила команда "BERT": Алексей А., Светлана, Алиса')
|
48 |
+
|
49 |
+
|
50 |
+
if page == "Классификация отзывов":
|
51 |
+
# Загрузка tf-idf модели и векторайзера
|
52 |
+
with open('tf-idf/tf-idf.pkl', 'rb') as f:
|
53 |
+
model_tf = pickle.load(f)
|
54 |
+
|
55 |
+
with open('tf-idf/tf-idf_vectorizer.pkl', 'rb') as f:
|
56 |
+
vectorizer_tf = pickle.load(f)
|
57 |
+
|
58 |
+
# Загрузка словаря vocab_to_int и Word2Vec модели
|
59 |
+
with open('lstm/vocab_to_int.json', 'r') as f:
|
60 |
+
vocab_to_int = json.load(f)
|
61 |
+
|
62 |
+
word2vec_model = gensim.models.Word2Vec.load("lstm/word2vec.model")
|
63 |
+
|
64 |
+
stop_words = ['и', 'в', 'во', 'не', 'что', 'он', 'на', 'я', 'с', 'со', 'как', 'а', 'то', 'все', 'она', 'так', 'его', 'но', 'да', 'ты', 'к', 'у', 'же', 'вы', 'за', 'бы', 'по', 'только', 'ее', 'мне', 'было', 'вот', 'от', 'меня', 'еще', 'нет', 'о', 'из', 'ему', 'теперь', 'когда', 'даже', 'ну', 'вдруг', 'ли', 'если', 'уже', 'или', 'ни', 'быть', 'был', 'него', 'до', 'вас', 'нибудь', 'опять', 'уж', 'вам', 'ведь', 'там', 'потом', 'себя', 'ничего', 'ей', 'может', 'они', 'тут', 'где', 'есть', 'надо', 'ней', 'для', 'мы', 'тебя', 'их', 'чем', 'была', 'сам', 'чтоб', 'без', 'будто', 'чего', 'раз', 'тоже', 'себе', 'под', 'будет', 'ж', 'тогда', 'кто', 'этот', 'того', 'потому', 'этого', 'какой', 'совсем', 'ним', 'здесь', 'этом', 'один', 'почти', 'мой', 'тем', 'чтобы', 'нее', 'сейчас', 'были', 'куда', 'зачем', 'всех', 'никогда', 'можно', 'при', 'наконец', 'два', 'об', 'другой', 'хоть', 'после', 'над', 'больше', 'тот', 'через', 'эти', 'нас', 'про', 'всего', 'них', 'какая', 'много', 'разве', 'три', 'эту', 'моя', 'впрочем', 'хорошо', 'свою', 'этой', 'перед', 'иногда', 'лучше', 'чуть', 'том', 'нельзя', 'такой', 'им', 'более', 'всегда', 'конечно', 'всю', 'между']
|
65 |
+
|
66 |
+
def data_preprocessing(text: str) -> str:
|
67 |
+
text = text.lower()
|
68 |
+
text = re.sub('<.*?>', '', text) # html tags
|
69 |
+
text = ''.join([c for c in text if c not in string.punctuation])# Remove punctuation
|
70 |
+
text = ' '.join([word for word in text.split() if word not in stop_words])
|
71 |
+
text = [word for word in text.split() if not word.isdigit()]
|
72 |
+
text = ' '.join(text)
|
73 |
+
return text
|
74 |
+
|
75 |
+
# Функция для предсказания класса отзыва
|
76 |
+
def classify_review_tf(review):
|
77 |
+
# Векторизация отзыва
|
78 |
+
review_vector = vectorizer_tf.transform([review])
|
79 |
+
# Предсказание
|
80 |
+
start_time = time.time()
|
81 |
+
prediction = model_tf.predict(review_vector)
|
82 |
+
end_time = time.time()
|
83 |
+
# Время предсказания
|
84 |
+
prediction_time = end_time - start_time
|
85 |
+
return prediction[0], prediction_time
|
86 |
+
|
87 |
+
VOCAB_SIZE = len(vocab_to_int) + 1 # add 1 for the padding token
|
88 |
+
EMBEDDING_DIM = 32
|
89 |
+
HIDDEN_SIZE = 32
|
90 |
+
SEQ_LEN = 100
|
91 |
+
|
92 |
+
class BahdanauAttention(nn.Module):
|
93 |
+
def __init__(self, hidden_size: torch.Tensor = HIDDEN_SIZE) -> None:
|
94 |
+
super().__init__()
|
95 |
+
|
96 |
+
self.W_q = nn.Linear(hidden_size, hidden_size)
|
97 |
+
self.W_k = nn.Linear(hidden_size, hidden_size)
|
98 |
+
self.V = nn.Linear(HIDDEN_SIZE, 1)
|
99 |
+
|
100 |
+
def forward(
|
101 |
+
self,
|
102 |
+
keys: torch.Tensor,
|
103 |
+
query: torch.Tensor
|
104 |
+
) -> Tuple[torch.Tensor, torch.Tensor]:
|
105 |
+
query = self.W_q(query)
|
106 |
+
keys = self.W_k(keys)
|
107 |
+
|
108 |
+
energy = self.V(torch.tanh(query.unsqueeze(1) + keys)).squeeze(-1)
|
109 |
+
weights = F.softmax(energy, -1)
|
110 |
+
context = torch.bmm(weights.unsqueeze(1), keys)
|
111 |
+
return context, weights
|
112 |
+
|
113 |
+
embedding_matrix = np.zeros((VOCAB_SIZE, EMBEDDING_DIM))
|
114 |
+
embedding_layer = torch.nn.Embedding.from_pretrained(torch.FloatTensor(embedding_matrix))
|
115 |
+
|
116 |
+
class LSTMConcatAttention(nn.Module):
|
117 |
+
def __init__(self) -> None:
|
118 |
+
super().__init__()
|
119 |
+
|
120 |
+
# self.embedding = nn.Embedding(VOCAB_SIZE, EMBEDDING_DIM)
|
121 |
+
self.embedding = embedding_layer
|
122 |
+
self.lstm = nn.LSTM(EMBEDDING_DIM, HIDDEN_SIZE, batch_first=True)
|
123 |
+
self.attn = BahdanauAttention(HIDDEN_SIZE)
|
124 |
+
self.clf = nn.Sequential(
|
125 |
+
nn.Linear(HIDDEN_SIZE, 128),
|
126 |
+
nn.Dropout(),
|
127 |
+
nn.Tanh(),
|
128 |
+
nn.Linear(128, 1)
|
129 |
+
)
|
130 |
+
|
131 |
+
def forward(self, x):
|
132 |
+
embeddings = self.embedding(x)
|
133 |
+
outputs, (h_n, _) = self.lstm(embeddings)
|
134 |
+
att_hidden, att_weights = self.attn(outputs, h_n.squeeze(0))
|
135 |
+
out = self.clf(att_hidden)
|
136 |
+
return out, att_weights
|
137 |
+
|
138 |
+
model_lstm = LSTMConcatAttention() # Инициализируйте с теми же параметрами, что использовались при обучении
|
139 |
+
model_lstm.load_state_dict(torch.load("lstm/lstm_model.pth"))
|
140 |
+
model_lstm.eval()
|
141 |
+
|
142 |
+
# Проверка и добавление токена <UNK>, если он отсутствует
|
143 |
+
if '<UNK>' not in vocab_to_int:
|
144 |
+
vocab_to_int['<UNK>'] = len(vocab_to_int) # Присвоение нового уникального индекса
|
145 |
+
|
146 |
+
# Проверка и добавление токена <PAD>, если он отсутствует
|
147 |
+
if '<PAD>' not in vocab_to_int:
|
148 |
+
vocab_to_int['<PAD>'] = len(vocab_to_int) # Присвоение нового уникального индекса
|
149 |
+
|
150 |
+
def text_to_vector(text, unknown_token_id=0):
|
151 |
+
words = text.split()
|
152 |
+
vector = [vocab_to_int.get(word, unknown_token_id) for word in words] # здесь unknown_token_id - это ID для "неизвестных" слов
|
153 |
+
return np.array(vector, dtype=np.int64) # Убедитесь, что тип данных int64
|
154 |
+
|
155 |
+
|
156 |
+
def classify_review_lstm(review: str, SEQ_LEN: int, model: nn.Module, threshold: float = 0.5):
|
157 |
+
"""Predict sentiment class for a review
|
158 |
+
|
159 |
+
Args:
|
160 |
+
review (str): Review text
|
161 |
+
SEQ_LEN (int): sequence length
|
162 |
+
model (nn.Module): trained model
|
163 |
+
threshold (float): threshold for class prediction
|
164 |
+
|
165 |
+
Returns:
|
166 |
+
str: Predicted sentiment ('positive' or 'negative')
|
167 |
+
"""
|
168 |
+
inp = text_to_vector(review)
|
169 |
+
inp_tensor = torch.tensor(inp, dtype=torch.int64)
|
170 |
+
start_time = time.time()
|
171 |
+
with torch.inference_mode():
|
172 |
+
pred, _ = model(inp_tensor.long().unsqueeze(0))
|
173 |
+
end_time = time.time()
|
174 |
+
prediction_time = end_time - start_time
|
175 |
+
# Convert prediction to sentiment label
|
176 |
+
sentiment = 'positive' if pred.sigmoid().item() > threshold else 'negative'
|
177 |
+
|
178 |
+
return sentiment, prediction_time
|
179 |
+
|
180 |
+
tokenizer_rubert = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny2")
|
181 |
+
model_rubert = AutoModel.from_pretrained("cointegrated/rubert-tiny2")
|
182 |
+
clf_rubert = LogisticRegression(max_iter=1000) # Предполагается, что ваша модель уже обучена
|
183 |
+
|
184 |
+
with open('rubert/logistic_regression_model.pkl', 'rb') as f:
|
185 |
+
clf_rubert = pickle.load(f)
|
186 |
+
|
187 |
+
# Функция для предсказания
|
188 |
+
def make_prediction(text):
|
189 |
+
start_time = time.time()
|
190 |
+
encoded = tokenizer_rubert(text, add_special_tokens=True, max_length=128, padding='max_length', truncation=True, return_tensors="pt")
|
191 |
+
with torch.no_grad():
|
192 |
+
outputs = model_rubert(**encoded)
|
193 |
+
features = outputs.last_hidden_state[:, 0, :].numpy()
|
194 |
+
prediction = clf_rubert.predict(features)
|
195 |
+
end_time = time.time()
|
196 |
+
prediction_time = end_time - start_time
|
197 |
+
return prediction[0], prediction_time
|
198 |
+
|
199 |
+
# Создание интерфейса Streamlit
|
200 |
+
st.title('Классификатор отзывов на клиники')
|
201 |
+
|
202 |
+
# Текстовое поле для ввода отзыва
|
203 |
+
user_review = st.text_input('Введите ваш отзыв на клинику')
|
204 |
+
|
205 |
+
if st.button('Классифицировать'):
|
206 |
+
if user_review:
|
207 |
+
# Классификация отзыва
|
208 |
+
prediction_tf, pred_time_tf = classify_review_tf(user_review)
|
209 |
+
st.write(f'Предсказанный класс TF-IDF: {prediction_tf}')
|
210 |
+
st.write(f'Время предсказания TF-IDF: {pred_time_tf:.4f} секунд')
|
211 |
+
prediction_lstm, pred_time_lstm = classify_review_lstm(user_review, SEQ_LEN=SEQ_LEN, model=model_lstm)
|
212 |
+
st.write(f'Предсказанный класс LSTM: {prediction_lstm}')
|
213 |
+
st.write(f'Время предсказания LSTM: {pred_time_lstm:.4f} секунд')
|
214 |
+
prediction_rubert, pred_time_rubert = make_prediction(user_review)
|
215 |
+
prediction_ru = 'negative' if prediction_rubert == 0 else 'positive'
|
216 |
+
st.write(f'Предсказанный класс RuBERT: {prediction_ru}')
|
217 |
+
st.write(f'Время предсказания RuBERT: {pred_time_rubert:.4f} секунд')
|
218 |
+
else:
|
219 |
+
st.write('Пожалуйста, введите отзыв')
|
220 |
+
|
221 |
+
if page == "Зоопарк моделей и F1-score":
|
222 |
+
# Создание данных для таблицы
|
223 |
+
data = {
|
224 |
+
"Название модели": ["TF-IDF", "LSTM", "RuBert tiny-2"],
|
225 |
+
"F-1 macro score": ["0,94", "0,89", "0,90"]
|
226 |
+
}
|
227 |
+
|
228 |
+
# Создание DataFrame
|
229 |
+
df = pd.DataFrame(data)
|
230 |
+
|
231 |
+
# Отображение таблицы в Streamlit
|
232 |
+
st.table(df)
|
233 |
+
|
234 |
+
|
235 |
+
if page == "Определение токсичности":
|
236 |
+
|
237 |
+
# Функция для загрузки обученной модели
|
238 |
+
def load_model(model_path):
|
239 |
+
with open(model_path, 'rb') as file:
|
240 |
+
model = pickle.load(file)
|
241 |
+
return model
|
242 |
+
|
243 |
+
# Загрузка обученной модели
|
244 |
+
clf_c = load_model('toxic/logistic_regression_model_toxic.pkl') # Укажите путь к файлу модели
|
245 |
+
|
246 |
+
# Загрузка токенизатора и модели BERT
|
247 |
+
tokenizer_c = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny-toxicity")
|
248 |
+
model_c = AutoModel.from_pretrained("cointegrated/rubert-tiny-toxicity")
|
249 |
+
|
250 |
+
# Функция для предсказания токсичности сообщения
|
251 |
+
def predict_toxicity(text):
|
252 |
+
encoded = tokenizer_c(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
253 |
+
with torch.no_grad():
|
254 |
+
outputs = model_c(**encoded)
|
255 |
+
features = outputs.last_hidden_state[:, 0, :].numpy()
|
256 |
+
prediction = clf_c.predict_proba(features)
|
257 |
+
return prediction[0]
|
258 |
+
|
259 |
+
model_checkpoint = 'cointegrated/rubert-tiny-toxicity'
|
260 |
+
tokenizer_b = AutoTokenizer.from_pretrained(model_checkpoint)
|
261 |
+
model_b = AutoModelForSequenceClassification.from_pretrained(model_checkpoint)
|
262 |
+
|
263 |
+
def text2toxicity(text):
|
264 |
+
with torch.no_grad():
|
265 |
+
inputs = tokenizer_b(text, return_tensors='pt', truncation=True, padding=True)
|
266 |
+
proba = torch.sigmoid(model_b(**inputs).logits).cpu().numpy()
|
267 |
+
return proba[0][1]
|
268 |
+
|
269 |
+
# Создание интерфейса Streamlit
|
270 |
+
st.title("Оценка токсичности сообщения")
|
271 |
+
|
272 |
+
# Текстовое поле для ввода сообщения
|
273 |
+
user_input = st.text_area("Введите сообщение для оценки")
|
274 |
+
|
275 |
+
if st.button("Оценить токсичность сообщения кастомизированной моделью"):
|
276 |
+
if user_input:
|
277 |
+
# Оценка токсичности сообщения
|
278 |
+
prediction = predict_toxicity(user_input)[1]
|
279 |
+
st.write(f'Вероятность токсичности согласно кастомизированной модели: {prediction:.4f}')
|
280 |
+
else:
|
281 |
+
st.write("Пожалуйста, введите сообщение")
|
282 |
+
|
283 |
+
if st.button('Определить токсичность базовой моделью'):
|
284 |
+
if user_input:
|
285 |
+
# Определение токсичности сообщения
|
286 |
+
proba_toxicity = text2toxicity(user_input)
|
287 |
+
st.write(f'Вероятность токсичности rubert-tiny-toxicity.pretrained: {proba_toxicity:.4f}')
|
288 |
+
else:
|
289 |
+
st.write('Пожалуйста, введите сообщение')
|
290 |
+
|
291 |
+
|
292 |
+
|
293 |
+
if page == "Генерация текста":
|
294 |
+
|
295 |
+
# Путь к вашим весам модели
|
296 |
+
model_weights_path = 'gpt-2/model.pt'
|
297 |
+
|
298 |
+
# Загружаем токенизатор от GPT-2
|
299 |
+
tokenizer = GPT2Tokenizer.from_pretrained("sberbank-ai/rugpt3small_based_on_gpt2")
|
300 |
+
|
301 |
+
# Создаем экземпляр модели с архитектурой GPT-2, но без предварительно обученных весов
|
302 |
+
model = GPT2LMHeadModel.from_pretrained('sberbank-ai/rugpt3small_based_on_gpt2')
|
303 |
+
|
304 |
+
# Загружаем веса вашей модели
|
305 |
+
model.load_state_dict(torch.load(model_weights_path, map_location='cpu'))
|
306 |
+
|
307 |
+
# Переносим модель на устройство (GPU или CPU)
|
308 |
+
device = 'cpu'
|
309 |
+
model.to(device)
|
310 |
+
model.eval()
|
311 |
+
|
312 |
+
def main():
|
313 |
+
st.title("Генератор плохих отзывов больниц от ruGPT3")
|
314 |
+
|
315 |
+
# Ввод текста от пользователя
|
316 |
+
user_prompt = st.text_area("Введите текст-промпт:", "Я была в этой клинике")
|
317 |
+
|
318 |
+
# Виджеты для динамической регуляции параметров
|
319 |
+
max_length = st.slider("Выберите max_length:", 10, 300, 100)
|
320 |
+
temperature = st.slider("Выберите temperature:", 1.0, 10.0, step=0.2)
|
321 |
+
top_k = st.slider("Выберите top_k:", 100, 500, 50)
|
322 |
+
top_p = st.slider("Выберите top_p:", 0.1, 1.0, 0.95, step=0.05)
|
323 |
+
num_beams = st.slider('Выберите num_beams:', 5, 40, step=1)
|
324 |
+
|
325 |
+
# Генерация текста при нажатии на кнопку
|
326 |
+
if st.button("Сгенерировать текст"):
|
327 |
+
with torch.no_grad():
|
328 |
+
prompt = tokenizer.encode(user_prompt, return_tensors='pt').to(device)
|
329 |
+
out = model.generate(
|
330 |
+
input_ids=prompt,
|
331 |
+
max_length=max_length,
|
332 |
+
num_beams=num_beams,
|
333 |
+
temperature=temperature,
|
334 |
+
top_k=top_k,
|
335 |
+
top_p=top_p,
|
336 |
+
no_repeat_ngram_size=2,
|
337 |
+
).cpu().numpy()
|
338 |
+
generated_text = tokenizer.decode(out[0], skip_special_tokens=True)
|
339 |
+
st.subheader("Сгенерированный текст:")
|
340 |
+
st.write(generated_text)
|
341 |
+
|
342 |
+
if __name__ == "__main__":
|
343 |
+
main()
|
344 |
+
|
lstm/lstm_model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a6fd3a156141324e2c9eb10ac3458a0e74ebb9c49aef162c5794a415f91de81f
|
3 |
+
size 11341922
|
lstm/rnn_preprocessing.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
import string
|
3 |
+
import numpy as np
|
4 |
+
import torch
|
5 |
+
|
6 |
+
from nltk.corpus import stopwords
|
7 |
+
stop_words = set(stopwords.words('english'))
|
8 |
+
|
9 |
+
def data_preprocessing(text: str) -> str:
|
10 |
+
"""preprocessing string: lowercase, removing html-tags, punctuation,
|
11 |
+
stopwords, digits
|
12 |
+
|
13 |
+
Args:
|
14 |
+
text (str): input string for preprocessing
|
15 |
+
|
16 |
+
Returns:
|
17 |
+
str: preprocessed string
|
18 |
+
"""
|
19 |
+
|
20 |
+
text = text.lower()
|
21 |
+
text = re.sub('<.*?>', '', text) # html tags
|
22 |
+
text = ''.join([c for c in text if c not in string.punctuation])# Remove punctuation
|
23 |
+
text = ' '.join([word for word in text.split() if word not in stop_words])
|
24 |
+
text = [word for word in text.split() if not word.isdigit()]
|
25 |
+
text = ' '.join(text)
|
26 |
+
return text
|
27 |
+
|
28 |
+
def get_words_by_freq(sorted_words: list, n: int = 10) -> list:
|
29 |
+
return list(filter(lambda x: x[1] > n, sorted_words))
|
30 |
+
|
31 |
+
def padding(review_int: list, seq_len: int) -> np.array: # type: ignore
|
32 |
+
"""Make left-sided padding for input list of tokens
|
33 |
+
|
34 |
+
Args:
|
35 |
+
review_int (list): input list of tokens
|
36 |
+
seq_len (int): max length of sequence, it len(review_int[i]) > seq_len it will be trimmed, else it will be padded by zeros
|
37 |
+
|
38 |
+
Returns:
|
39 |
+
np.array: padded sequences
|
40 |
+
"""
|
41 |
+
features = np.zeros((len(review_int), seq_len), dtype = int)
|
42 |
+
for i, review in enumerate(review_int):
|
43 |
+
if len(review) <= seq_len:
|
44 |
+
zeros = list(np.zeros(seq_len - len(review)))
|
45 |
+
new = zeros + review
|
46 |
+
else:
|
47 |
+
new = review[: seq_len]
|
48 |
+
features[i, :] = np.array(new)
|
49 |
+
|
50 |
+
return features
|
51 |
+
|
52 |
+
def preprocess_single_string(
|
53 |
+
input_string: str,
|
54 |
+
seq_len: int,
|
55 |
+
vocab_to_int: dict,
|
56 |
+
verbose : bool = False
|
57 |
+
) -> torch.tensor:
|
58 |
+
"""Function for all preprocessing steps on a single string
|
59 |
+
|
60 |
+
Args:
|
61 |
+
input_string (str): input single string for preprocessing
|
62 |
+
seq_len (int): max length of sequence, it len(review_int[i]) > seq_len it will be trimmed, else it will be padded by zeros
|
63 |
+
vocab_to_int (dict, optional): word corpus {'word' : int index}. Defaults to vocab_to_int.
|
64 |
+
|
65 |
+
Returns:
|
66 |
+
list: preprocessed string
|
67 |
+
"""
|
68 |
+
|
69 |
+
preprocessed_string = data_preprocessing(input_string)
|
70 |
+
result_list = []
|
71 |
+
for word in preprocessed_string.split():
|
72 |
+
try:
|
73 |
+
result_list.append(vocab_to_int[word])
|
74 |
+
except KeyError as e:
|
75 |
+
if verbose:
|
76 |
+
print(f'{e}: not in dictionary!')
|
77 |
+
pass
|
78 |
+
result_padded = padding([result_list], seq_len)[0]
|
79 |
+
|
80 |
+
return torch.tensor(result_padded)
|
lstm/vocab_to_int.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
lstm/word2vec.model
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6026f577c772a215706fdc1afa07bdbf069b30dc9f65b658bc638c52d6d79611
|
3 |
+
size 1251312
|
rubert/logistic_regression_model.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:3a7080b96e67f49e95633afb9f73f8df4c42859da5c72777cd4e5fb5c21373b3
|
3 |
+
size 3210
|
tf-idf/tf-idf.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:26ac8a2985942f283db82f07dbe2124b18e50d05c0f1e98ede95338a26911b42
|
3 |
+
size 529407
|
tf-idf/tf-idf_vectorizer.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:772dfeb1b7264ebf743229968e7d272f5aef1eb24911672708a485dc0421f147
|
3 |
+
size 2667929
|
toxic/logistic_regression_model_toxic.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:0a7214a8bbc6c4fde231a013fe2808d94532d6a84f054740cf6e897e86e9cd6b
|
3 |
+
size 3176
|