kodetr commited on
Commit
2b30b0d
·
verified ·
1 Parent(s): 1cec16e

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +339 -37
src/streamlit_app.py CHANGED
@@ -1,40 +1,342 @@
1
  import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
1
  import altair as alt
 
 
2
  import streamlit as st
3
+ from streamlit_option_menu import option_menu
4
+ import streamlit.components.v1 as html
5
+ from PIL import Image
6
+ import sys
7
+ import os
8
+ import re
9
+ import streamlit as st
10
+ import pandas as pd
11
+ import numpy as np
12
+
13
+ import tensorflow as tf
14
+ # print(tf.__version__)
15
+
16
+ import matplotlib.pyplot as plt
17
+ import seaborn as sns
18
+ from tensorflow.keras import callbacks
19
+ from tensorflow.keras.models import Sequential
20
+ from tensorflow.keras.layers import Conv1D, MaxPooling1D, Embedding, Dense, Dropout, GlobalMaxPooling1D
21
+ from tensorflow.keras.preprocessing.text import Tokenizer
22
+ from tensorflow.keras.preprocessing.sequence import pad_sequences
23
+ from tensorflow.keras.regularizers import l2
24
+ from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
25
+ from sklearn.model_selection import train_test_split
26
+ from sklearn.preprocessing import LabelEncoder
27
+ from imblearn.over_sampling import SMOTE
28
+ from PIL import Image
29
+
30
+ os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # -1 CPU | 0 GPU
31
+
32
+ # Set seed untuk reproduksibilitas
33
+ np.random.seed(42)
34
+ tf.random.set_seed(42)
35
+
36
+ class RealTimeLogger(callbacks.Callback):
37
+ def __init__(self, container, epochs):
38
+ super().__init__()
39
+ self.container = container
40
+ self.epochs = epochs
41
+
42
+ def on_epoch_end(self, epoch, logs=None):
43
+ logs = logs or {}
44
+ # Format log text dengan alignment
45
+ log_text = (
46
+ f"Epoch {epoch+1:03d}/{self.epochs:03d} | "
47
+ f"Loss: {logs.get('loss', 0):.4f} | "
48
+ f"Acc: {logs.get('accuracy', 0):.4f} | "
49
+ f"Val Loss: {logs.get('val_loss', 0):.4f} | "
50
+ f"Val Acc: {logs.get('val_accuracy', 0):.4f}\n"
51
+ )
52
+
53
+ # Update session state
54
+ if 'training_logs' not in st.session_state:
55
+ st.session_state.training_logs = []
56
+
57
+ st.session_state.training_logs.insert(0, log_text)
58
+
59
+ # Update tampilan real-time
60
+ with self.container:
61
+ st.subheader("Training Logs")
62
+ st.code(
63
+ "".join(st.session_state.training_logs[-100:]), # Batasi 100 line terakhir
64
+ language="log",
65
+ line_numbers=True
66
+ )
67
+
68
+ def clean_text(text):
69
+ text = text.lower()
70
+ text = re.sub(r'[^a-zA-Z0-9\s]', '', text)
71
+ return text
72
+
73
+ def load_data(file):
74
+ lines = file.getvalue().decode("utf-8").splitlines()
75
+ data, labels, bandwidth = [], [], []
76
+ for line in lines:
77
+ line = clean_text(line.strip())
78
+ if "fake bandwidth" in line:
79
+ labels.append("Fake")
80
+ match = re.search(r'(\d+)', line)
81
+ bandwidth.append(int(match.group()) if match else 0)
82
+ elif "genuine bandwidth" in line:
83
+ labels.append("Genuine")
84
+ match = re.search(r'(\d+)', line)
85
+ bandwidth.append(int(match.group()) if match else 0)
86
+ elif "no heavy activity" in line:
87
+ labels.append("No Heavy")
88
+ bandwidth.append(0)
89
+ else:
90
+ continue
91
+ data.append(line)
92
+ return data, labels, bandwidth
93
+
94
+ def preprocess_text(texts):
95
+ tokenizer = Tokenizer(num_words=10000, oov_token="<OOV>")
96
+ tokenizer.fit_on_texts(texts)
97
+ sequences = tokenizer.texts_to_sequences(texts)
98
+ padded_sequences = pad_sequences(sequences, maxlen=100, padding='post')
99
+ return tokenizer, padded_sequences
100
+
101
+ def build_cnn_model(input_length, num_classes=3, num_words=10000, embedding_dim=240):
102
+ model = Sequential([
103
+ # Perbaikan: Hapus parameter input_length dari Embedding
104
+ Embedding(num_words, embedding_dim),
105
+ Conv1D(256, 3, activation='relu', kernel_regularizer=l2(0.01)),
106
+ MaxPooling1D(3),
107
+ Conv1D(128, 3, activation='relu', kernel_regularizer=l2(0.01)),
108
+ MaxPooling1D(3),
109
+ Conv1D(64, 3, activation='relu', kernel_regularizer=l2(0.01)),
110
+ MaxPooling1D(3),
111
+ GlobalMaxPooling1D(),
112
+ Dense(128, activation='relu', kernel_regularizer=l2(0.01)),
113
+ Dropout(0.5),
114
+ Dense(num_classes, activation='softmax')
115
+ ])
116
+ model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
117
+ return model
118
+
119
+
120
+ #----------------------------------------------------------------------------------------------------
121
+ # Sidebar
122
+ #----------------------------------------------------------------------------------------------------
123
+ with st.sidebar:
124
+ choose = option_menu("Brandwidth", ["ABOUT", "CNN", "GRU", "LSTM", "COMBINE"],
125
+ icons=['person-circle', 'bar-chart-steps', 'activity', 'calendar-week','transparency'],
126
+ menu_icon="router", default_index=0,
127
+ styles={
128
+ "container": {"padding": "5!important", "background-color": "#fafafa"},
129
+ "icon": {"color": "black", "font-size": "25px"},
130
+ "nav-link": {"font-size": "16px", "text-align": "left", "margin":"0px", "--hover-color": "#eee"},
131
+ "nav-link-selected": {"background-color": "#02ab21"},
132
+ }
133
+ )
134
+
135
+ #----------------------------------------------------------------------------------------------------
136
+ # ABOUT
137
+ #----------------------------------------------------------------------------------------------------
138
+ # image_about = Image.open(r'/teamspace/studios/this_studio/icons/datamining.jpg')
139
+ if choose == "ABOUT":
140
+
141
+ col1, col2 = st.columns( [0.8, 0.2])
142
+ with col1:
143
+ st.markdown(
144
+ """ <style> .font {
145
+ font-size:35px ; color: #000000; font-weight: bold;}
146
+
147
+ .custom-text {
148
+ font-size: 18px;
149
+ text-align: justify;
150
+ color: #000000;
151
+ }
152
+ </style> """, unsafe_allow_html=True)
153
+ st.markdown('<p class="font">ABOUT</p>', unsafe_allow_html=True)
154
+
155
+ # with col2:
156
+ # st.markdown("## 🧠")
157
+
158
+ st.write('<p class="custom-text">Saya adalah seorang peneliti dan pengembang di bidang ilmu komputer yang memiliki fokus pada pemrosesan data dan pengklasifikasian bandwidth jaringan menggunakan pendekatan combine classification. Dalam pekerjaan saya, saya menggabungkan berbagai algoritma machine learning untuk meningkatkan akurasi dalam klasifikasi bandwidth, termasuk algoritma seperti Decision Tree, Random Forest, SVM, dan K-Nearest Neighbors., please visit website at: https://kodetr.com</p>', unsafe_allow_html=True)
159
+ # st.image(image_about, width=700)
160
+
161
+ #----------------------------------------------------------------------------------------------------
162
+ # CNN
163
+ #----------------------------------------------------------------------------------------------------
164
+
165
+ elif choose == "CNN":
166
+
167
+ st.title("Klasifikasi Bandwidth dengan CNN")
168
+ st.write("Aplikasi ini menggunakan model CNN untuk mengklasifikasikan data bandwidth menjadi Fake, Genuine, atau No Heavy Activity")
169
+
170
+ # Upload file
171
+ training_file = st.file_uploader("Upload Data Training (.txt)", type=["txt"])
172
+ real_files = st.file_uploader("Upload Data Real (.txt)", type=["txt"], accept_multiple_files=True)
173
+
174
+ # Parameter model
175
+ epochs = st.number_input("Jumlah Epoch", min_value=1, value=2000)
176
+ batch_size = st.number_input("Ukuran Batch", min_value=1, value=32)
177
+
178
+ if st.button("Proses Data"):
179
+ if training_file and real_files:
180
+ # Memproses data training
181
+ try:
182
+ data_train, labels_train, bandwidth_train = load_data(training_file)
183
+ if len(data_train) == 0:
184
+ st.error("Data training tidak valid atau kosong!")
185
+ st.stop()
186
+
187
+ # Preprocessing
188
+ tokenizer, X_train = preprocess_text(data_train)
189
+ le = LabelEncoder()
190
+ labels_encoded = le.fit_transform(labels_train)
191
+
192
+ # Split data
193
+ X_train, X_test, y_train, y_test, bw_train, bw_test = train_test_split(
194
+ X_train, labels_encoded, bandwidth_train,
195
+ test_size=0.2, stratify=labels_encoded, random_state=42
196
+ )
197
+
198
+ # SMOTE
199
+ smote = SMOTE(random_state=42)
200
+ X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)
201
+
202
+ # Konversi ke kategorikal
203
+ y_train_cat = tf.keras.utils.to_categorical(y_train_smote, num_classes=3)
204
+ y_test_cat = tf.keras.utils.to_categorical(y_test, num_classes=3)
205
+
206
+ if 'training_progress' not in st.session_state:
207
+ st.session_state.training_progress = []
208
+
209
+ # Buat container untuk live update
210
+ live_container = st.empty()
211
+
212
+ # Membangun dan melatih model
213
+ model = build_cnn_model(X_train.shape[1])
214
+ early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
215
+ reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.5, verbose=1)
216
+
217
+ history = model.fit(
218
+ X_train_smote, y_train_cat,
219
+ epochs=epochs,
220
+ batch_size=batch_size,
221
+ validation_data=(X_test, y_test_cat),
222
+ # callbacks=[early_stop, reduce_lr],
223
+ # verbose=2
224
+ callbacks=[
225
+ EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True),
226
+ ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.5, verbose=0),
227
+ RealTimeLogger(live_container, epochs)
228
+ ],
229
+ verbose=0
230
+ )
231
+ # Tampilkan grafik training history
232
+ st.subheader("📈 Grafik Hasil Training")
233
+
234
+ # Buat layout 2 kolom
235
+ col1, col2 = st.columns(2)
236
+
237
+ with col1:
238
+ # Grafik Loss
239
+ fig, ax = plt.subplots(figsize=(10, 5))
240
+ ax.plot(history.history['loss'], label='Training Loss', color='#FF4B4B', linewidth=2)
241
+ ax.plot(history.history['val_loss'], label='Validation Loss', color='#0068C9', linewidth=2)
242
+ ax.set_title('Perkembangan Loss', fontsize=14)
243
+ ax.set_xlabel('Epoch', fontsize=12)
244
+ ax.set_ylabel('Loss', fontsize=12)
245
+ ax.grid(True, alpha=0.3)
246
+ ax.legend()
247
+ st.pyplot(fig)
248
+
249
+ with col2:
250
+ # Grafik Accuracy
251
+ fig, ax = plt.subplots(figsize=(10, 5))
252
+ ax.plot(history.history['accuracy'], label='Training Accuracy', color='#00D154', linewidth=2)
253
+ ax.plot(history.history['val_accuracy'], label='Validation Accuracy', color='#FF922B', linewidth=2)
254
+ ax.set_title('Perkembangan Accuracy', fontsize=14)
255
+ ax.set_xlabel('Epoch', fontsize=12)
256
+ ax.set_ylabel('Accuracy', fontsize=12)
257
+ ax.grid(True, alpha=0.3)
258
+ ax.legend()
259
+ st.pyplot(fig)
260
+
261
+ # Evaluasi
262
+ loss, acc = model.evaluate(X_test, y_test_cat, verbose=0)
263
+ st.success(f"Akurasi Model: {acc*100:.2f}%")
264
+
265
+ # Memproses data real
266
+ data_real, labels_real, bandwidth_real = [], [], []
267
+ for file in real_files:
268
+ d, lbl, bw = load_data(file)
269
+ data_real.extend(d)
270
+ labels_real.extend(lbl)
271
+ bandwidth_real.extend(bw)
272
+
273
+ # Menghitung statistik
274
+ fake = labels_real.count('Fake')
275
+ genuine = labels_real.count('Genuine')
276
+ no_heavy = labels_real.count('No Heavy')
277
+ total = len(labels_real)
278
+
279
+ # Visualisasi
280
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
281
+
282
+ # Pie chart
283
+ ax1.pie([fake, genuine, no_heavy],
284
+ labels=['Fake', 'Genuine', 'No Heavy'],
285
+ autopct='%1.1f%%')
286
+ ax1.set_title('Distribusi Kategori Bandwidth')
287
+
288
+ # Bar plot bandwidth
289
+ avg_bw = [
290
+ np.mean([bw for lbl, bw in zip(labels_real, bandwidth_real) if lbl == 'Fake'] or [0]),
291
+ np.mean([bw for lbl, bw in zip(labels_real, bandwidth_real) if lbl == 'Genuine'] or [0]),
292
+ 0
293
+ ]
294
+ ax2.bar(['Fake', 'Genuine', 'No Heavy'], avg_bw)
295
+ ax2.set_title('Rata-rata Bandwidth per Kategori')
296
+ ax2.set_ylabel('Mbps')
297
+
298
+ st.pyplot(fig)
299
+
300
+ # Tampilkan statistik
301
+ st.subheader("Statistik Data Real:")
302
+ st.write(f"Total Data: {total}")
303
+ st.write(f"Fake Bandwidth: {fake} ({fake/total*100:.2f}%)")
304
+ st.write(f"Genuine Bandwidth: {genuine} ({genuine/total*100:.2f}%)")
305
+ st.write(f"No Heavy Activity: {no_heavy} ({no_heavy/total*100:.2f}%)")
306
+
307
+ except Exception as e:
308
+ st.error(f"Terjadi kesalahan: {str(e)}")
309
+ else:
310
+ st.warning("Harap upload file training dan file real terlebih dahulu!")
311
+
312
+ #----------------------------------------------------------------------------------------------------
313
+ # GRU
314
+ #----------------------------------------------------------------------------------------------------
315
+
316
+ elif choose == "GRU":
317
+ st.title("Klasifikasi Bandwidth dengan GRU")
318
+
319
+ # st.markdown('Design GRU')
320
+
321
+
322
+
323
+ #----------------------------------------------------------------------------------------------------
324
+ # LSTM
325
+ #----------------------------------------------------------------------------------------------------
326
+
327
+ elif choose == "LSTM":
328
+ st.title("Klasifikasi Bandwidth dengan LSTM")
329
+
330
+ # st.subheader('Test 123')
331
+ # st.markdown('Design LSTM')
332
+
333
+
334
+ #----------------------------------------------------------------------------------------------------
335
+ # Combine
336
+ #----------------------------------------------------------------------------------------------------
337
+
338
+ elif choose == "COMBINE":
339
+ st.title("Klasifikasi Bandwidth dengan COMBINE")
340
 
341
+ # st.subheader('Test 123')
342
+ # st.markdown('Design LSTM')