hari6677 commited on
Commit
e851d90
·
verified ·
1 Parent(s): 9cb2776

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -0
app.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import pandas as pd
4
+ import tensorflow as tf
5
+ import joblib
6
+ import json
7
+
8
+ # --- 1. CONFIGURATION AND FILE LOADING ---
9
+
10
+ # Load the saved model, scaler, feature names, and categorical map
11
+ try:
12
+ # Load Model
13
+ model = tf.keras.models.load_model('improved_intrusion_detection_model.h5')
14
+
15
+ # Load Preprocessing Objects
16
+ scaler = joblib.load('kdd_scaler_StandardScaler.joblib')
17
+
18
+ with open('kdd_41_original_feature_names.json', 'r') as f:
19
+ FEATURE_NAMES = json.load(f)
20
+
21
+ with open('kdd_categorical_unique_values.json', 'r') as f:
22
+ CATEGORICAL_MAPPING = json.load(f)
23
+
24
+ except FileNotFoundError as e:
25
+ print(f"Error loading required file: {e}. Ensure all files are in the same directory.")
26
+ raise
27
+
28
+ # Define categorical and numerical feature names/indices based on the mapping
29
+ CATEGORICAL_COLS = list(CATEGORICAL_MAPPING.keys())
30
+ NUMERICAL_COLS = [col for col in FEATURE_NAMES if col not in CATEGORICAL_COLS]
31
+
32
+ # Determine the final column order after preprocessing
33
+ # This order must match the training data: Numerical + One-Hot Encoded
34
+ FINAL_COLUMNS = NUMERICAL_COLS
35
+ for col in CATEGORICAL_COLS:
36
+ for value in CATEGORICAL_MAPPING[col]:
37
+ FINAL_COLUMNS.append(f'{col}_{value}')
38
+
39
+ # --- 2. PREDICTION FUNCTION ---
40
+
41
+ def predict_attack(*raw_input_values):
42
+ """
43
+ Processes the 41 raw user inputs, prepares them for the model, and returns a prediction.
44
+ """
45
+ if len(raw_input_values) != len(FEATURE_NAMES):
46
+ return "Input Error: Expected 41 features, received {len(raw_input_values)}."
47
+
48
+ # 1. Create a raw DataFrame from the user input
49
+ raw_df = pd.DataFrame([raw_input_values], columns=FEATURE_NAMES)
50
+
51
+ # Ensure numerical columns are numeric type (Gradio gives strings)
52
+ for col in NUMERICAL_COLS:
53
+ # Graceful handling for non-numeric input
54
+ try:
55
+ raw_df[col] = pd.to_numeric(raw_df[col])
56
+ except ValueError:
57
+ return f"Input Error: Non-numeric value detected in column: {col}"
58
+
59
+ # 2. One-Hot Encoding for Categorical Columns
60
+ df_encoded = raw_df.copy()
61
+ for col, unique_values in CATEGORICAL_MAPPING.items():
62
+ # Create a temporary DataFrame for OHE, with columns for every known value
63
+ ohe_temp = pd.DataFrame(0, index=df_encoded.index, columns=[f'{col}_{val}' for val in unique_values])
64
+
65
+ # Set the correct column to 1 based on user's input value
66
+ user_value = df_encoded[col].iloc[0]
67
+ ohe_col_name = f'{col}_{user_value}'
68
+ if ohe_col_name in ohe_temp.columns:
69
+ ohe_temp[ohe_col_name] = 1
70
+
71
+ # Drop the original column and concatenate the new OHE columns
72
+ df_encoded = df_encoded.drop(columns=[col])
73
+ df_encoded = pd.concat([df_encoded, ohe_temp], axis=1)
74
+
75
+ # 3. Align and Reorder Features
76
+ # The final DataFrame must contain all 119 columns in the exact order as the FINAL_COLUMNS list
77
+ # Use reindex to add missing OHE columns (set to 0) and reorder
78
+ X_processed = df_encoded.reindex(columns=FINAL_COLUMNS, fill_value=0)
79
+
80
+ # Convert to NumPy array for scaling
81
+ X_array = X_processed.values.astype(np.float32)
82
+
83
+ # 4. Standard Scaling
84
+ X_scaled = scaler.transform(X_array)
85
+
86
+ # 5. Reshape for CNN (1, 119, 1)
87
+ X_cnn = X_scaled.reshape((1, X_scaled.shape[1], 1))
88
+
89
+ # 6. Predict
90
+ prediction = model.predict(X_cnn, verbose=0)
91
+
92
+ # Apply threshold and determine result
93
+ # Output is a single value probability (0 to 1)
94
+ probability = prediction[0][0]
95
+
96
+ if probability > 0.5:
97
+ result = f"🚨 ATTACK DETECTED! (Confidence: {probability:.2f})"
98
+ color = "red"
99
+ else:
100
+ result = f"✅ Normal Traffic (Confidence: {1 - probability:.2f})"
101
+ color = "green"
102
+
103
+ # HTML formatting for colored output in Gradio
104
+ return f'<h1 style="color:{color}; font-size:24px;">{result}</h1>'
105
+
106
+ # --- 3. GRADIO INTERFACE SETUP ---
107
+
108
+ # Create 41 Gradio Input Components (Textboxes for simplicity)
109
+ input_components = []
110
+ for name in FEATURE_NAMES:
111
+ if name in NUMERICAL_COLS:
112
+ # Use Number component for better input validation/type enforcement
113
+ input_components.append(gr.Number(label=name, value=0))
114
+ elif name in CATEGORICAL_COLS:
115
+ # Use Dropdown for categorical features
116
+ input_components.append(gr.Dropdown(
117
+ label=name,
118
+ choices=CATEGORICAL_MAPPING[name],
119
+ value=CATEGORICAL_MAPPING[name][0]
120
+ ))
121
+ else:
122
+ # Fallback for unexpected case
123
+ input_components.append(gr.Textbox(label=name, value="0"))
124
+
125
+ # Gradio Interface
126
+ iface = gr.Interface(
127
+ fn=predict_attack,
128
+ inputs=input_components,
129
+ outputs=gr.HTML(label="Prediction Result"), # Use HTML component to render colored text
130
+ title="Intrusion Detection System (KDD/NSL-KDD CNN)",
131
+ description="Enter the 41 feature values of a network connection to detect if it is an attack or normal traffic. Use the attack patterns provided (e.g., Neptune DoS) to test the model."
132
+ )
133
+
134
+ # Launch the app
135
+ if __name__ == "__main__":
136
+ iface.launch()