File size: 2,949 Bytes
1f15521
 
 
 
fb84e9f
5a10e97
1f15521
f63b67c
 
 
090478d
 
 
6e6bbac
771e5b4
090478d
f63b67c
5a10e97
f63b67c
fb84e9f
5a10e97
fb84e9f
 
 
f63b67c
 
5a10e97
f63b67c
fb84e9f
5a10e97
f63b67c
45a038c
b2c601f
f63b67c
5a10e97
f63b67c
fb84e9f
 
 
b2c601f
f63b67c
45a038c
f63b67c
 
 
 
 
5a10e97
 
f63b67c
45a038c
 
 
fb84e9f
 
f63b67c
 
5a10e97
 
 
fb84e9f
5a10e97
f63b67c
 
fb84e9f
f63b67c
090478d
 
45a038c
 
 
 
fb84e9f
45a038c
090478d
 
 
 
771e5b4
090478d
f63b67c
771e5b4
 
 
 
f63b67c
 
 
5a10e97
f63b67c
5a10e97
090478d
f63b67c
 
45a038c
 
1f15521
5a10e97
 
f63b67c
fb84e9f
5a10e97
45a038c
5a10e97
1f15521
5a10e97
090478d
 
5a10e97
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
# ================================
# ENVIRONMENT (MUST BE FIRST)
# ================================
import os
os.environ["KERAS_BACKEND"] = "tensorflow"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

# ================================
# IMPORTS
# ================================
import gradio as gr
import tensorflow as tf
import numpy as np
from PIL import Image
from tensorflow.keras.preprocessing.text import tokenizer_from_json

# ================================
# LOAD MODEL (.keras β†’ Keras 3 SAFE)
# ================================
model = tf.keras.models.load_model(
    "fusion_ticket_model_final.keras",
    compile=False
)
print("βœ… Model loaded")

# ================================
# LOAD TOKENIZER (JSON – CORRECT WAY)
# ================================
with open("tokenizer.json", "r", encoding="utf-8") as f:
    tokenizer = tokenizer_from_json(f.read())

print("βœ… Tokenizer loaded")

# ================================
# CONSTANTS (MUST MATCH TRAINING)
# ================================
IMG_SIZE = (128, 128)
MAX_LEN = 50
LABELS = ["Critical", "High", "Medium", "Low"]

# ================================
# IMAGE PREPROCESSING
# ================================
def preprocess_image(image: Image.Image):
    image = image.convert("RGB")
    image = image.resize(IMG_SIZE)
    img = np.array(image, dtype=np.float32) / 255.0
    img = np.expand_dims(img, axis=0)
    return img

# ================================
# TEXT PREPROCESSING
# ================================
def preprocess_text(text):
    if not text:
        text = ""
    seq = tokenizer.texts_to_sequences([text])
    padded = tf.keras.preprocessing.sequence.pad_sequences(
        seq,
        maxlen=MAX_LEN
    )
    return padded

# ================================
# PREDICTION FUNCTION
# ================================
def predict_ticket(image, text):
    if image is None:
        return {
            "Critical": 0.0,
            "High": 0.0,
            "Medium": 0.0,
            "Low": 0.0,
        }

    img = preprocess_image(image)
    txt = preprocess_text(text)

    probs = model.predict([img, txt], verbose=0)[0]

    return {
        "Critical": float(probs[0]),
        "High": float(probs[1]),
        "Medium": float(probs[2]),
        "Low": float(probs[3]),
    }

# ================================
# GRADIO UI
# ================================
interface = gr.Interface(
    fn=predict_ticket,
    inputs=[
        gr.Image(type="pil", label="πŸ“€ Upload Ticket Screenshot"),
        gr.Textbox(
            lines=4,
            placeholder="Describe the issue (recommended)",
            label="✍️ Ticket Description"
        )
    ],
    outputs=gr.Label(num_top_classes=4, label="🚨 Predicted Severity"),
    title="🎫 Ticket Severity Classification",
    description=(
        "CNN + NLP **Fusion Model** that predicts ticket urgency.\n\n"
        "**Classes:** Critical | High | Medium | Low"
    )
)

interface.launch()