import streamlit as st import torch from transformers import AutoTokenizer, AutoModel import joblib import numpy as np import json import pandas as pd from gensim.models import Word2Vec import time from typing import Tuple from torch.utils.data import DataLoader, TensorDataset import torch.nn.functional as F import torch.nn as nn from torchmetrics import Accuracy from torchmetrics.functional import f1_score from string import punctuation import sklearn as sk import os from sklearn.linear_model import LogisticRegression def main(): # Боковая панель с навигацией menu = ["Классификация отзыва на рестораны", "Классификация тематики новостей из телеграмм каналов", "Генерация текста GPT-моделью"] choice = st.sidebar.radio("Навигация", menu) # Отображение контента в зависимости от выбранной страницы if choice == "Классификация отзыва на рестораны": page_restoran() elif choice == "Классификация тематики новостей из телеграмм каналов": page_telegramm() elif choice == "Генерация текста GPT-моделью": page_generaition() with open('vocab_lstm_att.json', 'r') as fp: vocab_to_int = json.load(fp) def page_restoran(): model_path = "word2vec_model.bin" if os.path.exists(model_path): wv = Word2Vec.load(model_path) else: print(f"File '{model_path}' not found.") model_path = "word2vec_model.bin" wv = Word2Vec.load(model_path) VOCAB_SIZE = len(vocab_to_int)+1 HIDDEN_SIZE = 128 SEQ_LEN = 128 DEVICE='cpu' EMBEDDING_DIM = 128 embedding_matrix = torch.load('embedding_matrix.pt') embedding_layer = torch.nn.Embedding.from_pretrained(torch.FloatTensor(embedding_matrix)) class ConcatAttention(nn.Module): def __init__( self, hidden_size: int = HIDDEN_SIZE ) -> None: super().__init__() self.hidden_size = hidden_size self.linear = nn.Linear(hidden_size, hidden_size) self.align = nn.Linear(hidden_size * 2, hidden_size) self.tanh = nn.Tanh() def forward( self, lstm_outputs: torch.Tensor, final_hidden: torch.Tensor ) -> Tuple[torch.Tensor, torch.Tensor]: att_weights = self.linear(lstm_outputs) att_weights = torch.bmm(att_weights, final_hidden.unsqueeze(2)) att_weights = F.softmax(att_weights.squeeze(2), dim=1) cntxt = torch.bmm(lstm_outputs.transpose(1, 2), att_weights.unsqueeze(2)) concatted = torch.cat((cntxt, final_hidden.unsqueeze(2)), dim=1) att_hidden = self.tanh(self.align(concatted.squeeze(-1))) return att_hidden, att_weights class LSTMConcatAttention(nn.Module): def __init__(self) -> None: super().__init__() self.embedding = embedding_layer self.lstm = nn.LSTM(EMBEDDING_DIM, HIDDEN_SIZE, batch_first=True) self.attn = ConcatAttention(HIDDEN_SIZE) self.clf = nn.Sequential( nn.Linear(HIDDEN_SIZE, 128), nn.Dropout(), nn.Tanh(), nn.Linear(128, 6) ) def forward(self, x): embeddings = self.embedding(x) outputs, (h_n, _) = self.lstm(embeddings) att_hidden, att_weights = self.attn(outputs, h_n.squeeze(0)) out = self.clf(att_hidden) return out, att_weights model_lstm_att = LSTMConcatAttention() model_lstm_att.load_state_dict(torch.load('lstm_att_model.pt', map_location='cpu')) model_lstm_att.eval() def pred(text): start_time = time.time() text = text.lower() text = ''.join([c for c in text if c not in punctuation]) text = [vocab_to_int[word] for word in text.split() if vocab_to_int.get(word)] if len(text) <= 128: zeros = list(np.zeros(128 - len(text))) text = zeros + text else: text = text[: 128] text = torch.Tensor(text) text = text.unsqueeze(0) text = text.type(torch.LongTensor) pred = model_lstm_att(text)[0].argmax(1) labels = {0: '0', 1:'1', 2:'2', 3: '3', 4:'4', 5:'5'} end_time = time.time() inference_time = end_time - start_time return f"***{labels[pred.item()]}***, время предсказания: ***{inference_time:.4f} сек***." """ ## Классификация отзывов на ресторан """ st.image('2024-02-02 12.58.31.jpg') st.title('Напиши отзыв на ресторан🌹') user_input = st.text_area('Введите отзыв', '') if st.button('Классифицировать LSTM!🤩'): if user_input.strip() == '': st.error('Введите, пожалуйста, отзыв!') else: st.success(pred(user_input)) tokenizer = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny2") model = AutoModel.from_pretrained("cointegrated/rubert-tiny2") # Загрузка предобученной модели логистической регрессии lr_model = joblib.load('logistic_regression_model1.pkl') # веса модели # Расшифровка оценок class_mapping = { 1: 'Не удовлетворительно', 2: 'Удовлетворительно', 3: 'Хорошо', 4: 'Отлично', 0: 'Превосходно' } # Функция для классификации текста def embed_destil(text, model, tokenizer): t = tokenizer(text, padding=True, truncation=True, return_tensors='pt') with torch.no_grad(): model_output = model(**{k: v.to(model.device) for k, v in t.items()}) embeddings = model_output.last_hidden_state[:, 0, :] embeddings = torch.nn.functional.normalize(embeddings) return embeddings if st.button('Классифицировать ruBERT!🤩'): if user_input.strip() == '': st.error('Пожалуйста, напишите текст отзыва') else: X= embed_destil(user_input, model, tokenizer) predictions= lr_model.predict(X) res=class_mapping[predictions[0]] st.success(f'Оценка заведению: {res}') model_ml = LogisticRegression() vectorizer = joblib.load("vectorizer.pkl") def preprocess(text): # Убедитесь, что text - это список if isinstance(text, str): text = [text] # Преобразуйте текст text = vectorizer.transform(text) return text model = model_ml model = joblib.load("log_reg_tfidf_model.pkl") def predict(text): start_time = time.time() text = preprocess(text) predicted_label = model.predict(text) dict = {0: '0', 1:'1', 2:'2', 3: '3', 4:'4', 5:'5'} predicted_label_text = dict[predicted_label[0]] end_time = time.time() inference_time = end_time - start_time return f"***{predicted_label_text}***, время предсказания: ***{inference_time:.4f} сек***." if st.button('Классифицировать ML-TFIDF!🤩'): if user_input.strip() == '': st.error('Введите, пожалуйста, отзыв!') else: st.success(predict(user_input)) # if choice_model == 'LSTM(attention)': # if text: # st.write(pred(text)) data = pd.DataFrame({'Модель': ['TFIDF-LogReg', 'LSTM(Attention)', 'BERT model'], 'F1-macro': [0.25, 0.2, 0.261]}) # Вывод таблицы checkbox = st.sidebar.checkbox("Таблица f1-macro") if checkbox: st.write("

