sentimentanalyzer01 commited on
Commit
81e292c
·
verified ·
1 Parent(s): c9a5683

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -57
app.py CHANGED
@@ -20,6 +20,9 @@ from transformers import BertTokenizer, BertModel
20
  import warnings
21
  warnings.filterwarnings('ignore')
22
 
 
 
 
23
  try:
24
  import pkg_resources
25
  print("✅ pkg_resources уже установлен")
@@ -30,15 +33,6 @@ except ImportError:
30
  import pkg_resources
31
  print("✅ pkg_resources установлен")
32
 
33
- # Сохраняем ссылку на класс в глобальной области видимости
34
- _global_ontology_class = None
35
-
36
- def _register_ontology_class(cls):
37
- """Регистрирует класс OntologyEmotionModel для pickle"""
38
- import __main__
39
- __main__.OntologyEmotionModel = cls
40
- print(f"✅ Класс {cls.__name__} зарегистрирован в __main__")
41
-
42
  # Определяем устройство
43
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
44
  print(f"Используется устройство: {device}")
@@ -105,7 +99,6 @@ class EmotionBERT(nn.Module):
105
  def __init__(self, bert_model_name, num_classes, dropout=0.3):
106
  super().__init__()
107
  self.bert = BertModel.from_pretrained(bert_model_name)
108
- # Замораживаем все слои кроме последних
109
  for p in list(self.bert.parameters())[:-50]:
110
  p.requires_grad = False
111
  hidden = self.bert.config.hidden_size
@@ -240,13 +233,11 @@ class OntologyEmotionModel:
240
  adj = rule_analysis['adjustments']
241
  rules = rule_analysis['rules_applied']
242
 
243
- # Базовая корректировка
244
  conf_mult = 1.0 + adj['arousal'] * 0.2
245
  conf_mult = np.clip(conf_mult, 0.5, 1.5)
246
  new_confidence = original_confidence * conf_mult
247
  new_emotion = original_emotion
248
 
249
- # Специальные правила
250
  for rule in rules:
251
  if rule.startswith("отрицания:"):
252
  new_confidence *= 0.8
@@ -260,7 +251,6 @@ class OntologyEmotionModel:
260
  def get_ontology_analysis(self, text: str, model_prediction: Dict) -> Dict:
261
  rule_analysis = self.apply_linguistic_rules(text)
262
  adjusted = self.adjust_prediction_with_rules(model_prediction, rule_analysis)
263
-
264
  return {
265
  'rule_analysis': rule_analysis,
266
  'adjusted_prediction': adjusted
@@ -321,7 +311,6 @@ class CascadeEmotionClassifier:
321
  'probabilities': lstm_probs[0].cpu().numpy().tolist()
322
  }
323
 
324
- # Применяем онтологию к LSTM предсказанию
325
  lstm_onto = self.ontology_model.get_ontology_analysis(text_clean, lstm_pred_dict)
326
  lstm_adjusted = lstm_onto['adjusted_prediction']
327
 
@@ -330,7 +319,6 @@ class CascadeEmotionClassifier:
330
  final = lstm_adjusted
331
  used_model = "LSTM с онтологией"
332
  else:
333
- # BERT prediction
334
  self.stats['bert'] += 1
335
  enc = self.tokenizer(
336
  text_clean,
@@ -356,14 +344,12 @@ class CascadeEmotionClassifier:
356
  'probabilities': bert_probs[0].cpu().numpy().tolist()
357
  }
358
 
359
- # Применяем онтологию к BERT предсказанию
360
  bert_onto = self.ontology_model.get_ontology_analysis(text_clean, bert_pred_dict)
361
  bert_adjusted = bert_onto['adjusted_prediction']
362
  final = bert_adjusted
363
  used_model = "BERT с онтологией"
364
- lstm_onto = bert_onto # для единообразия
365
 
366
- # Формируем результат
367
  result = {
368
  'text': text,
369
  'text_clean': text_clean,
@@ -380,47 +366,41 @@ class CascadeEmotionClassifier:
380
  'lstm_confidence': float(lstm_conf.item()),
381
  'was_corrected': len(lstm_onto['rule_analysis']['rules_applied']) > 0
382
  }
383
-
384
  return result
385
 
386
  # ============================================================
