File size: 4,257 Bytes
5ba7acb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import streamlit as st
import joblib
import pandas as pd
from time import time
import transformers
import torch
from torch import nn


st.title("Классификация отзыва по кино")
user_input = st.text_area("Введите ваш отзыв на фильм:", height=100)

model1 = torch.load("models/model_log_reg.pth", map_location="cpu", weights_only=False)

bert_model = transformers.BertModel.from_pretrained("cointegrated/rubert-tiny2")

class LSTMClassifier(nn.Module):
    def __init__(self, vocab_size, embed_dim=128, hidden_dim=64, output_dim=3):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
        self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
        self.fc = nn.Linear(hidden_dim, output_dim)
    
    def forward(self, x):
        x = self.embedding(x)
        _, (h_n, _) = self.lstm(x)
        out = self.fc(h_n[-1])
        return out

model2 = LSTMClassifier(vocab_size=159014)
model2.load_state_dict(torch.load('models/lstm_model.pth', map_location="cpu"))
model2.eval()
class MyTinyBERT(nn.Module):
    def __init__(self):
        super().__init__()
        # забираем bert для русского языка
        self.bert = bert_model
        # морозим его параметры
        for param in self.bert.parameters():
            param.requires_grad = False
        # добавляем собственный слой классификации
        self.linear = nn.Sequential(
            nn.Linear(312, 256),
            nn.Softmax(),
            # # выход на 3 класса как в задаче выше
            nn.Linear(256, 3)
        )
 
        
    def forward(self, input_ids, attention_mask):
        # данные на вход берту
        bert_out = self.bert(input_ids=input_ids, attention_mask=attention_mask)
        # нормализируем – хуже не будет
        normed_bert_out = nn.functional.normalize(bert_out.last_hidden_state[:, 0, :])
        # далее блок классификации
        out = self.linear(normed_bert_out)
        return out

tokenizer = transformers.BertTokenizer.from_pretrained("cointegrated/rubert-tiny2")


model3 = MyTinyBERT()

model3.load_state_dict(torch.load('models/model111.pth', map_location="cpu"))
model3.eval()


labels = ['Плохой отзыв', 'Нейтральный отзыв', 'Прекрасный отзыв']

# Функция для предобработки отзыва
def preprocess_review(review_text, vocab):
    # Очистка отзыва: удаление эмодзи, знаков препинания, стоп-слов и приведение к нижнему регистру
      # Удаляем эмодзи
      # Убираем знаки препинания
    review_text = review_text.lower()  # Приводим к нижнему регистру

    # Токенизация
    tokens = review_text.split()

    # Удаляем стоп-слова

    # Преобразуем в индексы из словаря (vocab)
    tokens = [vocab.get(word, 0) for word in tokens]  # Если слово нет в vocab, заменяем на 0

    return tokens

vocab = joblib.load('models/vocab.pkl')

if user_input:
    st.subheader("🔍 Предсказания моделей")

    results = {}
    encoding = tokenizer(user_input, truncation=True, padding='max_length', max_length=18, return_tensors='pt')
    # TF-IDF + Logistic Regression
    start = time()
    pred = model1.predict([user_input])[0]
    end = time()
    st.write(labels[pred], ' : LogisticRegression')
    st.write(round(end - start,3),"сек")
    start = time()
    outputs = model3(encoding['input_ids'] ,encoding['attention_mask'])
    end = time()
    st.write(labels[outputs.argmax(1)],' : BertModel')
    st.write(round(end - start,3),"сек")
    start = time()
    lod = preprocess_review(user_input,vocab)
    input_tensor = torch.tensor(lod).unsqueeze(0)

    output = model2(input_tensor)
    _, predicted = torch.max(output, dim=1)

    label = predicted.item()
    st.write(labels[label],' : LSTM')
    end = time()
    st.write(round(end - start,3),"сек")