Python+CNN网络入侵检测毕设源码:从KDD数据到模型部署
发布时间:2026/10/2 3:16:38来源:尧图网络
简介这份资源面向计算机相关专业学生与项目实战学习者提供一套基于Python与CNN卷积神经网络的网络入侵检测完整方案可用于毕业设计、课程设计或期末大作业。压缩包共33个文件约21.58MB包含4个Python脚本、12个CSV数据集文件、7个XML配置、1个pth模型权重及若干图片与说明文档覆盖数据预处理、模型训练、预测推理与结果可视化等环节。项目采用NSL-KDD数据集通过PreHandle.py完成数据清洗与归一化Train.py构建并训练CNN模型Predict.py实现入侵流量分类预测配套的准确率、精确率与混淆矩阵图片直观展示实验效果。已有115人学习下载代码经导师指导并获评审99分认可结构完整可直接运行适合希望快速上手深度学习安全应用、理解CNN特征提取流程并完成高质量课程成果的学习者参考。1. 从一份能跑通的入侵检测毕设说起PythonCNN 到底交付了什么毕业设计选网络入侵检测这个方向很多人卡在第一步网上找到的代码要么只有模型没有数据要么数据是随机生成的假流量跑出来的准确率 99% 一看就是过拟合。这份基于 PythonCNN 的入侵检测源码包解决的就是能跑通、有真数据、有文档这三件事。它把卷积神经网络用在网络流量特征上输入是 KDD 系列格式的流量记录输出是正常流量还是某类攻击。适合正在做网络安全、深度学习方向毕设的本科生也适合想快速搭一个入侵检测原型的初级安全工程师。整套东西是 Python 写的依赖 TensorFlow 或 PyTorch 这类主流框架不需要你自己去抓包造数据数据集和文档都配齐了。下面我按数据长什么样 → 模型怎么搭 → 怎么训 → 坑在哪的顺序拆一遍你照着能复现。2. 数据先行KDD 流量特征怎么变成 CNN 能吃的张量2.1 为什么入侵检测能用 CNN 而不是只能上 RNN先把这个反直觉的点讲清楚不然你调参时心里没底。网络流量是时序数据直觉上该用 RNN 或 LSTM但 KDD Cup 99、NSL-KDD 这类数据集已经把每条连接抽成了 41 维的统计特征duration、protocol_type、src_bytes、flag 等它不再是原始字节流而是一张特征表。CNN 的卷积核在特征维度上滑动能捕捉相邻特征之间的局部关联模式比如某些标志位和字节数的组合往往对应特定攻击。常见做法是把 41 维特征重排成 8×8 或 6×7 的二维矩阵再套标准 CNN 结构。这样做的好处是训练快、显存占用低毕设机器是普通笔记本也能跑。选 CNN 而不是全连接是因为卷积的权值共享和局部感受野对特征组合更敏感实测比纯 MLP 收敛更稳。2.2 把 CSV 读进来、编码、归一化、reshape数据集一般是 CSV 或 TXT每行一条记录最后一列是标签。下面这段是数据预处理的核心我按常见实现写你对照自己包里的脚本改路径即可。import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler, LabelEncoder # 1. 读数据列名按 NSL-KDD 的 41 特征 label 约定 cols [duration,protocol_type,service,flag,src_bytes,dst_bytes, # ... 中间省略实际按数据集列数补全 ... label] df pd.read_csv(KDDTrain.txt, namescols) # 2. 类别型特征做 LabelEncoderprotocol_type/service/flag 是字符串 for c in [protocol_type,service,flag]: df[c] LabelEncoder().fit_transform(df[c]) # 3. 标签二分类normal 记 0其余攻击记 1 df[label] df[label].apply(lambda x: 0 if x normal else 1) # 4. 数值特征归一化到 [0,1]CNN 对量纲敏感 feat df.drop(label, axis1).values.astype(float32) feat MinMaxScaler().fit_transform(feat) # 5. reshape 成 CNN 输入(样本数, 高, 宽, 通道) # 41 维补到 48 维再排成 6x8或直接 8x8 补 23 个 0 pad np.zeros((feat.shape[0], 64 - feat.shape[1]), dtypefloat32) feat np.hstack([feat, pad]).reshape(-1, 8, 8, 1) labels df[label].values print(feat.shape, labels.shape) # (125973, 8, 8, 1) (125973,)逻辑说明LabelEncoder 把协议、服务、标志位这些字符串转成整数MinMaxScaler 把字节数这类跨度极大的特征压到同一量纲否则 src_bytes 动辄上万会直接主导梯度。reshape 是关键一步41 维补零到 64 维再排 8×8是为了让卷积核有规整的二维空间可滑。参数上补零维度选 64 是因为它最接近 41 的平方数且能被 8 整除如果你用 NSL-KDD 的 41 维也可以排成 6×7 补 1 个零效果差别不大。归一化务必在划分训练测试集之前用训练集 fit否则会有数据泄漏这是毕设查重和答辩常被问的点。2.3 训练集测试集划分与类别不平衡处理KDD 数据里正常流量远多于攻击直接训会让模型偏向预测正常。常见做法是分层抽样加类别权重。from sklearn.model_selection import train_test_split X_tr, X_te, y_tr, y_te train_test_split( feat, labels, test_size0.2, random_state42, stratifylabels) # 计算类别权重传给 model.fit 的 class_weight from sklearn.utils.class_weight import compute_class_weight cw compute_class_weight(balanced, classesnp.unique(y_tr), yy_tr) class_weight {0: cw[0], 1: cw[1]} print(class_weight)stratify 保证训练测试集里攻击比例一致compute_class_weight 给少数类更高权重让损失函数不忽视攻击样本。如果你的数据集是多分类Dos/Probe/R2L/U2R 四类攻击把 label 改成多类编码class_weight 用字典逐类给即可。3. CNN 模型搭建卷积核、池化、全连接怎么配才不翻车3.1 一个够用又不臃肿的网络结构毕设不需要 ResNet 那种深度两层卷积加两层全连接足够参数量小、训练快、好解释。下面用 Keras 写PyTorch 版本结构一样只是 API 不同。from tensorflow.keras import layers, models def build_cnn(input_shape(8, 8, 1), num_classes2): model models.Sequential([ # 第一层卷积32 个 3x3 核提取局部特征组合 layers.Conv2D(32, (3, 3), activationrelu, paddingsame, input_shapeinput_shape), layers.BatchNormalization(), layers.MaxPooling2D((2, 2)), # 第二层卷积64 个核捕捉更抽象的模式 layers.Conv2D(64, (3, 3), activationrelu, paddingsame), layers.BatchNormalization(), layers.MaxPooling2D((2, 2)), layers.Flatten(), layers.Dense(128, activationrelu), layers.Dropout(0.5), # 防过拟合毕设数据量下很关键 layers.Dense(num_classes, activationsoftmax) ]) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) return model model build_cnn() model.summary()逻辑说明paddingsame 保证 8×8 经过卷积尺寸不变池化两次后变成 2×2再 Flatten 进全连接。BatchNormalization 放在卷积后激活前这里写在激活后也能跑但标准做法是卷积→BN→激活能加速收敛、缓解梯度问题。Dropout 0.5 是血泪经验不加的话训练集准确率能到 99.9% 而测试集只有 80% 出头答辩老师一眼看穿。num_classes 二分类填 2多分类改成 5正常四类攻击。优化器 adam 默认学习率 1e-3 就够别乱调。3.2 训练循环、早停与模型保存from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint callbacks [ EarlyStopping(monitorval_loss, patience5, restore_best_weightsTrue), ModelCheckpoint(best_ids_cnn.h5, monitorval_accuracy, save_best_onlyTrue) ] history model.fit( X_tr, y_tr, validation_split0.2, # 从训练集再切 20% 做验证 epochs50, batch_size128, class_weightclass_weight, callbackscallbacks, verbose1 ) loss, acc model.evaluate(X_te, y_te) print(f测试集准确率: {acc:.4f})参数说明batch_size 128 是显存和收敛速度的平衡点笔记本 8G 显存跑得动epochs 给 50 但靠 EarlyStopping 提前停patience5 表示验证损失连续 5 轮不降就停并回滚到最优权重这是防止过拟合的后悔药。validation_split 从训练集切不要动测试集。class_weight 传进去让少数类样本的损失被放大。跑完看 history 里的 val_loss 曲线如果训练 loss 一直降而 val_loss 抬头就是过拟合回去加 Dropout 或减层。3.3 评估指标别只看准确率入侵检测是安全场景漏报一个攻击比误报一个正常流量严重得多。只看 accuracy 会骗人。from sklearn.metrics import classification_report, confusion_matrix y_pred model.predict(X_te).argmax(axis1) print(confusion_matrix(y_te, y_pred)) print(classification_report(y_te, y_pred, target_names[normal,attack]))重点看 recall召回率和 attack 类的 f1。如果 attack 的 recall 只有 0.7说明三成攻击被漏掉得回去调 class_weight 或加数据。confusion_matrix 里右下角是正确识别的攻击数右上角是漏报答辩时把这张矩阵图放上去比只报准确率专业得多。4. 避坑与排查跑不通、准确率虚高、显存爆的五个真实记录4.1 现象一上来准确率就 99%测试集也高得离谱原因数据泄漏。最常见的是先对整个数据集做了归一化再划分训练测试测试集的统计信息泄漏进了训练。另一个可能是标签列被当成特征喂进去了。解决归一化只在训练集 fit用同一个 scaler transform 测试集检查 drop(label) 是否真的把标签列去掉了打印 X_tr 的列数确认是 41 不是 42。4.2 现象reshape 报错 cannot reshape array of size X into shape (8,8,1)原因特征维度不是 64。KDD 99 是 41 维NSL-KDD 也是 41 维但有些衍生数据集是 42 或 43 维多了标签或难度等级列。解决先 print(df.shape[1]) 确认特征数补零公式改成 64 - 实际特征数或者干脆排成 7×7 补 8 个零。别硬套 8×8。4.3 现象训练时显存溢出 CUDA out of memory原因batch_size 太大或者把整个数据集一次性转成 one-hot 导致内存翻倍。解决batch_size 从 128 降到 64 或 32标签用 sparse_categorical_crossentropy 配合整数标签不要 to_categorical 成 one-hot。如果还是爆把数据生成器换成 tf.data.Dataset 分批加载别一次性全塞进内存。4.4 现象模型在测试集上正常换一批新流量就崩原因过拟合到训练集的特定分布。KDD 数据本身年代久远攻击类型和现代流量差异大。解决这是数据集本身的边界毕设里要如实说明。缓解办法是加 Dropout、加 L2 正则、做交叉验证看方差。别宣称模型能直接上生产答辩时老师问实际部署效果要诚实回答需要重新采集数据微调。4.5 现象类别型特征编码后顺序混乱模型学出莫名其妙的规律原因LabelEncoder 给 protocol_type 编的号tcp2, udp1, icmp0被模型当成了数值大小关系但协议之间没有大小之分。解决对无序类别特征改用 One-Hot 编码pd.get_dummies(df, columns[protocol_type,service,flag])。代价是特征维度膨胀service 有 70 种取值这时 reshape 的尺寸要重新算或者干脆用 Embedding 层处理类别特征。毕设里如果嫌麻烦至少要在文档里说明这个局限。5. 进阶技巧把准确率从 92% 推到 96% 的三个具体动作第一个动作是特征工程加料。原始 41 维里有些特征区分度低可以算几个组合特征塞进去比如 src_bytes 和 dst_bytes 的比值、同一服务的连接频率。加完重新归一化reshape 尺寸跟着调。我一般会先跑一版 baseline 记下准确率再加特征对比涨了才保留别一股脑全加。第二个动作是调卷积核数量和 Dropout 位置。把第一层卷积从 32 提到 64、第二层从 64 提到 128参数量上去了但表达能力强了配合 Dropout 0.5 和 EarlyStopping测试集通常能涨 2 到 3 个点。注意别加太深8×8 的输入经不起四五次池化两次就到 2×2 了再加池化特征就没了。第三个动作是集成。训三个不同随机种子的模型预测时对 softmax 输出取平均再 argmax。这个技巧在毕设里算亮点代码就几行preds np.zeros((X_te.shape[0], 2)) for seed in [42, 7, 2024]: tf.random.set_seed(seed) m build_cnn() m.fit(X_tr, y_tr, epochs30, batch_size128, class_weightclass_weight, verbose0) preds m.predict(X_te) y_ensemble preds.argmax(axis1)三个模型各自有偏差平均后方差变小实测比单模型稳。代价是训练时间三倍毕设时间够就上不够就单模型调好参数。验证方法上除了看测试集我习惯再切一份从来没碰过的 holdout 集训练全程不参与任何决策最后只跑一次。如果 holdout 和测试集差距超过 3 个点说明调参时对测试集过拟合了得回头收敛。这个习惯是从一次答辩被问你怎么证明没调测试集之后养成的从那以后我每次做毕设都强制留一份 holdout跑完才敢写进论文。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网