387
- # ⚠️ РЕГИСТРИРУЕМ КЛАСС ДЛЯ PICKLE ПОСЛЕ ЕГО ОПРЕДЕЛЕНИЯ
388
- # ============================================================
389
- _register_ontology_class(OntologyEmotionModel)
390
-
391
- # ============================================================
392
- # ЗАГРУЗКА МОДЕЛИ (исправленная версия)
393
  # ============================================================
394
- # ===== ИСПРАВЛЕНО: загрузка онтологии с предварительной инициализацией pymorphy3 =====
395
- print("📂 Загрузка сохранённой онтологии...")
396
- try:
397
- # Предварительно инициализируем pymorphy3, чтобы словари загрузились
398
- test_morph = pymorphy3.MorphAnalyzer()
399
- test_word = test_morph.parse('тест')[0]
400
- print("✅ pymorphy3 инициализирован")
401
 
402
- # Убеждаемся, что класс доступен
403
- import __main__
404
- __main__.OntologyEmotionModel = OntologyEmotionModel
405
 
406
- # Загружаем онтологию
407
- with open(f'{model_dir}/ontology_model.pkl', 'rb') as f:
408
- ontology_model = pickle.load(f)
409
- print("✅ Сохранённая онтология успешно загружена!")
410
 
411
- # Проверяем статистику
412
- if hasattr(ontology_model, 'get_statistics'):
413
- stats = ontology_model.get_statistics()
414
- print(f"📊 Статистика онтологии: узлов={stats.get('ontology_nodes', 0)}")
 
 
 
 
 
 
415
 
416
- except Exception as e:
417
- print(f"❌ Ошибка загрузки онтологии: {e}")
418
- print("🔍 Подробности ошибки:")
419
- import traceback
420
- traceback.print_exc()
421
- raise RuntimeError("Не удалось загрузить онтологию") from e
422
- # ============================================================
423
- # ============================================================
424
 
425
  # Создаем и загружаем LSTM
426
  print("📂 Загрузка LSTM модели...")
@@ -474,11 +454,8 @@ except Exception as e:
474
  # FASTAPI ПРИЛОЖЕНИЕ
475
  # ============================================================
476
  app = FastAPI(title="Emotion Analysis with BERT and Ontology")
477
-
478
- # Настраиваем шаблоны
479
  templates = Jinja2Templates(directory="templates")
480
 
481
- # Глобальная переменная для модели
482
  classifier = None
483
  model_info = None
484
 
@@ -510,16 +487,14 @@ async def predict(text: str = Form(...)):
510
  try:
511
  result = classifier.predict(text)
512
 
513
- # Форматируем правила для отображения
514
  rules_display = []
515
- for rule in result['rules_applied'][:10]: # Показываем не больше 10 правил
516
  if ':' in rule:
517
  cat, val = rule.split(':', 1)
518
  rules_display.append(f"<span class='rule-tag rule-{cat.strip()}'>{cat}: {val.strip()}</span>")
519
  else:
520
  rules_display.append(f"<span class='rule-tag'>{rule}</span>")
521
 
522
- # Форматируем вероятности
523
  probs_display = []
524
  for emotion, prob in result['class_probabilities'].items():
525
  percentage = prob * 100
 
20
  import warnings
21
  warnings.filterwarnings('ignore')
22
 
23
+ # ============================================================
24
+ # Устанавливаем setuptools для pkg_resources
25
+ # ============================================================
26
  try:
27
  import pkg_resources
28
  print("✅ pkg_resources уже установлен")
 
33
  import pkg_resources
34
  print("✅ pkg_resources установлен")
35
 
 
 
 
 
 
 
 
 
 
36
  # Определяем устройство
37
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
38
  print(f"Используется устройство: {device}")
 
99
  def __init__(self, bert_model_name, num_classes, dropout=0.3):
100
  super().__init__()
101
  self.bert = BertModel.from_pretrained(bert_model_name)
 
102
  for p in list(self.bert.parameters())[:-50]:
103
  p.requires_grad = False
104
  hidden = self.bert.config.hidden_size
 
233
  adj = rule_analysis['adjustments']
234
  rules = rule_analysis['rules_applied']
235
 
 
236
  conf_mult = 1.0 + adj['arousal'] * 0.2
237
  conf_mult = np.clip(conf_mult, 0.5, 1.5)
238
  new_confidence = original_confidence * conf_mult
