Spaces:
Runtime error
Runtime error
files uploaded
Browse files- app.py +140 -16
- gpt-2/model.pt +3 -0
- rubert/logistic_regression_model.pkl +3 -0
- toxic/logistic_regression_model_toxic.pkl +3 -0
app.py
CHANGED
|
@@ -21,15 +21,13 @@ import torch.nn as nn
|
|
| 21 |
import json
|
| 22 |
import gensim
|
| 23 |
import torch.nn.functional as F
|
| 24 |
-
|
| 25 |
-
from nltk.corpus import stopwords
|
| 26 |
-
stop_words = set(stopwords.words('english'))
|
| 27 |
|
| 28 |
|
| 29 |
st.title('10-я неделя DS. Классификация отзывов, определение токсичности и генерация текста')
|
| 30 |
|
| 31 |
st.sidebar.header('Выберите страницу')
|
| 32 |
-
page = st.sidebar.radio("Выберите страницу", ["Вводная информация", "Классификация отзывов", "Определение токсичности", "Генерация текста"])
|
| 33 |
|
| 34 |
if page == "Вводная информация":
|
| 35 |
|
|
@@ -60,6 +58,8 @@ if page == "Классификация отзывов":
|
|
| 60 |
vocab_to_int = json.load(f)
|
| 61 |
|
| 62 |
word2vec_model = gensim.models.Word2Vec.load("lstm/word2vec.model")
|
|
|
|
|
|
|
| 63 |
|
| 64 |
def data_preprocessing(text: str) -> str:
|
| 65 |
text = text.lower()
|
|
@@ -137,15 +137,19 @@ if page == "Классификация отзывов":
|
|
| 137 |
model_lstm.load_state_dict(torch.load("lstm/lstm_model.pth"))
|
| 138 |
model_lstm.eval()
|
| 139 |
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
-
|
| 149 |
def classify_review_lstm(review):
|
| 150 |
# Векторизация отзыва
|
| 151 |
review_vector = text_to_vector(review)
|
|
@@ -161,6 +165,25 @@ if page == "Классификация отзывов":
|
|
| 161 |
# Время предсказания
|
| 162 |
prediction_time = end_time - start_time
|
| 163 |
return prediction, prediction_time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
# Создание интерфейса Streamlit
|
| 166 |
st.title('Классификатор отзывов на клиники')
|
|
@@ -177,17 +200,118 @@ if page == "Классификация отзывов":
|
|
| 177 |
prediction_lstm, pred_time_lstm = classify_review_lstm(user_review)
|
| 178 |
st.write(f'Предсказанный класс LSTM: {prediction_tf}')
|
| 179 |
st.write(f'Время предсказания LSTM: {pred_time_tf:.4f} секунд')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
else:
|
| 181 |
st.write('Пожалуйста, введите отзыв')
|
| 182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
|
|
|
|
|
|
|
| 184 |
|
|
|
|
|
|
|
| 185 |
|
| 186 |
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
# if page == "Генерация текста":
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
import json
|
| 22 |
import gensim
|
| 23 |
import torch.nn.functional as F
|
| 24 |
+
from transformers import GPT2LMHeadModel, GPT2Tokenizer
|
|
|
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
st.title('10-я неделя DS. Классификация отзывов, определение токсичности и генерация текста')
|
| 28 |
|
| 29 |
st.sidebar.header('Выберите страницу')
|
| 30 |
+
page = st.sidebar.radio("Выберите страницу", ["Вводная информация", "Классификация отзывов", "Классификация отзывов: неважная информация", "Определение токсичности", "Генерация текста"])
|
| 31 |
|
| 32 |
if page == "Вводная информация":
|
| 33 |
|
|
|
|
| 58 |
vocab_to_int = json.load(f)
|
| 59 |
|
| 60 |
word2vec_model = gensim.models.Word2Vec.load("lstm/word2vec.model")
|
| 61 |
+
|
| 62 |
+
stop_words = ['и', 'в', 'во', 'не', 'что', 'он', 'на', 'я', 'с', 'со', 'как', 'а', 'то', 'все', 'она', 'так', 'его', 'но', 'да', 'ты', 'к', 'у', 'же', 'вы', 'за', 'бы', 'по', 'только', 'ее', 'мне', 'было', 'вот', 'от', 'меня', 'еще', 'нет', 'о', 'из', 'ему', 'теперь', 'когда', 'даже', 'ну', 'вдруг', 'ли', 'если', 'уже', 'или', 'ни', 'быть', 'был', 'него', 'до', 'вас', 'нибудь', 'опять', 'уж', 'вам', 'ведь', 'там', 'потом', 'себя', 'ничего', 'ей', 'может', 'они', 'тут', 'где', 'есть', 'надо', 'ней', 'для', 'мы', 'тебя', 'их', 'чем', 'была', 'сам', 'чтоб', 'без', 'будто', 'чего', 'раз', 'тоже', 'себе', 'под', 'будет', 'ж', 'тогда', 'кто', 'этот', 'того', 'потому', 'этого', 'какой', 'совсем', 'ним', 'здесь', 'этом', 'один', 'почти', 'мой', 'тем', 'чтобы', 'нее', 'сейчас', 'были', 'куда', 'зачем', 'всех', 'никогда', 'можно', 'при', 'наконец', 'два', 'об', 'другой', 'хоть', 'после', 'над', 'больше', 'тот', 'через', 'эти', 'нас', 'про', 'всего', 'них', 'какая', 'много', 'разве', 'три', 'эту', 'моя', 'впрочем', 'хорошо', 'свою', 'этой', 'перед', 'иногда', 'лучше', 'чуть', 'том', 'нельзя', 'такой', 'им', 'более', 'всегда', 'конечно', 'всю', 'между']
|
| 63 |
|
| 64 |
def data_preprocessing(text: str) -> str:
|
| 65 |
text = text.lower()
|
|
|
|
| 137 |
model_lstm.load_state_dict(torch.load("lstm/lstm_model.pth"))
|
| 138 |
model_lstm.eval()
|
| 139 |
|
| 140 |
+
# Проверка и добавление токена <UNK>, если он отсутствует
|
| 141 |
+
if '<UNK>' not in vocab_to_int:
|
| 142 |
+
vocab_to_int['<UNK>'] = len(vocab_to_int) # Присвоение нового уникального индекса
|
| 143 |
+
|
| 144 |
+
# Проверка и добавление токена <PAD>, если он отсутствует
|
| 145 |
+
if '<PAD>' not in vocab_to_int:
|
| 146 |
+
vocab_to_int['<PAD>'] = len(vocab_to_int) # Присвоение нового уникального индекса
|
| 147 |
+
|
| 148 |
+
def text_to_vector(text, unknown_token_id=0):
|
| 149 |
+
words = text.split()
|
| 150 |
+
vector = [vocab_to_int.get(word, unknown_token_id) for word in words] # здесь unknown_token_id - это ID для "неизвестных" слов
|
| 151 |
+
return np.array(vector, dtype=np.int64) # Убедитесь, что тип данных int64
|
| 152 |
|
|
|
|
| 153 |
def classify_review_lstm(review):
|
| 154 |
# Векторизация отзыва
|
| 155 |
review_vector = text_to_vector(review)
|
|
|
|
| 165 |
# Время предсказания
|
| 166 |
prediction_time = end_time - start_time
|
| 167 |
return prediction, prediction_time
|
| 168 |
+
|
| 169 |
+
tokenizer_rubert = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny2")
|
| 170 |
+
model_rubert = AutoModel.from_pretrained("cointegrated/rubert-tiny2")
|
| 171 |
+
clf_rubert = LogisticRegression(max_iter=1000) # Предполагается, что ваша модель уже обучена
|
| 172 |
+
|
| 173 |
+
with open('rubert/logistic_regression_model.pkl', 'rb') as f:
|
| 174 |
+
clf_rubert = pickle.load(f)
|
| 175 |
+
|
| 176 |
+
# Функция для предсказания
|
| 177 |
+
def make_prediction(text):
|
| 178 |
+
start_time = time.time()
|
| 179 |
+
encoded = tokenizer_rubert(text, add_special_tokens=True, max_length=128, padding='max_length', truncation=True, return_tensors="pt")
|
| 180 |
+
with torch.no_grad():
|
| 181 |
+
outputs = model_rubert(**encoded)
|
| 182 |
+
features = outputs.last_hidden_state[:, 0, :].numpy()
|
| 183 |
+
prediction = clf_rubert.predict(features)
|
| 184 |
+
end_time = time.time()
|
| 185 |
+
prediction_time = end_time - start_time
|
| 186 |
+
return prediction[0], prediction_time
|
| 187 |
|
| 188 |
# Создание интерфейса Streamlit
|
| 189 |
st.title('Классификатор отзывов на клиники')
|
|
|
|
| 200 |
prediction_lstm, pred_time_lstm = classify_review_lstm(user_review)
|
| 201 |
st.write(f'Предсказанный класс LSTM: {prediction_tf}')
|
| 202 |
st.write(f'Время предсказания LSTM: {pred_time_tf:.4f} секунд')
|
| 203 |
+
prediction_rubert, pred_time_rubert = make_prediction(user_review)
|
| 204 |
+
prediction_ru = 'negative' if prediction_rubert == 0 else 'positive'
|
| 205 |
+
st.write(f'Предсказанный класс RuBERT: {prediction_ru}')
|
| 206 |
+
st.write(f'Время предсказания RuBERT: {pred_time_rubert:.4f} секунд')
|
| 207 |
else:
|
| 208 |
st.write('Пожалуйста, введите отзыв')
|
| 209 |
|
| 210 |
+
if page == "Классификация отзывов: неважная информация":
|
| 211 |
+
# Создание данных для таблицы
|
| 212 |
+
data = {
|
| 213 |
+
"Название модели": ["TF-IDF", "LSTM", "RuBert tiny-2"],
|
| 214 |
+
"F-1 macro score": ["0,94", "0,89", "0,90"]
|
| 215 |
+
}
|
| 216 |
|
| 217 |
+
# Создание DataFrame
|
| 218 |
+
df = pd.DataFrame(data)
|
| 219 |
|
| 220 |
+
# Отображение таблицы в Streamlit
|
| 221 |
+
st.table(df)
|
| 222 |
|
| 223 |
|
| 224 |
+
if page == "Определение токсичности":
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
+
# Функция для загрузки обученной модели
|
| 227 |
+
def load_model(model_path):
|
| 228 |
+
with open(model_path, 'rb') as file:
|
| 229 |
+
model = pickle.load(file)
|
| 230 |
+
return model
|
| 231 |
|
| 232 |
+
# Загрузка обученной модели
|
| 233 |
+
clf = load_model('toxic/logistic_regression_model_toxic.pkl') # Укажите путь к файлу модели
|
| 234 |
+
|
| 235 |
+
# Загрузка токенизатора и модели BERT
|
| 236 |
+
tokenizer = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny-toxicity")
|
| 237 |
+
model = AutoModel.from_pretrained("cointegrated/rubert-tiny-toxicity")
|
| 238 |
+
|
| 239 |
+
# Функция для предсказания токсичности сообщения
|
| 240 |
+
def predict_toxicity(text):
|
| 241 |
+
encoded = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
| 242 |
+
with torch.no_grad():
|
| 243 |
+
outputs = model(**encoded)
|
| 244 |
+
features = outputs.last_hidden_state[:, 0, :].numpy()
|
| 245 |
+
prediction = clf.predict(features)
|
| 246 |
+
return prediction[0]
|
| 247 |
|
| 248 |
+
# Создание интерфейса Streamlit
|
| 249 |
+
st.title("Оценка токсичности сообщения")
|
| 250 |
+
|
| 251 |
+
# Текстовое поле для ввода сообщения
|
| 252 |
+
user_input = st.text_area("Введите сообщение для оценки")
|
| 253 |
+
|
| 254 |
+
if st.button("Оценить"):
|
| 255 |
+
if user_input:
|
| 256 |
+
# Оценка токсичности сообщения
|
| 257 |
+
prediction = predict_toxicity(user_input)
|
| 258 |
+
if prediction > 0.5:
|
| 259 |
+
st.write("Сообщение токсично")
|
| 260 |
+
st.write(prediction)
|
| 261 |
+
else:
|
| 262 |
+
st.write("Сообщение не токсично")
|
| 263 |
+
st.write(prediction)
|
| 264 |
+
else:
|
| 265 |
+
st.write("Пожалуйста, введите сообщение")
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
if page == "Генерация текста":
|
| 270 |
+
# Путь к вашим весам модели
|
| 271 |
+
model_weights_path = 'gpt-2/model.pt'
|
| 272 |
+
|
| 273 |
+
# Загружаем токенизатор от GPT-2
|
| 274 |
+
tokenizer = GPT2Tokenizer.from_pretrained("sberbank-ai/rugpt3small_based_on_gpt2")
|
| 275 |
+
|
| 276 |
+
# Создаем экземпляр модели с архитектурой GPT-2, но без предварительно обученных весов
|
| 277 |
+
model = GPT2LMHeadModel.from_pretrained('sberbank-ai/rugpt3small_based_on_gpt2')
|
| 278 |
+
|
| 279 |
+
# Загружаем веса вашей модели
|
| 280 |
+
model.load_state_dict(torch.load(model_weights_path, map_location='cpu'))
|
| 281 |
+
|
| 282 |
+
# Переноси�� модель на устройство (GPU или CPU)
|
| 283 |
+
device = 'cpu'
|
| 284 |
+
model.to(device)
|
| 285 |
+
model.eval()
|
| 286 |
+
|
| 287 |
+
def main():
|
| 288 |
+
st.title("Генератор плохих отзывов больниц от ruGPT3")
|
| 289 |
+
|
| 290 |
+
# Ввод текста от пользователя
|
| 291 |
+
user_prompt = st.text_area("Введите текст-промпт:", "Я была в этой клинике..")
|
| 292 |
+
|
| 293 |
+
# Виджеты для динамической регуляции параметров
|
| 294 |
+
max_length = st.slider("Выберите max_length:", 10, 300, 100)
|
| 295 |
+
temperature = st.slider("Выберите temperature:", 1.0, 10.0, step=0.2)
|
| 296 |
+
top_k = st.slider("Выберите top_k:", 100, 500, 50)
|
| 297 |
+
top_p = st.slider("Выберите top_p:", 0.1, 1.0, 0.95, step=0.05)
|
| 298 |
+
num_beams = st.slider('Выберите num_beams:', 5, 40, step=1)
|
| 299 |
+
|
| 300 |
+
# Генерация текста при нажатии на кнопку
|
| 301 |
+
if st.button("Сгенерировать текст"):
|
| 302 |
+
with torch.no_grad():
|
| 303 |
+
prompt = tokenizer.encode(user_prompt, return_tensors='pt').to(device)
|
| 304 |
+
out = model.generate(
|
| 305 |
+
input_ids=prompt,
|
| 306 |
+
max_length=max_length,
|
| 307 |
+
num_beams=num_beams,
|
| 308 |
+
temperature=temperature,
|
| 309 |
+
top_k=top_k,
|
| 310 |
+
top_p=top_p,
|
| 311 |
+
no_repeat_ngram_size=2,
|
| 312 |
+
).cpu().numpy()
|
| 313 |
+
generated_text = tokenizer.decode(out[0], skip_special_tokens=True)
|
| 314 |
+
st.subheader("Сгенерированный текст:")
|
| 315 |
+
st.write(generated_text)
|
| 316 |
+
if __name__ == "__main__":
|
| 317 |
+
main()
|
gpt-2/model.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:58b8435eaabf77d3e051ef7971d32e4db2d2af2a785cd08a31b88b19f50c2ddb
|
| 3 |
+
size 500972122
|
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
|
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
|