Training SentinelMesh: Building a 1D-CNN IoT Attack Classifier
In Part 1, I covered the SentinelMesh architecture: IoT devices send traffic telemetry to an edge gateway, where machine learning models classify suspicious behavior and generate alerts.
In this post, I will focus on the first model: the 1D Convolutional Neural Network, or 1D-CNN.
The CNN is the reactive detection engine of SentinelMesh. Its job is to answer one question:
Does this network flow look benign or malicious?
Why use a 1D-CNN for network traffic?
CNNs are often associated with images, but they can also work well on one-dimensional structured data.
In this project, each network flow is represented by a vector of numeric features. Instead of scanning across pixels, the 1D-CNN scans across network-flow features such as packet size, protocol type, header length, inter-arrival time, TCP flags, and traffic rate.
The intuition is simple:
- Benign traffic has certain feature patterns.
- Attack traffic has different feature patterns.
- A 1D-CNN can learn local combinations of features that act like attack fingerprints.
Step 1: Load the dataset
The project used a balanced subset of the CIC-IoT-2023 dataset.
import pandas as pd
import numpy as np
_df = pd.read_csv("SentinelMesh_Final_Subset.csv")
print(_df.shape)
print(_df.head())
The subset contained 240,000 records with both benign and attack traffic. The original labels included multiple attack types, but for this first model I converted the problem into binary classification.
_df["is_attack"] = _df["Label"].apply(lambda x: 0 if x == "BENIGN" else 1)
The target became:
0 = benign traffic
1 = attack traffic
Step 2: Clean the data
Network-flow data can contain missing values or infinite values, especially when features are calculated using ratios or time-based fields.
_df.replace([np.inf, -np.inf], np.nan, inplace=True)
_df.dropna(inplace=True)
This is not the exciting part of machine learning, but it matters. Bad values can silently break model training or cause unstable results.
Step 3: Balance the classes
For a security model, class imbalance can be dangerous.
If a dataset contains far more attack traffic than benign traffic, the model may over-predict attacks. If it contains far more benign traffic, the model may miss actual attacks.
For this CNN, I used 100,000 benign records and 100,000 attack records.
benign_pool = _df[_df["is_attack"] == 0]
attack_pool = _df[_df["is_attack"] == 1]
benign_subset = benign_pool.sample(n=100000, random_state=42)
attack_subset = attack_pool.sample(n=100000, random_state=42)
df_balanced = pd.concat([benign_subset, attack_subset]).sample(
frac=1,
random_state=42
)
That produced a clean binary dataset with 200,000 records.
Step 4: Scale and reshape the features
The CNN used 39 numeric input features.
from sklearn.preprocessing import StandardScaler
X = df_balanced.drop(["Label", "is_attack"], axis=1)
y = df_balanced["is_attack"].values.astype("float32")
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X).astype("float32")
A 1D-CNN expects a three-dimensional input:
(samples, features, channels)
So I reshaped the data into:
(samples, 39, 1)
X_reshaped = X_scaled.reshape(X_scaled.shape[0], X_scaled.shape[1], 1)
Step 5: Train-validation split
I used an 80/20 split:
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(
X_reshaped,
y,
test_size=0.2,
random_state=42,
stratify=y
)
This gave me:
Training samples: 160,000
Validation samples: 40,000
Step 6: Build the 1D-CNN
Here is the model architecture:
import tensorflow as tf
from tensorflow.keras import layers, models
model = models.Sequential([
layers.Conv1D(64, kernel_size=3, activation="relu", input_shape=(39, 1)),
layers.MaxPooling1D(pool_size=2),
layers.BatchNormalization(),
layers.Conv1D(128, kernel_size=3, activation="relu"),
layers.GlobalAveragePooling1D(),
layers.Dropout(0.3),
layers.Dense(64, activation="relu"),
layers.Dense(1, activation="sigmoid")
])
model.compile(
optimizer="adam",
loss="binary_crossentropy",
metrics=["accuracy"]
)
The final sigmoid layer outputs a probability between 0 and 1.
Closer to 0 = likely benign
Closer to 1 = likely attack
Step 7: Train the model
history = model.fit(
X_train,
y_train,
epochs=10,
batch_size=64,
validation_data=(X_val, y_val),
verbose=1
)
The model had 33,537 total parameters, which is small enough to be realistic for an edge-style deployment.
Step 8: Evaluate the CNN
The CNN reached about 98.8% validation accuracy on the held-out validation set.

The classification report looked roughly like this:
precision recall f1-score support
Benign 0.98 1.00 0.99 20,000
Attack 1.00 0.98 0.99 20,000
Accuracy 0.99 40,000
For cybersecurity, accuracy alone is not enough. The most important thing to watch is false negatives.
A false positive means the system flagged benign traffic as suspicious. That is annoying.
A false negative means the system missed an attack. That is dangerous.
So for intrusion detection, attack recall is one of the most important metrics.
Step 9: Save the model
Once trained, the model can be saved and loaded by the edge inference pipeline.
model.save("sentinelmesh_cnn_model.keras")
In a production-style version, this model artifact would be versioned in a model registry such as MLflow.
What this model does well
The CNN worked well because network-flow features contain strong attack patterns. Flood attacks, scanning behavior, spoofing, and other malicious activity often create feature combinations that look different from normal device traffic.
The model is also relatively lightweight, which makes it a good candidate for edge inference.
What this model does not solve
The CNN is reactive. It classifies a flow after enough information is available.
That means it is good at answering:
Is this traffic malicious?
But it is less good at answering:
Is something abnormal starting to happen before the traffic is clearly malicious?
That is where the LSTM comes in.
What comes next
In Part 3, I will add the second model: an LSTM traffic-rate predictor. Instead of classifying individual flows, the LSTM learns a baseline of normal traffic behavior and helps detect abnormal spikes.
Then I will combine the CNN and LSTM outputs into a simple alerting dashboard.