import altair as alt import streamlit as st from streamlit_option_menu import option_menu import streamlit.components.v1 as html from PIL import Image import sys import os import re import pandas as pd import numpy as np import tensorflow as tf # print(tf.__version__) import matplotlib.pyplot as plt import seaborn as sns from tensorflow.keras import callbacks from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv1D, MaxPooling1D, Embedding, Dense, Dropout, GlobalMaxPooling1D from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.regularizers import l2 from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from imblearn.over_sampling import SMOTE from PIL import Image os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # -1 CPU | 0 GPU # Set seed untuk reproduksibilitas np.random.seed(42) tf.random.set_seed(42) class RealTimeLogger(callbacks.Callback): def __init__(self, container, epochs): super().__init__() self.container = container self.epochs = epochs def on_epoch_end(self, epoch, logs=None): logs = logs or {} # Format log text dengan alignment log_text = ( f"Epoch {epoch+1:03d}/{self.epochs:03d} | " f"Loss: {logs.get('loss', 0):.4f} | " f"Acc: {logs.get('accuracy', 0):.4f} | " f"Val Loss: {logs.get('val_loss', 0):.4f} | " f"Val Acc: {logs.get('val_accuracy', 0):.4f}\n" ) # Update session state if 'training_logs' not in st.session_state: st.session_state.training_logs = [] st.session_state.training_logs.insert(0, log_text) # Update tampilan real-time with self.container: st.subheader("Training Logs") st.code( "".join(st.session_state.training_logs[-100:]), # Batasi 100 line terakhir language="log", line_numbers=True ) def clean_text(text): text = text.lower() text = re.sub(r'[^a-zA-Z0-9\s]', '', text) return text def load_data(file): lines = file.getvalue().decode("utf-8").splitlines() data, labels, bandwidth = [], [], [] for line in lines: line = clean_text(line.strip()) if "fake bandwidth" in line: labels.append("Fake") match = re.search(r'(\d+)', line) bandwidth.append(int(match.group()) if match else 0) elif "genuine bandwidth" in line: labels.append("Genuine") match = re.search(r'(\d+)', line) bandwidth.append(int(match.group()) if match else 0) elif "no heavy activity" in line: labels.append("No Heavy") bandwidth.append(0) else: continue data.append(line) return data, labels, bandwidth def preprocess_text(texts): tokenizer = Tokenizer(num_words=10000, oov_token="") tokenizer.fit_on_texts(texts) sequences = tokenizer.texts_to_sequences(texts) padded_sequences = pad_sequences(sequences, maxlen=100, padding='post') return tokenizer, padded_sequences def build_cnn_model(input_length, num_classes=3, num_words=10000, embedding_dim=240): model = Sequential([ # Perbaikan: Hapus parameter input_length dari Embedding Embedding(num_words, embedding_dim), Conv1D(256, 3, activation='relu', kernel_regularizer=l2(0.01)), MaxPooling1D(3), Conv1D(128, 3, activation='relu', kernel_regularizer=l2(0.01)), MaxPooling1D(3), Conv1D(64, 3, activation='relu', kernel_regularizer=l2(0.01)), MaxPooling1D(3), GlobalMaxPooling1D(), Dense(128, activation='relu', kernel_regularizer=l2(0.01)), Dropout(0.5), Dense(num_classes, activation='softmax') ]) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) return model #---------------------------------------------------------------------------------------------------- # Sidebar #---------------------------------------------------------------------------------------------------- with st.sidebar: choose = option_menu("Brandwidth", ["ABOUT", "CNN", "GRU", "LSTM", "COMBINE"], icons=['person-circle', 'bar-chart-steps', 'activity', 'calendar-week','transparency'], menu_icon="router", default_index=0, styles={ "container": {"padding": "5!important", "background-color": "#fafafa"}, "icon": {"color": "black", "font-size": "25px"}, "nav-link": {"font-size": "16px", "text-align": "left", "margin":"0px", "--hover-color": "#eee"}, "nav-link-selected": {"background-color": "#02ab21"}, } ) #---------------------------------------------------------------------------------------------------- # ABOUT #---------------------------------------------------------------------------------------------------- # image_about = Image.open(r'/teamspace/studios/this_studio/icons/datamining.jpg') if choose == "ABOUT": col1, col2 = st.columns( [0.8, 0.2]) with col1: st.markdown( """ """, unsafe_allow_html=True) st.markdown('

ABOUT

', unsafe_allow_html=True) # with col2: # st.markdown("## 🧠") st.write('

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

