Spaces:
Running
Running
File size: 8,604 Bytes
8db7949 |
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
__all__ = ["binary_app"]
import gradio as gr
import torch
import os
from model_utils import load_model, classify_text
from binoculars_utils import initialize_binoculars, compute_scores
# Initialize Binoculars models
bino_chat, bino_coder = initialize_binoculars()
# Load binary classifier model
model, scaler, label_encoder, imputer = load_model()
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
MINIMUM_TOKENS = 50
SAMPLE_TEXT = """Привет! Я хотел бы рассказать вам о своём опыте путешествия по Петербургу. Невероятный город с богатой историей и красивой архитектурой. Особенно запомнился Эрмитаж с его огромной коллекцией произведений искусства. Также понравилась прогулка по каналам города, где можно увидеть множество старинных мостов и зданий."""
css = """
.human-text {
color: black !important;
line-height: 1.9em;
padding: 0.5em;
background: #ccffcc;
border-radius: 0.5rem;
font-weight: bold;
}
.ai-text {
color: black !important;
line-height: 1.9em;
padding: 0.5em;
background: #ffad99;
border-radius: 0.5rem;
font-weight: bold;
}
.analysis-block {
background: #f5f5f5;
padding: 15px;
border-radius: 8px;
margin-top: 10px;
}
.scores {
font-size: 1.1em;
padding: 10px;
background: #e6f7ff;
border-radius: 5px;
margin: 10px 0;
}
"""
def run_binary_classifier(text, show_analysis=False):
if len(text.strip()) < MINIMUM_TOKENS:
return gr.Markdown(f"Текст слишком короткий. Требуется минимум {MINIMUM_TOKENS} символов."), None, None
# Compute scores using binoculars
scores = compute_scores(text, bino_chat, bino_coder)
# Run classification
result = classify_text(text, model, scaler, label_encoder, imputer=imputer, scores=scores)
# Format results
predicted_class = result['predicted_class']
probabilities = result['probabilities']
# Format probabilities
prob_str = ""
for cls, prob in probabilities.items():
prob_str += f"- {cls}: {prob:.4f}\n"
# Format scores
scores_str = ""
if scores:
scores_str = "### Binoculars Scores\n"
if 'score_chat' in scores:
scores_str += f"- Score Chat: {scores['score_chat']:.4f}\n"
if 'score_coder' in scores:
scores_str += f"- Score Coder: {scores['score_coder']:.4f}\n"
# Result markdown
class_style = "human-text" if predicted_class == "Human" else "ai-text"
result_md = f"""
## Результат классификации
Предсказанный класс: <span class="{class_style}">{predicted_class}</span>
### Вероятности классов:
{prob_str}
{scores_str}
"""
# Analysis markdown
analysis_md = None
if show_analysis:
features = result['features']
text_analysis = result['text_analysis']
analysis_md = "## Анализ текста\n\n"
# Basic statistics
analysis_md += "### Основная статистика\n"
analysis_md += f"- Всего токенов: {text_analysis['basic_stats']['total_tokens']}\n"
analysis_md += f"- Всего слов: {text_analysis['basic_stats']['total_words']}\n"
analysis_md += f"- Уникальных слов: {text_analysis['basic_stats']['unique_words']}\n"
analysis_md += f"- Стоп-слов: {text_analysis['basic_stats']['stop_words']}\n"
analysis_md += f"- Средняя длина слова: {text_analysis['basic_stats']['avg_word_length']:.2f} символов\n\n"
# Lexical diversity
analysis_md += "### Лексическое разнообразие\n"
analysis_md += f"- TTR (Type-Token Ratio): {text_analysis['lexical_diversity']['ttr']:.3f}\n"
analysis_md += f"- MTLD (упрощенный): {text_analysis['lexical_diversity']['mtld']:.2f}\n\n"
# Text structure
analysis_md += "### Структура текста\n"
analysis_md += f"- Количество предложений: {text_analysis['text_structure']['sentence_count']}\n"
analysis_md += f"- Средняя длина предложения: {text_analysis['text_structure']['avg_sentence_length']:.2f} токенов\n\n"
# Readability
analysis_md += "### Читабельность\n"
analysis_md += f"- Flesch-Kincaid score: {text_analysis['readability']['flesh_kincaid_score']:.2f}\n"
analysis_md += f"- Процент длинных слов: {text_analysis['readability']['long_words_percent']:.2f}%\n\n"
# Semantic coherence
analysis_md += "### Семантическая связность\n"
analysis_md += f"- Средняя связность между предложениями: {text_analysis['semantic_coherence']['avg_coherence_score']:.3f}\n"
return gr.Markdown(result_md), gr.Markdown(analysis_md) if analysis_md else None, text
def reset_outputs():
return None, None, ""
with gr.Blocks(css=css, theme=gr.themes.Base()) as binary_app:
with gr.Row():
with gr.Column(scale=3):
gr.HTML("<h1>Binary Classifier: Human vs AI Text Detection</h1>")
gr.HTML("<p>This demo uses a neural network (Medium_Binary_Network) to classify text as either written by a human or generated by AI.</p>")
with gr.Row():
with gr.Column():
input_text = gr.Textbox(value=SAMPLE_TEXT, placeholder="Введите текст для анализа",
lines=10, label="Текст для анализа")
with gr.Row():
analysis_checkbox = gr.Checkbox(label="Показать детальный анализ текста", value=False)
submit_button = gr.Button("Классифицировать", variant="primary")
clear_button = gr.Button("Очистить")
with gr.Row():
with gr.Column():
result_output = gr.Markdown(label="Результат")
with gr.Row():
with gr.Column():
analysis_output = gr.Markdown(label="Анализ")
with gr.Accordion("О модели", open=False):
gr.Markdown("""
### О бинарном классификаторе
Эта демонстрация использует нейронную сеть Medium_Binary_Network для классификации текста как написанного человеком или сгенерированного ИИ.
#### Архитектура модели:
- Входной слой: Количество признаков (зависит от анализа текста)
- Скрытые слои: [256, 192, 128, 64]
- Выходной слой: 2 класса (Human, AI)
- Dropout: 0.3
#### Особенности:
- Используется анализ текста и оценки качества текста с помощью Binoculars
- Анализируются морфологические, синтаксические и семантические особенности текста
- Вычисляются показатели лексического разнообразия и читабельности
#### Рекомендации:
- Для более точной классификации рекомендуется использовать тексты длиннее 100 слов
- Модель обучена на русскоязычных текстах
""")
# Set up event handlers
submit_button.click(
fn=run_binary_classifier,
inputs=[input_text, analysis_checkbox],
outputs=[result_output, analysis_output, input_text]
)
clear_button.click(
fn=reset_outputs,
inputs=[],
outputs=[result_output, analysis_output, input_text]
) |