239
  new_emotion = original_emotion
240
 
 
241
  for rule in rules:
242
  if rule.startswith("отрицания:"):
243
  new_confidence *= 0.8
 
251
  def get_ontology_analysis(self, text: str, model_prediction: Dict) -> Dict:
252
  rule_analysis = self.apply_linguistic_rules(text)
253
  adjusted = self.adjust_prediction_with_rules(model_prediction, rule_analysis)
 
254
  return {
255
  'rule_analysis': rule_analysis,
256
  'adjusted_prediction': adjusted
 
311
  'probabilities': lstm_probs[0].cpu().numpy().tolist()
312
  }
313
 
 
314
  lstm_onto = self.ontology_model.get_ontology_analysis(text_clean, lstm_pred_dict)
315
  lstm_adjusted = lstm_onto['adjusted_prediction']
316
 
 
319
  final = lstm_adjusted
320
  used_model = "LSTM с онтологией"
321
  else:
 
322
  self.stats['bert'] += 1
323
  enc = self.tokenizer(
324
  text_clean,
 
344
  'probabilities': bert_probs[0].cpu().numpy().tolist()
345
  }
346
 
 
347
  bert_onto = self.ontology_model.get_ontology_analysis(text_clean, bert_pred_dict)
348
  bert_adjusted = bert_onto['adjusted_prediction']
349
  final = bert_adjusted
350
  used_model = "BERT с онтологией"
351
+ lstm_onto = bert_onto
352
 
 
353
  result = {
354
  'text': text,
355
  'text_clean': text_clean,
 
366
  'lstm_confidence': float(lstm_conf.item()),
367
  'was_corrected': len(lstm_onto['rule_analysis']['rules_applied']) > 0
368
  }
 
369
  return result
370
 
371
  # ============================================================
372
+ # ЗАГРУЗКА МОДЕЛИ
 
 
 
 
 
373
  # ============================================================
374
+ def load_model():
375
+ print("Загрузка модели...")
376
+ model_dir = 'model'
 
 
 
 
377
 
378
+ # Загружаем информацию о модели
379
+ with open(f'{model_dir}/model_info.json', 'r', encoding='utf-8') as f:
380
+ model_info = json.load(f)
381
 
382
+ # Загружаем vocab
383
+ with open(f'{model_dir}/vocab.json', 'r', encoding='utf-8') as f:
384
+ vocab = json.load(f)
 
385
 
386
+ # Загружаем label encoder
387
+ with open(f'{model_dir}/label_encoder.pkl', 'rb') as f:
388
+ label_encoder = pickle.load(f)
389
+
390
+ # Загружаем онтологию
391
+ print("📂 Загрузка сохранённой онтологии...")
392
+ try:
393
+ # Убеждаемся, что класс доступен
394
+ import __main__
395
+ __main__.OntologyEmotionModel = OntologyEmotionModel
396
 
397
+ # Загружаем онтологию
398
+ with open(f'{model_dir}/ontology_model.pkl', 'rb') as f:
399
+ ontology_model = pickle.load(f)
400
+ print("✅ Сохранённая онтология успешно загружена!")
401
+ except Exception as e:
402
+ print(f" Ошибка загрузки онтологии: {e}")
403
+ raise RuntimeError("Не удалось загрузить онтологию") from e
 
404
 
405
  # Создаем и загружаем LSTM
406
  print("📂 Загрузка LSTM модели...")
 
454
  # FASTAPI ПРИЛОЖЕНИЕ
455
  # ============================================================
456
  app = FastAPI(title="Emotion Analysis with BERT and Ontology")
 
 
457
  templates = Jinja2Templates(directory="templates")
458
 
 
459
  classifier = None
460
  model_info = None
461
 
 
487
  try:
488
  result = classifier.predict(text)
489
 
 
490
  rules_display = []
491
+ for rule in result['rules_applied'][:10]:
492
  if ':' in rule:
493
  cat, val = rule.split(':', 1)
494
  rules_display.append(f"<span class='rule-tag rule-{cat.strip()}'>{cat}: {val.strip()}</span>")
495
  else:
496
  rules_display.append(f"<span class='rule-tag'>{rule}</span>")
497
 
 
498
  probs_display = []
499
  for emotion, prob in result['class_probabilities'].items():
500
  percentage = prob * 100