', unsafe_allow_html=True) # st.image(image_about, width=700) #---------------------------------------------------------------------------------------------------- # CNN #---------------------------------------------------------------------------------------------------- elif choose == "CNN": st.title("Klasifikasi Bandwidth dengan CNN") st.write("Aplikasi ini menggunakan model CNN untuk mengklasifikasikan data bandwidth menjadi Fake, Genuine, atau No Heavy Activity") # Upload file training_file = st.file_uploader("Upload Data Training (.txt)", type=["txt"], accept_multiple_files=True) real_files = st.file_uploader("Upload Data Real (.txt)", type=["txt"], accept_multiple_files=True) # Parameter model epochs = st.number_input("Jumlah Epoch", min_value=1, value=2000) batch_size = st.number_input("Ukuran Batch", min_value=1, value=32) if st.button("Proses Data"): if training_file and real_files: # Memproses data training try: data_train, labels_train, bandwidth_train = load_data(training_file) if len(data_train) == 0: st.error("Data training tidak valid atau kosong!") st.stop() # Preprocessing tokenizer, X_train = preprocess_text(data_train) le = LabelEncoder() labels_encoded = le.fit_transform(labels_train) # Split data X_train, X_test, y_train, y_test, bw_train, bw_test = train_test_split( X_train, labels_encoded, bandwidth_train, test_size=0.2, stratify=labels_encoded, random_state=42 ) # SMOTE smote = SMOTE(random_state=42) X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train) # Konversi ke kategorikal y_train_cat = tf.keras.utils.to_categorical(y_train_smote, num_classes=3) y_test_cat = tf.keras.utils.to_categorical(y_test, num_classes=3) if 'training_progress' not in st.session_state: st.session_state.training_progress = [] # Buat container untuk live update live_container = st.empty() # Membangun dan melatih model model = build_cnn_model(X_train.shape[1]) early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.5, verbose=1) history = model.fit( X_train_smote, y_train_cat, epochs=epochs, batch_size=batch_size, validation_data=(X_test, y_test_cat), # callbacks=[early_stop, reduce_lr], # verbose=2 callbacks=[ EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True), ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.5, verbose=0), RealTimeLogger(live_container, epochs) ], verbose=0 ) # Tampilkan grafik training history st.subheader("📈 Grafik Hasil Training") # Buat layout 2 kolom col1, col2 = st.columns(2) with col1: # Grafik Loss fig, ax = plt.subplots(figsize=(10, 5)) ax.plot(history.history['loss'], label='Training Loss', color='#FF4B4B', linewidth=2) ax.plot(history.history['val_loss'], label='Validation Loss', color='#0068C9', linewidth=2) ax.set_title('Perkembangan Loss', fontsize=14) ax.set_xlabel('Epoch', fontsize=12) ax.set_ylabel('Loss', fontsize=12) ax.grid(True, alpha=0.3) ax.legend() st.pyplot(fig) with col2: # Grafik Accuracy fig, ax = plt.subplots(figsize=(10, 5)) ax.plot(history.history['accuracy'], label='Training Accuracy', color='#00D154', linewidth=2) ax.plot(history.history['val_accuracy'], label='Validation Accuracy', color='#FF922B', linewidth=2) ax.set_title('Perkembangan Accuracy', fontsize=14) ax.set_xlabel('Epoch', fontsize=12) ax.set_ylabel('Accuracy', fontsize=12) ax.grid(True, alpha=0.3) ax.legend() st.pyplot(fig) # Evaluasi loss, acc = model.evaluate(X_test, y_test_cat, verbose=0) st.success(f"Akurasi Model: {acc*100:.2f}%") # Memproses data real data_real, labels_real, bandwidth_real = [], [], [] for file in real_files: d, lbl, bw = load_data(file) data_real.extend(d) labels_real.extend(lbl) bandwidth_real.extend(bw) # Menghitung statistik fake = labels_real.count('Fake') genuine = labels_real.count('Genuine') no_heavy = labels_real.count('No Heavy') total = len(labels_real) # Visualisasi fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6)) # Pie chart ax1.pie([fake, genuine, no_heavy], labels=['Fake', 'Genuine', 'No Heavy'], autopct='%1.1f%%') ax1.set_title('Distribusi Kategori Bandwidth') # Bar plot bandwidth avg_bw = [ np.mean([bw for lbl, bw in zip(labels_real, bandwidth_real) if lbl == 'Fake'] or [0]), np.mean([bw for lbl, bw in zip(labels_real, bandwidth_real) if lbl == 'Genuine'] or [0]), 0 ] ax2.bar(['Fake', 'Genuine', 'No Heavy'], avg_bw) ax2.set_title('Rata-rata Bandwidth per Kategori') ax2.set_ylabel('Mbps') st.pyplot(fig) # Tampilkan statistik st.subheader("Statistik Data Real:") st.write(f"Total Data: {total}") st.write(f"Fake Bandwidth: {fake} ({fake/total*100:.2f}%)") st.write(f"Genuine Bandwidth: {genuine} ({genuine/total*100:.2f}%)") st.write(f"No Heavy Activity: {no_heavy} ({no_heavy/total*100:.2f}%)") except Exception as e: st.error(f"Terjadi kesalahan: {str(e)}") else: st.warning("Harap upload file training dan file real terlebih dahulu!") #---------------------------------------------------------------------------------------------------- # GRU #---------------------------------------------------------------------------------------------------- elif choose == "GRU": st.title("Klasifikasi Bandwidth dengan GRU") # st.markdown('Design GRU') #---------------------------------------------------------------------------------------------------- # LSTM #---------------------------------------------------------------------------------------------------- elif choose == "LSTM": st.title("Klasifikasi Bandwidth dengan LSTM") # st.subheader('Test 123') # st.markdown('Design LSTM') #---------------------------------------------------------------------------------------------------- # Combine #---------------------------------------------------------------------------------------------------- elif choose == "COMBINE": st.title("Klasifikasi Bandwidth dengan COMBINE") # st.subheader('Test 123') # st.markdown('Design LSTM')