In this blog post, I will walk you through the implementation of an AI-powered Intrusion Detection System (IDS) using machine learning techniques. I will cover the preprocessing of the dataset, building a neural network model, training the model, and evaluating its performance.
Importing Necessary Libraries
First, I need to import the necessary libraries for our project. These include libraries for data manipulation, visualization, and building neural networks.
import torch
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
Loading the Dataset
Next, I load the training and testing datasets. These datasets contain network traffic data which we will use to train and evaluate our model.
df = pd.read_csv('./archive/KDDTrain+.txt', header=None)
test_df = pd.read_csv('./archive/KDDTest+.txt', header=None)
columns = [
'duration', 'protocol_type', 'service', 'flag', 'src_bytes', 'dst_bytes', 'land',
'wrong_fragment', 'urgent', 'hot', 'num_failed_logins', 'logged_in', 'num_compromised',
'root_shell', 'su_attempted', 'num_root', 'num_file_creations', 'num_shells',
'num_access_files', 'num_outbound_cmds', 'is_host_login', 'is_guest_login', 'count',
'srv_count', 'serror_rate', 'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate',
'same_srv_rate', 'diff_srv_rate', 'srv_diff_host_rate', 'dst_host_count',
'dst_host_srv_count', 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate',
'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', 'dst_host_serror_rate',
'dst_host_srv_serror_rate', 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate',
'attack', 'level'
]
df.columns = columns
test_df.columns = columns
Data Preprocessing
To prepare the data for training, I convert the attack
column to a binary format, where 'normal' traffic is labeled as 0 and all other traffic is labeled as 1. I also encode categorical variables.
df['attack_binary'] = df.attack.map(lambda a: 0 if a == 'normal' else 1)
df.drop('attack', axis=1, inplace=True)
test_df['attack_binary'] = test_df.attack.map(lambda a: 0 if a == 'normal' else 1)
test_df.drop('attack', axis=1, inplace=True)
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
clm = ['protocol_type', 'service', 'flag']
for x in clm:
df[x] = le.fit_transform(df[x])
test_df[x] = le.fit_transform(test_df[x])
Feature Selection
I select specific features for our model to train on.
features = ['service', 'flag', 'src_bytes', 'dst_bytes', 'logged_in', 'count',
'serror_rate', 'srv_serror_rate', 'same_srv_rate', 'diff_srv_rate',
'dst_host_srv_count', 'dst_host_same_srv_rate',
'dst_host_diff_srv_rate', 'dst_host_serror_rate',
'dst_host_srv_serror_rate']
X = df[features]
y = df['attack_binary']
X = X.values
y = y.values
Splitting the Dataset
I split the dataset into training and testing sets.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=41)
X_train = torch.FloatTensor(X_train)
X_test = torch.FloatTensor(X_test)
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)
Building the Neural Network Model
I define our neural network architecture.
class Model(nn.Module):
def __init__(self, in_features=15, h1=30, h2=30, h3=30, out_features=2):
super().__init__()
self.fc1 = nn.Linear(in_features, h1)
self.fc2 = nn.Linear(h1, h2)
self.fc3 = nn.Linear(h2, h3)
self.out = nn.Linear(h3, out_features)
def forward(self, x):
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = F.relu(self.fc3(x))
x = self.out(x)
return x
Training the Model
I initialize the model, define the loss function and optimizer, and then train the model.
torch.manual_seed(41)
model = Model()
weights = torch.tensor([0.5, 3.0], dtype=torch.float32) # Increase the weight for the 'attack' class
criterion = nn.CrossEntropyLoss(weight=weights)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
epochs = 600
losses = []
for i in range(epochs):
y_pred = model.forward(X_train)
loss = criterion(y_pred, y_train)
losses.append(loss.detach().numpy())
if i % 10 == 0:
print(f'Epoch: {i} and loss: {loss}')
optimizer.zero_grad()
loss.backward()
optimizer.step()
plt.plot(range(epochs), losses)
plt.ylabel("loss/errors")
plt.xlabel('Epoch')
Evaluating the Model
I evaluate the model's performance on the test set.
with torch.no_grad():
y_eval = model.forward(X_test)
loss = criterion(y_eval, y_test)
correct = 0
with torch.no_grad():
for i, data in enumerate(X_test):
y_val = model.forward(data)
print(f'{i+1}.) {str(y_val)} \t {y_test[i]} \t {y_val.argmax().item()}')
if y_val.argmax().item() == y_test[i]:
correct+=1
print(correct)
Model Metrics
I calculate accuracy, precision, recall, and plot the confusion matrix.
import torch
from sklearn.metrics import accuracy_score, classification_report, precision_score, recall_score
model.eval()
predictions = []
labels = []
with torch.no_grad():
for data, label in zip(X_test, y_test):
y_val = model(data.unsqueeze(0))
_, predicted = torch.max(y_val, dim=1)
predictions.append(predicted.item())
labels.append(label.item())
accuracy = accuracy_score(labels, predictions)
precision = precision_score(labels, predictions, average='weighted')
recall = recall_score(labels, predictions, average='weighted')
report = classification_report(labels, predictions)
print(f'Accuracy: {accuracy * 100:.2f}%')
print(f'Precision: {precision * 100:.2f}%')
print(f'Recall: {recall * 100:.2f}%')
print("Classification Report:")
print(report)
Confusion Matrix
Finally, I will visualize the confusion matrix to understand the performance of our model better.
from sklearn.metrics import classification_report, accuracy_score, precision_score, recall_score, confusion_matrix
import seaborn as sns
neuralnetwork = confusion_matrix(labels, predictions)
plt.figure(figsize=(8, 6))
sns.heatmap(neuralnetwork, annot=True, fmt='d', cmap='Blues', xticklabels=['Negative', 'Positive'], yticklabels=['Negative', 'Positive'])
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.title('Confusion Matrix')
plt.show()
Conclusion
In this blog post, I built an AI-powered Intrusion Detection System using machine learning techniques. I walked through the steps of data preprocessing, model building, training, and evaluation. By following these steps, you can create a robust IDS to enhance the security of network systems.