Оценка качества моделей по метрике f1-macro

", unsafe_allow_html=True) st.table(data) def page_telegramm(): st.header("Определить тему новости 📑") # Добавьте контент для страницы 2 st.image('collage.jpg') # Загрузка предобученной модели RuBERT tokenizer = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny2") model = AutoModel.from_pretrained("cointegrated/rubert-tiny2") # Загрузка предобученной модели логистической регрессии lr_model = joblib.load('trained_logistic_regression_model.pkl') class_mapping = { 1: 'Мода🛍️', 2: 'Спорт🏀', 3: 'Технологии📱', 4: 'Финансы💰', 0: 'Криптовалюта💸' } # Функция для классификации текста def embed_bert_cls(text, model, tokenizer): t = tokenizer(text, padding=True, truncation=True, return_tensors='pt') with torch.no_grad(): model_output = model(**{k: v.to(model.device) for k, v in t.items()}) embeddings = model_output.last_hidden_state[:, 0, :] embeddings = torch.nn.functional.normalize(embeddings) return embeddings user_input = st.text_area('Введите текст для классификации:', '') if st.button('Классифицировать!🤩'): if user_input.strip() == '': st.error('Пожалуйста, введите текст!😡') else: X= embed_bert_cls(user_input, model, tokenizer) predictions= lr_model.predict(X) res=class_mapping[predictions[0]] st.success(f'Я думаю, что тема новости: {res}') def page_generaition(): st.subheader("Генерация текста GPT-моделью") # Добавьте контент для страницы 3 if __name__ == "__main__": main()