Daizzyy commited on
Commit
9bac518
·
verified ·
1 Parent(s): a97ca42

Upload 11 files

Browse files
app.py ADDED
@@ -0,0 +1,652 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # streamlit_app.py
3
+
4
+
5
+ # import streamlit as st
6
+ # from streamlit_lottie import st_lottie
7
+ # from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
8
+ # import torch
9
+ # import json
10
+
11
+ # # ---------------- Load Model ----------------
12
+ # @st.cache_resource
13
+ # def load_model():
14
+ # model_name = "./models" # path to your fine-tuned model
15
+ # tokenizer = AutoTokenizer.from_pretrained(model_name)
16
+ # model = AutoModelForSequenceClassification.from_pretrained(model_name)
17
+ # classifier = pipeline("text-classification", model=model, tokenizer=tokenizer, return_all_scores=True)
18
+ # return classifier
19
+
20
+ # classifier = load_model()
21
+
22
+ # # ---------------- CSS Styles ----------------
23
+ # st.markdown(
24
+ # """
25
+ # <style>
26
+ # body {
27
+ # background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
28
+ # animation: gradientBG 15s ease infinite;
29
+ # height: 100vh;
30
+ # }
31
+
32
+ # @keyframes gradientBG {
33
+ # 0% {background-position: 0% 50%;}
34
+ # 50% {background-position: 100% 50%;}
35
+ # 100% {background-position: 0% 50%;}
36
+ # }
37
+
38
+ # .title {
39
+ # font-size: 55px;
40
+ # font-weight: bold;
41
+ # background: linear-gradient(270deg,
42
+ # #ff0000, #ff7f00, #ffff00, #00ff00,
43
+ # #0000ff, #4b0082, #8f00ff, #ff0000);
44
+ # background-size: 1500% 1500%;
45
+ # -webkit-background-clip: text;
46
+ # -webkit-text-fill-color: transparent;
47
+ # animation: rainbow 10s linear infinite;
48
+ # margin-bottom: 10px;
49
+ # }
50
+
51
+ # @keyframes rainbow {
52
+ # 0% {background-position: 0% 50%;}
53
+ # 50% {background-position: 100% 50%;}
54
+ # 100% {background-position: 0% 50%;}
55
+ # }
56
+
57
+ # .intro-line {
58
+ # font-size: 18px;
59
+ # color: white;
60
+ # margin-bottom: 25px;
61
+ # font-style:italic;
62
+ # }
63
+
64
+ # .stButton button {
65
+ # display: block;
66
+ # margin: 30px auto;
67
+ # background: linear-gradient(90deg, #ff4b4b, #ff8c00);
68
+ # color: white;
69
+ # border-radius: 12px;
70
+ # height: 3em;
71
+ # width: 12em;
72
+ # font-size: 18px;
73
+ # font-weight: bold;
74
+ # border: none;
75
+ # box-shadow: 0px 4px 10px rgba(0,0,0,0.3);
76
+ # transition: 0.3s;
77
+ # }
78
+ # .stButton button:hover {
79
+ # transform: scale(1.1);
80
+ # background: linear-gradient(90deg, #7d00ff, #00d4ff);
81
+ # }
82
+
83
+ # .output-box {
84
+ # padding: 15px;
85
+ # border-radius: 12px;
86
+ # margin-top: 20px;
87
+ # font-size: 20px;
88
+ # font-weight: bold;
89
+ # text-align: center;
90
+ # }
91
+ # .safe {
92
+ # background-color: rgba(0,255,0,0.2);
93
+ # color: #00ff7f;
94
+ # }
95
+ # .bully {
96
+ # background-color: rgba(255,0,0,0.2);
97
+ # color: #ff4b4b;
98
+ # }
99
+ # </style>
100
+ # """,
101
+ # unsafe_allow_html=True
102
+ # )
103
+
104
+ # # ---------------- Load Lottie Animation ----------------
105
+ # with open("Cybersecurity.json", "r") as f:
106
+ # lottie_anim = json.load(f)
107
+
108
+ # # ---------------- Layout ----------------
109
+ # col1, col2 = st.columns([2, 1])
110
+
111
+ # with col1:
112
+ # st.markdown("<div class='title'>Cyberbullying Detection System</div>", unsafe_allow_html=True)
113
+ # st.markdown("<div class='intro-line'>This tool analyzes text messages and helps identify possible cyberbullying patterns.</div>", unsafe_allow_html=True)
114
+
115
+ # with col2:
116
+ # st_lottie(lottie_anim, height=250, key="cyberbully")
117
+
118
+ # # ---------------- Input Section ----------------
119
+ # st.markdown("### Enter a message :")
120
+ # user_input = st.text_area("", "")
121
+
122
+ # # ---------------- Prediction Button ----------------
123
+ # if st.button("🔍 Detect"):
124
+ # if not user_input.strip():
125
+ # st.warning("Please enter some text.")
126
+ # else:
127
+ # results = classifier(user_input)[0]
128
+ # best = max(results, key=lambda x: x['score'])
129
+ # label = best['label']
130
+ # score = best['score']
131
+
132
+ # # Cyberbullying logic
133
+ # if label.lower() == "not_cyberbullying":
134
+ # result = f"<div class='output-box safe'>✅ Safe message (Confidence: {score:.2f})</div>"
135
+ # else:
136
+ # result = f"<div class='output-box bully'>⚠️ Cyberbullying detected ({label})<br>Confidence: {score:.2f}</div>"
137
+
138
+ # st.markdown(result, unsafe_allow_html=True)
139
+
140
+ # # Probability dictionary
141
+ # probs = {r['label']: round(r['score'], 3) for r in results}
142
+ # st.json(probs)
143
+
144
+
145
+ # gradio_app.py
146
+
147
+ import gradio as gr
148
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
149
+ # ---------------- Load Model ----------------
150
+ def load_model():
151
+ model_path = "./models"
152
+ tokenizer = AutoTokenizer.from_pretrained(model_path)
153
+ model = AutoModelForSequenceClassification.from_pretrained(model_path)
154
+ return pipeline(
155
+ "text-classification",
156
+ model=model,
157
+ tokenizer=tokenizer,
158
+ return_all_scores=True
159
+ )
160
+ classifier = load_model()
161
+ # ---------------- Prediction Logic ----------------
162
+ def predict(text):
163
+ if not text.strip():
164
+ return "<div class='warn'>⚠️ Please enter some text.</div>"
165
+ results = classifier(text)[0]
166
+ best = max(results, key=lambda x: x["score"])
167
+ label = best["label"]
168
+ score = best["score"]
169
+ if label.lower() == "not_cyberbullying":
170
+ return f"""
171
+ <div class='safe'>
172
+ <div class='checkmark'>✅</div>
173
+ <div class='safe-text'>Safe Message</div>
174
+ <div class='confidence-bar'>
175
+ <div class='confidence-fill safe-fill' style='width: {score*100}%'></div>
176
+ </div>
177
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
178
+ </div>
179
+ """
180
+ else:
181
+ return f"""
182
+ <div class='bully'>
183
+ <div class='warning-icon'>⚠️</div>
184
+ <div class='bully-text'>Cyberbullying Detected</div>
185
+ <div class='label-badge'>{label}</div>
186
+ <div class='confidence-bar'>
187
+ <div class='confidence-fill bully-fill' style='width: {score*100}%'></div>
188
+ </div>
189
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
190
+ </div>
191
+ """
192
+ # ---------------- UI ----------------
193
+ with gr.Blocks(theme=gr.themes.Soft(), css="""
194
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
195
+
196
+ * {
197
+ margin: 0;
198
+ padding: 0;
199
+ box-sizing: border-box;
200
+ }
201
+
202
+ html, body {
203
+ background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
204
+ background-size: 400% 400%;
205
+ animation: gradientBG 15s ease infinite;
206
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
207
+ min-height: 100vh;
208
+ position: fixed;
209
+ width: 100%;
210
+ height: 100%;
211
+ }
212
+
213
+ @keyframes gradientBG {
214
+ 0% {background-position: 0% 50%;}
215
+ 25% {background-position: 100% 50%;}
216
+ 50% {background-position: 100% 100%;}
217
+ 75% {background-position: 0% 100%;}
218
+ 100% {background-position: 0% 50%;}
219
+ }
220
+
221
+ .gradio-container {
222
+ background: rgba(20, 20, 40, 0.85) !important;
223
+ border-radius: 25px !important;
224
+ box-shadow: 0 25px 80px rgba(0, 0, 0, 0.4), inset 0 0 30px rgba(255, 255, 255, 0.1) !important;
225
+ backdrop-filter: blur(15px) !important;
226
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
227
+ padding: 40px !important;
228
+ }
229
+
230
+ .title {
231
+ font-size: 52px;
232
+ font-weight: 900;
233
+ text-align: center;
234
+ background: linear-gradient(135deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
235
+ -webkit-background-clip: text;
236
+ -webkit-text-fill-color: transparent;
237
+ background-clip: text;
238
+ animation: slideInDown 1s ease-out, glow 3s ease-in-out infinite;
239
+ margin-bottom: 10px;
240
+ text-shadow: 0 0 30px rgba(255, 75, 75, 0.5);
241
+ }
242
+
243
+ @keyframes slideInDown {
244
+ from {
245
+ opacity: 0;
246
+ transform: translateY(-50px);
247
+ }
248
+ to {
249
+ opacity: 1;
250
+ transform: translateY(0);
251
+ }
252
+ }
253
+
254
+ @keyframes glow {
255
+ 0%, 100% {
256
+ text-shadow: 0 0 20px rgba(255, 75, 75, 0.5), 0 0 40px rgba(255, 140, 0, 0.3);
257
+ }
258
+ 50% {
259
+ text-shadow: 0 0 30px rgba(75, 127, 255, 0.6), 0 0 60px rgba(125, 0, 255, 0.4);
260
+ }
261
+ }
262
+
263
+ .subtitle {
264
+ text-align: center;
265
+ color: #e0e0ff;
266
+ margin-bottom: 30px;
267
+ font-style: italic;
268
+ font-size: 16px;
269
+ animation: fadeInUp 1s ease-out 0.2s both;
270
+ letter-spacing: 1px;
271
+ }
272
+
273
+ @keyframes fadeInUp {
274
+ from {
275
+ opacity: 0;
276
+ transform: translateY(30px);
277
+ }
278
+ to {
279
+ opacity: 1;
280
+ transform: translateY(0);
281
+ }
282
+ }
283
+
284
+ /* Input Container */
285
+ .textbox-container {
286
+ animation: scaleIn 0.7s ease-out 0.3s both;
287
+ }
288
+
289
+ @keyframes scaleIn {
290
+ from {
291
+ opacity: 0;
292
+ transform: scale(0.9) rotateX(10deg);
293
+ }
294
+ to {
295
+ opacity: 1;
296
+ transform: scale(1) rotateX(0deg);
297
+ }
298
+ }
299
+
300
+ textarea {
301
+ background: rgba(255, 255, 255, 0.08) !important;
302
+ border: 2px solid rgba(75, 127, 255, 0.3) !important;
303
+ border-radius: 15px !important;
304
+ padding: 18px !important;
305
+ font-size: 16px !important;
306
+ color: #e0e0ff !important;
307
+ transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
308
+ box-shadow: 0 8px 32px rgba(75, 127, 255, 0.1), inset 0 0 20px rgba(255, 255, 255, 0.05) !important;
309
+ backdrop-filter: blur(10px) !important;
310
+ }
311
+
312
+ textarea::placeholder {
313
+ color: rgba(224, 224, 255, 0.5) !important;
314
+ }
315
+
316
+ textarea:focus {
317
+ border-color: #4b7fff !important;
318
+ box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1) !important;
319
+ transform: translateY(-5px) scale(1.02);
320
+ animation: inputGlow 2s ease-in-out infinite;
321
+ }
322
+
323
+ @keyframes inputGlow {
324
+ 0%, 100% {
325
+ box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1);
326
+ }
327
+ 50% {
328
+ box-shadow: 0 20px 60px rgba(125, 0, 255, 0.5), inset 0 0 40px rgba(125, 0, 255, 0.2);
329
+ }
330
+ }
331
+
332
+ /* Button Styling with Ripple Effect */
333
+ .btn-primary {
334
+ background: linear-gradient(135deg, #4b7fff, #7d00ff, #ff4b4b) !important;
335
+ background-size: 300% 300% !important;
336
+ border: 2px solid rgba(75, 127, 255, 0.5) !important;
337
+ color: white !important;
338
+ font-weight: 700 !important;
339
+ font-size: 16px !important;
340
+ padding: 14px 40px !important;
341
+ border-radius: 50px !important;
342
+ cursor: pointer !important;
343
+ transition: all 0.4s ease !important;
344
+ box-shadow: 0 10px 40px rgba(75, 127, 255, 0.4), inset 0 0 20px rgba(255, 255, 255, 0.1) !important;
345
+ animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
346
+ position: relative;
347
+ overflow: hidden;
348
+ }
349
+
350
+ @keyframes bounceIn {
351
+ 0% {
352
+ opacity: 0;
353
+ transform: scale(0.1) rotateZ(-45deg);
354
+ }
355
+ 50% {
356
+ opacity: 1;
357
+ transform: scale(1.1) rotateZ(10deg);
358
+ }
359
+ 100% {
360
+ transform: scale(1) rotateZ(0deg);
361
+ }
362
+ }
363
+
364
+ .btn-primary:hover {
365
+ transform: translateY(-5px) scale(1.05);
366
+ box-shadow: 0 20px 60px rgba(125, 0, 255, 0.6), inset 0 0 30px rgba(255, 255, 255, 0.15) !important;
367
+ background-position: 100% 0 !important;
368
+ animation: gradientShift 3s ease infinite;
369
+ }
370
+
371
+ @keyframes gradientShift {
372
+ 0% {background-position: 0% 50%;}
373
+ 50% {background-position: 100% 50%;}
374
+ 100% {background-position: 0% 50%;}
375
+ }
376
+
377
+ .btn-primary:active {
378
+ transform: translateY(-2px) scale(0.98);
379
+ }
380
+
381
+ /* Ripple Effect */
382
+ .btn-primary::before {
383
+ content: '';
384
+ position: absolute;
385
+ top: 50%;
386
+ left: 50%;
387
+ width: 0;
388
+ height: 0;
389
+ border-radius: 50%;
390
+ background: rgba(255, 255, 255, 0.6);
391
+ transform: translate(-50%, -50%);
392
+ transition: width 0.6s, height 0.6s;
393
+ }
394
+
395
+ .btn-primary:active::before {
396
+ width: 400px;
397
+ height: 400px;
398
+ }
399
+
400
+ /* Result Cards */
401
+ .safe {
402
+ background: linear-gradient(135deg, rgba(0, 255, 100, 0.15), rgba(100, 255, 150, 0.08));
403
+ border: 2px solid rgba(0, 255, 100, 0.4);
404
+ padding: 35px;
405
+ border-radius: 20px;
406
+ color: #00ff64;
407
+ text-align: center;
408
+ animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowGreen 3s ease-in-out infinite;
409
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
410
+ backdrop-filter: blur(15px);
411
+ }
412
+
413
+ .bully {
414
+ background: linear-gradient(135deg, rgba(255, 0, 0, 0.15), rgba(255, 100, 100, 0.08));
415
+ border: 2px solid rgba(255, 107, 107, 0.4);
416
+ padding: 35px;
417
+ border-radius: 20px;
418
+ color: #ff6b6b;
419
+ text-align: center;
420
+ animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowRed 2s ease-in-out infinite;
421
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
422
+ backdrop-filter: blur(15px);
423
+ }
424
+
425
+ @keyframes slideInRight {
426
+ from {
427
+ opacity: 0;
428
+ transform: translateX(100px) rotateY(20deg);
429
+ }
430
+ to {
431
+ opacity: 1;
432
+ transform: translateX(0) rotateY(0deg);
433
+ }
434
+ }
435
+
436
+ @keyframes cardGlowGreen {
437
+ 0%, 100% {
438
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
439
+ }
440
+ 50% {
441
+ box-shadow: 0 30px 80px rgba(0, 255, 100, 0.4), inset 0 0 40px rgba(0, 255, 100, 0.2);
442
+ }
443
+ }
444
+
445
+ @keyframes cardGlowRed {
446
+ 0%, 100% {
447
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
448
+ }
449
+ 50% {
450
+ box-shadow: 0 30px 80px rgba(255, 107, 107, 0.4), inset 0 0 40px rgba(255, 107, 107, 0.2);
451
+ }
452
+ }
453
+
454
+ .warn {
455
+ color: #ffb700;
456
+ text-align: center;
457
+ font-weight: 700;
458
+ font-size: 18px;
459
+ animation: shake 0.5s ease-in-out, pulse 1.5s ease-in-out infinite 0.5s;
460
+ padding: 20px;
461
+ }
462
+
463
+ @keyframes shake {
464
+ 0%, 100% {transform: translateX(0);}
465
+ 10%, 30%, 50%, 70%, 90% {transform: translateX(-8px);}
466
+ 20%, 40%, 60%, 80% {transform: translateX(8px);}
467
+ }
468
+
469
+ @keyframes pulse {
470
+ 0%, 100% {opacity: 1;}
471
+ 50% {opacity: 0.6;}
472
+ }
473
+
474
+ /* Icons */
475
+ .checkmark, .warning-icon {
476
+ font-size: 56px;
477
+ margin-bottom: 15px;
478
+ animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
479
+ display: inline-block;
480
+ }
481
+
482
+ @keyframes bounce {
483
+ 0% {
484
+ opacity: 0;
485
+ transform: scale(0) rotateZ(-45deg);
486
+ }
487
+ 50% {
488
+ transform: scale(1.2) rotateZ(15deg);
489
+ }
490
+ 100% {
491
+ opacity: 1;
492
+ transform: scale(1) rotateZ(0deg);
493
+ }
494
+ }
495
+
496
+ .warning-icon {
497
+ animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), pulse-warning 1.5s ease-in-out 0.8s infinite;
498
+ }
499
+
500
+ @keyframes pulse-warning {
501
+ 0%, 100% {
502
+ transform: scale(1);
503
+ filter: drop-shadow(0 0 5px rgba(255, 107, 107, 0.5));
504
+ }
505
+ 50% {
506
+ transform: scale(1.2);
507
+ filter: drop-shadow(0 0 20px rgba(255, 107, 107, 1));
508
+ }
509
+ }
510
+
511
+ /* Text */
512
+ .safe-text, .bully-text {
513
+ font-size: 28px;
514
+ font-weight: 800;
515
+ margin-bottom: 15px;
516
+ animation: fadeInDown 0.8s ease-out 0.2s both;
517
+ letter-spacing: 0.5px;
518
+ }
519
+
520
+ @keyframes fadeInDown {
521
+ from {
522
+ opacity: 0;
523
+ transform: translateY(-20px);
524
+ }
525
+ to {
526
+ opacity: 1;
527
+ transform: translateY(0);
528
+ }
529
+ }
530
+
531
+ .label-badge {
532
+ display: inline-block;
533
+ background: rgba(255, 107, 107, 0.2);
534
+ border: 2px solid rgba(255, 107, 107, 0.5);
535
+ padding: 10px 20px;
536
+ border-radius: 25px;
537
+ margin-bottom: 18px;
538
+ font-size: 14px;
539
+ font-weight: 700;
540
+ animation: zoomIn 0.7s ease-out 0.3s both;
541
+ box-shadow: 0 5px 20px rgba(255, 107, 107, 0.2);
542
+ }
543
+
544
+ @keyframes zoomIn {
545
+ from {
546
+ opacity: 0;
547
+ transform: scale(0.3);
548
+ }
549
+ to {
550
+ opacity: 1;
551
+ transform: scale(1);
552
+ }
553
+ }
554
+
555
+ /* Confidence Bar */
556
+ .confidence-bar {
557
+ width: 100%;
558
+ height: 10px;
559
+ background: rgba(255, 255, 255, 0.1);
560
+ border-radius: 12px;
561
+ margin-bottom: 15px;
562
+ overflow: hidden;
563
+ animation: fadeIn 0.8s ease-out 0.1s both;
564
+ border: 1px solid rgba(255, 255, 255, 0.2);
565
+ box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3);
566
+ }
567
+
568
+ .confidence-fill {
569
+ height: 100%;
570
+ border-radius: 12px;
571
+ transition: width 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
572
+ animation: fillWidth 1.2s ease-out;
573
+ }
574
+
575
+ @keyframes fillWidth {
576
+ from {
577
+ width: 0 !important;
578
+ }
579
+ }
580
+
581
+ .safe-fill {
582
+ background: linear-gradient(90deg, #00ff64, #00d452, #00ff64);
583
+ background-size: 200% 200%;
584
+ box-shadow: 0 0 25px rgba(0, 255, 100, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
585
+ animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
586
+ }
587
+
588
+ .bully-fill {
589
+ background: linear-gradient(90deg, #ff6b6b, #ff4444, #ff6b6b);
590
+ background-size: 200% 200%;
591
+ box-shadow: 0 0 25px rgba(255, 107, 107, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
592
+ animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
593
+ }
594
+
595
+ @keyframes shimmer {
596
+ 0%, 100% {background-position: 0% 50%;}
597
+ 50% {background-position: 100% 50%;}
598
+ }
599
+
600
+ .confidence-score {
601
+ font-size: 15px;
602
+ opacity: 0.9;
603
+ animation: fadeIn 0.8s ease-out 0.4s both;
604
+ font-weight: 600;
605
+ letter-spacing: 0.5px;
606
+ }
607
+
608
+ @keyframes fadeIn {
609
+ from {
610
+ opacity: 0;
611
+ }
612
+ to {
613
+ opacity: 1;
614
+ }
615
+ }
616
+
617
+ /* Responsive */
618
+ @media (max-width: 768px) {
619
+ .title {
620
+ font-size: 36px;
621
+ }
622
+
623
+ .safe, .bully {
624
+ padding: 25px;
625
+ }
626
+
627
+ html, body {
628
+ background-size: 600% 600%;
629
+ }
630
+ }
631
+ """) as demo:
632
+ gr.Markdown("<div class='title'>🛡️ Cyberbullying Detection System</div>")
633
+ gr.Markdown("<div class='subtitle'>End-to-end NLP system for detecting cyberbullying, including religion-based abuse</div>")
634
+
635
+ with gr.Group():
636
+ text_input = gr.Textbox(
637
+ lines=4,
638
+ placeholder="Enter a message to analyze...",
639
+ label="Input Text",
640
+ elem_classes="textbox-container"
641
+ )
642
+ detect_btn = gr.Button("🔍 Detect", variant="primary")
643
+
644
+ output = gr.HTML()
645
+
646
+ detect_btn.click(
647
+ fn=predict,
648
+ inputs=text_input,
649
+ outputs=output
650
+ )
651
+
652
+ demo.launch()
config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "gelu",
3
+ "architectures": [
4
+ "DistilBertForSequenceClassification"
5
+ ],
6
+ "attention_dropout": 0.1,
7
+ "dim": 768,
8
+ "dropout": 0.1,
9
+ "hidden_dim": 3072,
10
+ "id2label": {
11
+ "0": "age",
12
+ "1": "ethnicity",
13
+ "2": "gender",
14
+ "3": "not_cyberbullying",
15
+ "4": "other_cyberbullying",
16
+ "5": "religion"
17
+ },
18
+ "initializer_range": 0.02,
19
+ "label2id": {
20
+ "age": 0,
21
+ "ethnicity": 1,
22
+ "gender": 2,
23
+ "not_cyberbullying": 3,
24
+ "other_cyberbullying": 4,
25
+ "religion": 5
26
+ },
27
+ "max_position_embeddings": 512,
28
+ "model_type": "distilbert",
29
+ "n_heads": 12,
30
+ "n_layers": 6,
31
+ "pad_token_id": 0,
32
+ "problem_type": "single_label_classification",
33
+ "qa_dropout": 0.1,
34
+ "seq_classif_dropout": 0.2,
35
+ "sinusoidal_pos_embds": false,
36
+ "tie_weights_": true,
37
+ "torch_dtype": "float32",
38
+ "transformers_version": "4.53.3",
39
+ "vocab_size": 30522
40
+ }
label_encoder.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:58d35a74ab441b00df61647ebadbf784cad8d849a048788bed9b19a3b1fd793f
3
+ size 553
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e641cce650040e4a147564cab82b12e7e8260f7d02ff1410399f171a51403ead
3
+ size 267844872
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ numpy
2
+ pandas
3
+ scikit-learn
4
+ torch
5
+ transformers
6
+ datasets
7
+ accelerate
special_tokens_map.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "cls_token": "[CLS]",
3
+ "mask_token": "[MASK]",
4
+ "pad_token": "[PAD]",
5
+ "sep_token": "[SEP]",
6
+ "unk_token": "[UNK]"
7
+ }
tfidf_logreg_best.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:796a2bcd126927b9e0aef0bcc3f85bbb5e36fec7af5e499db011524dcc363708
3
+ size 10399084
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "[PAD]",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "100": {
12
+ "content": "[UNK]",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "101": {
20
+ "content": "[CLS]",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "102": {
28
+ "content": "[SEP]",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "103": {
36
+ "content": "[MASK]",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ }
43
+ },
44
+ "clean_up_tokenization_spaces": false,
45
+ "cls_token": "[CLS]",
46
+ "do_lower_case": true,
47
+ "extra_special_tokens": {},
48
+ "mask_token": "[MASK]",
49
+ "model_max_length": 512,
50
+ "pad_token": "[PAD]",
51
+ "sep_token": "[SEP]",
52
+ "strip_accents": null,
53
+ "tokenize_chinese_chars": true,
54
+ "tokenizer_class": "DistilBertTokenizer",
55
+ "unk_token": "[UNK]"
56
+ }
training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cf2f784b7e538494e42c73130341a5dab79b4b13041d7e2bcc4e1ced3397ffe0
3
+ size 5304
vocab.txt ADDED
The diff for this file is too large to render. See raw diff