Spaces:
Sleeping
Sleeping
| # ================================ | |
| # 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() | |