news 2026/10/2 8:35:30

联邦学习入侵检测实战:NSL-KDD非IID数据训练与GUI监控

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
联邦学习入侵检测实战:NSL-KDD非IID数据训练与GUI监控

简介:本资源是一套基于联邦学习框架与NSL-KDD标准数据集实现的网络入侵检测系统完整Python工程,专为计算机、电子信息及数学类专业本科生设计,适用于毕业设计、课程设计与期末大作业等高阶实践场景。项目已通过导师评审并获98分高分,集成训练/测试/可视化全流程,含GUI交互界面,显著降低部署与演示门槛。压缩包共63个文件,涵盖12个核心Python源码(含client/server双端逻辑、模型定义、GUI构建与连接函数)、3个权重文件(Net.weight、local_model.weight等)、10个说明类txt文档、2个png结果对比图及CSV日志数据,整体26.18MB,结构清晰、模块解耦度高,便于理解联邦学习在安全领域的分布式建模实践。目前已有307人学习下载,读者可直接运行复现完整检测流程,获取带注释的联邦训练代码、本地/全局模型评估对比结果、GUI操作逻辑及多客户端协同调试范例,是深入理解隐私保护型IDS落地的优质参考项目。

1. 联邦学习做入侵检测,真能不传原始流量数据就训出可用模型?——NSL-KDD+Python+GUI全栈可运行项目实测

你手头有一批真实网络流量日志,但合规红线卡得死:不能把原始pcap或连接记录上传到中心服务器,更不能让第三方看到用户IP、端口、协议载荷。这时候,传统集中式训练直接废掉。而这个98分毕设项目,用纯Python实现了三客户端+单服务器的联邦学习闭环,所有原始NSL-KDD数据全程保留在本地client目录下,只交换加密后的模型权重(local_model.weight、Net.weight),最后在GUI界面里实时对比各客户端本地测试准确率与全局聚合模型效果。它不是玩具Demo——文件列表里明晃晃躺着resultCompare1.png和resultCompare2.png两张可视化结果图,data.log和data3.log记录着每轮通信的loss与acc变化,initDate.py里甚至做了NSL-KDD字段对齐与one-hot编码预处理。适合正在赶毕设 deadline 的计算机/网安专业学生,也适合想亲手拆解“联邦学习如何落地安全场景”的工程师:代码不依赖GPU,PyTorch 1.8+即可跑通,GUI用tkinter写成,连打包成exe都留了server.zip和client.zip两个现成压缩包。别被“高分设计”唬住——它真正硬核的地方,在于把联邦学习里最棘手的非独立同分布(Non-IID)数据切分、客户端异步更新冲突、本地模型过拟合监控这些黑匣子,全摊开在main_client_1.py、main_server.py和model.py的注释行里。


2. 从NSL-KDD原始数据到联邦训练:四步完成数据准备与本地模型初始化

2.1 NSL-KDD数据集结构解析与本地化切分逻辑

NSL-KDD有KDDTrain+.txt和KDDTest+.txt两个主文件,共41个特征(如duration、protocol_type、service、flag等)加1个标签attack_type。本项目没用官方train/test划分,而是通过initDate.py做了按攻击类型比例保留在各客户端的Non-IID切分:

  • client/目录下data/子文件夹存放各客户端专属数据(如client1_data.csv)
  • 切分规则在initDate.py第47行:train_ratio = [0.4, 0.35, 0.25]—— 三个客户端分别拿到40%、35%、25%的总训练样本,且每个客户端的数据中normal、dos、probe、r2l、u2r五类攻击占比严格按原始数据分布浮动±3%
  • 标签映射表硬编码在initDate.py第22行:label_map = {'normal':0, 'dos':1, 'probe':2, 'r2l':3, 'u2r':4},避免pandas读取时字符串标签导致torch.nn.CrossEntropyLoss报错

提示:原始NSL-KDD的KDDTrain+.txt是无header的CSV,initDate.py第63行用pd.read_csv(..., header=None)强制读取,再通过columns=feature_names注入列名。若你替换为自定义流量数据,必须确保feature_names列表长度=41,且顺序与NSL-KDD官方文档一致。

2.2 客户端本地模型构建:轻量CNN+全连接双分支设计

model.py定义了Net类,结构比常规入侵检测模型更克制:

  • 输入层:41维特征 →nn.Linear(41, 64)→ ReLU
  • 特征提取层:nn.Conv1d(in_channels=1, out_channels=16, kernel_size=3)(将41维展平为[1,41]后卷积)
  • 分类头:两路并行输出——self.fc1输出5类攻击概率,self.fc2额外输出二分类(normal/attack)用于置信度校验
  • 关键细节:forward()函数第32行x = x.view(x.size(0), -1)执行flatten,避免Conv1d输出维度与Linear输入不匹配;__init__中self.dropout = nn.Dropout(0.3)防止客户端小数据集过拟合
# model.py 关键片段(已补全缺失注释) class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv1d(1, 16, 3) # 输入: [batch, 1, 41] → 输出: [batch, 16, 39] self.fc1 = nn.Linear(16*39, 5) # 改变此处可适配不同特征数 self.fc2 = nn.Linear(16*39, 2) # 二分类辅助头,提升泛化性 self.dropout = nn.Dropout(0.3) def forward(self, x): x = x.unsqueeze(1) # 增加channel维度: [batch, 41] → [batch, 1, 41] x = F.relu(self.conv1(x)) # 卷积后尺寸: [batch, 16, 39] x = x.view(x.size(0), -1) # flatten: [batch, 16*39] x = self.dropout(x) out1 = self.fc1(x) # 5类攻击输出 out2 = self.fc2(x) # normal/attack二分类输出 return out1, out2

2.3 本地训练循环:带早停与梯度裁剪的鲁棒实现

main_client_1.py中train_local_model()函数封装了完整训练流程,核心参数全部外置到argu.py:

  • args.local_epochs = 5:每个客户端每轮联邦通信只训5 epoch,避免本地过拟合
  • args.lr = 0.01:学习率设为0.01而非常规0.001,因NSL-KDD特征尺度差异大(duration范围0~58000,count仅0~511),需更高lr加速收敛
  • args.clip_grad_norm = 1.0:梯度裁剪阈值设为1.0,防止Non-IID数据导致梯度爆炸(实测不裁剪时client2的loss在第3轮突增至inf)
  • 早停机制:patience=3,连续3轮验证集acc不升则终止本轮本地训练,保存local_model.weight
# main_client_1.py 训练循环节选(含关键参数说明) def train_local_model(model, train_loader, val_loader, args): optimizer = torch.optim.SGD(model.parameters(), lr=args.lr) criterion = nn.CrossEntropyLoss() best_val_acc = 0.0 patience_counter = 0 for epoch in range(args.local_epochs): model.train() for data, target in train_loader: optimizer.zero_grad() output, _ = model(data) # 只用5分类头计算loss loss = criterion(output, target) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip_grad_norm) # 防梯度爆炸 optimizer.step() # 验证阶段 val_acc = validate(model, val_loader) if val_acc > best_val_acc: best_val_acc = val_acc torch.save(model.state_dict(), 'local_model.weight') # 仅保存最优模型 patience_counter = 0 else: patience_counter += 1 if patience_counter >= args.patience: break # 早停触发

2.4 全局模型聚合:FedAvg实现与权重衰减策略

main_server.py中的aggregate_models()函数执行标准FedAvg,但增加了客户端贡献度加权:

  • 权重计算公式:weight_i = client_data_size_i / total_data_size(client_data_size_i来自initDate.py生成的client_stats.json)
  • 衰减策略:第k轮聚合时,全局模型W^k=0.9 * W^{k-1} + 0.1 * Σ(weight_i * W_i^k),避免某客户端突发异常权重污染全局模型
  • 验证逻辑:聚合后立即用server_test_loader(NSL-KDD完整test集)评估,结果写入data.log,格式为[Round 5] Global Acc: 89.2%, Loss: 0.321

注意:server.zip中main_server.py第89行global_model.load_state_dict(aggregated_state_dict)后,必须调用global_model.eval(),否则后续validate()会因BatchNorm层统计量未冻结导致acc虚高。


3. GUI界面交互与联邦训练监控:从启动到结果可视化的全流程控制

3.1 GUI主界面功能分区与事件绑定逻辑

GUI.py基于tkinter构建,采用ttk.Notebook实现多标签页:

  • 首页(Start Page):三个按钮分别触发start_server()、start_client1()、start_client2(),底层调用subprocess.Popen(['python', 'main_server.py'])启动进程
  • 训练监控页(Training Monitor):嵌入matplotlib画布,实时绘制data.log中解析出的Round、Global Acc、Client1 Acc、Client2 Acc四条曲线
  • 结果对比页(Result Compare):显示resultCompare1.png(各客户端本地测试混淆矩阵)和resultCompare2.png(全局模型vs各客户端模型在统一test集上的acc对比柱状图)

关键事件绑定在GUI.py第127行:

# GUI.py 事件绑定示例 self.start_btn = ttk.Button(self.start_frame, text="启动联邦训练", command=self.start_federated_training) self.start_btn.grid(row=0, column=0, padx=10, pady=5) def start_federated_training(self): # 启动server进程并监听端口 self.server_proc = subprocess.Popen(['python', 'main_server.py'], stdout=open('server.log', 'w'), stderr=subprocess.STDOUT) time.sleep(2) # 确保server已监听 # 并行启动两个client self.client1_proc = subprocess.Popen(['python', 'main_client_1.py']) self.client2_proc = subprocess.Popen(['python', 'main_client_2.py'])

3.2 日志解析引擎:从data.log提取指标并驱动图表更新

GUI.py中parse_log_file()函数是监控页的核心,它持续读取data.log末尾新增行:

  • 正则匹配模式:r'\[Round (\d+)\] Global Acc: ([\d.]+)%, Loss: ([\d.]+)'
  • 每次匹配到新轮次,将round_num、global_acc、client1_acc(从data.log中Client1 Acc:字段提取)存入self.round_history列表
  • 图表更新逻辑:self.ax.clear()→self.ax.plot(rounds, global_accs, label='Global')→self.canvas.draw()

提示:data.log默认每轮写入3行(server一行,client1一行,client2一行),但parse_log_file()使用tail -f式轮询(while True: with open('data.log') as f: f.seek(0, 2); line = f.readline()),避免日志过大时全量读取卡顿。

3.3 结果对比图生成原理:Matplotlib动态绘图与PNG导出

resultCompare1.png由utils.py中plot_confusion_matrix()生成:

  • 输入:各客户端local_testModel.weight在NSL-KDD test集上的预测结果(y_true,y_pred)
  • 绘图:sns.heatmap(cm, annot=True, fmt='d', cmap='Blues'),x轴/y轴标注['normal','dos','probe','r2l','u2r']
  • 导出:plt.savefig('resultCompare1.png', dpi=300, bbox_inches='tight'),确保论文打印清晰

resultCompare2.png则用柱状图对比:

模型类型Client1 AccClient2 AccGlobal Acc
本地模型86.2%82.7%—
全局模型89.5%89.5%89.5%
# utils.py 中 resultCompare2.png 生成代码 def plot_accuracy_comparison(client1_acc, client2_acc, global_acc): models = ['Client1 Local', 'Client2 Local', 'Global Model'] accs = [client1_acc, client2_acc, global_acc] plt.figure(figsize=(8, 5)) bars = plt.bar(models, accs, color=['#1f77b4', '#ff7f0e', '#2ca02c']) plt.ylabel('Accuracy (%)') plt.title('Model Accuracy Comparison on NSL-KDD Test Set') plt.ylim(80, 95) # 在柱子顶部添加数值标签 for bar, acc in zip(bars, accs): plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.3, f'{acc:.1f}%', ha='center', va='bottom') plt.savefig('resultCompare2.png', dpi=300, bbox_inches='tight')

3.4 进程管理与异常捕获:GUI如何优雅处理训练中断

GUI.py中stop_training()函数不仅发送kill信号,还执行清理:

  • 终止server/client进程:self.server_proc.terminate()→self.server_proc.wait(timeout=5)
  • 若超时未退出,则强制kill:os.kill(self.server_proc.pid, signal.SIGKILL)
  • 清理临时文件:os.remove('local_model.weight')、os.remove('Net.weight'),防止下次启动加载旧权重
  • 异常捕获:try...except subprocess.TimeoutExpired捕获进程僵死,弹窗提示“检测到进程无响应,请检查端口占用”

注意:Windows系统需在subprocess.Popen中添加creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,否则terminate()无法杀死子进程树。


4. 联邦学习实战避坑指南:五个血泪经验总结(现象→原因→解决)

4.1 现象:客户端训练loss在第2轮突然飙升至inf,server日志显示RuntimeError: invalid gradient at index 0

原因:NSL-KDD数据中存在极少数duration=0且src_bytes=0的记录,经initDate.py标准化后产生nan值,nn.CrossEntropyLoss反向传播时梯度爆炸。
解决:在initDate.py数据清洗环节(第102行)增加df = df.replace([np.inf, -np.inf], np.nan).dropna(),并在main_client_*.py中train_loader创建前添加dataset = dataset[~dataset.isnull().any(axis=1)]。

4.2 现象:GUI监控页曲线停滞,data.log最新记录停留在[Round 3],但main_server.py进程仍在运行

原因:server与client间socket通信超时,默认connFun.py中socket.settimeout(30),当某客户端因CPU占用过高未及时响应,server等待30秒后断开连接,但未重试机制导致训练卡死。
解决:修改connFun.py第45行sock.settimeout(120),并在main_server.py的receive_from_client()函数中增加重试逻辑:for attempt in range(3): try: ... except socket.timeout: continue。

4.3 现象:resultCompare1.png混淆矩阵中r2l类召回率为0,但全局模型acc达89%,明显过拟合

原因:r2l类在NSL-KDD中仅占训练集0.12%,initDate.py切分时未做SMOTE过采样,导致client2分到的r2l样本不足5个,本地模型根本学不会该类别。
解决:在initDate.py切分后插入SMOTE模块(需pip install imblearn):

from imblearn.over_sampling import SMOTE smote = SMOTE(random_state=42, sampling_strategy={'r2l': 50}) # 强制r2l类扩增至50样本 X_res, y_res = smote.fit_resample(X_train, y_train)

4.4 现象:main_client_1.py报错ModuleNotFoundError: No module named 'torch',但终端python -c "import torch"可成功

原因:GUI启动时subprocess.Popen未继承当前Python环境,而是调用系统默认python(可能为Python 2.7),而项目依赖PyTorch需Python 3.6+。
解决:在GUI.py中显式指定Python路径:

# 替换原subprocess调用 python_path = sys.executable # 获取当前运行GUI的Python解释器路径 self.client1_proc = subprocess.Popen([python_path, 'main_client_1.py'])

4.5 现象:resultCompare2.png中Global Model柱子高度低于Client1 Local,违背联邦学习“全局优于局部”常识

原因:main_server.py中validate()函数误用train_loader而非test_loader计算全局acc,导致用训练集评估——这在Non-IID场景下必然虚高。
解决:检查main_server.py第156行val_loader = get_test_loader(),确认get_test_loader()返回的是NSL-KDD完整test集,而非某个客户端的train数据。


5. 模型性能深度验证:用NSL-KDD官方评估指标替代accuracy单一指标

5.1 为什么accuracy在入侵检测中具有欺骗性?

NSL-KDD中normal样本占比78.5%,即使模型把所有样本全判为normal,accuracy也能达到78.5%。而实际安全需求关注的是漏报率(False Negative Rate)——把dos攻击判为normal,后果远比把normal判为dos严重。本项目在utils.py中内置了NSL-KDD官方推荐的四大指标计算:

  • Detection Rate (DR)= TP / (TP + FN)
  • False Alarm Rate (FAR)= FP / (FP + TN)
  • Accuracy= (TP + TN) / (TP + TN + FP + FN)
  • Precision= TP / (TP + FP)

其中TP/TN/FP/FN按攻击大类统计:normal为负样本,其余四类(dos/probe/r2l/u2r)合并为正样本。

5.2 四类攻击的DR/FAR分离计算与可视化

utils.py中calculate_detailed_metrics()函数将混淆矩阵按行展开:

真实标签 \ 预测normaldosprober2lu2r
normalTNFP1FP2FP3FP4
dosFN1TP1000
probeFN20TP200
r2lFN300TP30
u2rFN4000TP4

然后逐类计算:

  • dos_DR = TP1 / (TP1 + FN1)
  • dos_FAR = (FP1 + FP2 + FP3 + FP4) / (FP1 + FP2 + FP3 + FP4 + TN)
  • 其余类同理
# utils.py 指标计算核心逻辑 def calculate_detailed_metrics(y_true, y_pred): cm = confusion_matrix(y_true, y_pred) # cm[i][j] = 真实i类被预测为j类的样本数 metrics = {} for i, attack in enumerate(['normal', 'dos', 'probe', 'r2l', 'u2r']): if i == 0: # normal类作为负样本 tn = cm[i][i] fp = cm[i].sum() - tn fn = cm[:, i].sum() - tn tp = cm.sum() - (tn + fp + fn) else: # 攻击类作为正样本 tp = cm[i][i] fn = cm[i].sum() - tp fp = cm[:, i].sum() - tp tn = cm.sum() - (tp + fn + fp) metrics[attack] = { 'DR': tp / (tp + fn) if (tp + fn) > 0 else 0, 'FAR': fp / (fp + tn) if (fp + tn) > 0 else 0 } return metrics

5.3 联邦学习特有的灾难性遗忘验证方法

联邦学习中,客户端每轮只用本地数据微调,可能导致对其他攻击类别的识别能力退化。本项目通过跨轮次保留测试集验证:

  • 在initDate.py中预留10%原始NSL-KDD test样本作为cross_round_test.csv
  • 每轮联邦训练结束后,用global_model和client1_model分别在该保留集上运行calculate_detailed_metrics()
  • 结果写入cross_round_log.txt,格式为:
    Round 1: Client1 dos_DR=0.82, Global dos_DR=0.79
    Round 5: Client1 dos_DR=0.75, Global dos_DR=0.85
    → 发现Client1对dos的DR下降7%,而Global上升6%,证明联邦聚合有效缓解了客户端灾难性遗忘

提示:cross_round_test.csv必须在所有客户端切分前生成,否则Non-IID切分会导致保留集分布失真。initDate.py第188行cross_test_df = full_test_df.sample(frac=0.1, random_state=42)即为此目的。

5.4 从GUI一键导出符合论文要求的评估报告

GUI.py中“Export Report”按钮触发generate_academic_report()函数,自动生成LaTeX兼容的Markdown表格:

指标Client1 LocalClient2 LocalGlobal Model
dos DR82.3%76.1%85.7%
r2l DR41.2%52.8%48.3%
FAR12.4%15.6%9.8%
Accuracy86.2%82.7%89.5%

该表格直接复制进论文Results章节,无需手动调整。导出的report.md还包含resultCompare1.png和resultCompare2.png的base64内联引用,确保离线提交时图片不丢失。

从那以后我每次部署联邦学习项目,都强制走一遍cross_round_test.csv的跨轮次验证——哪怕多花2小时,也要确认全局模型没有在悄悄遗忘某个攻击类型。毕竟在安全领域,一次漏报的成本,远高于一百次误报。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 8:35:15

蓝牙协议规范PDF合集:从解压到检索的完整实战指南

简介:蓝牙协议栈是嵌入式开发中最常被误解的技术体系之一,从BLE连接建立到GATT服务发现,每一层行为都由蓝牙核心规范严格定义。工程师在调试低功耗设备时,经常需要查阅HCI命令、L2CAP信令或Attribute PDU格式,而权威规…

作者头像 李华
网站建设 2026/10/2 8:35:11

草原牦牛行为识别数据集:YOLO+VOC双格式8674张样本实战解析

简介:数据集为草原牦牛行为识别数据集,面向计算机视觉学习者与智慧牧场应用开发者,共8674张jpg图片及对应标注,覆盖吃草、打架、站立、躺、移动、交配等8种行为,可直接用于目标检测模型训练。资源包共2000个文件&#…

作者头像 李华
网站建设 2026/10/2 8:34:35

基于Transformer的时间序列预测Python源码解析与调优

简介:一套基于Transformer模型的时间序列预测Python源码项目,主要面向需要完成课程期末大作业、毕业设计或入门深度学习时序建模的高校学生与开发者。项目已在本地编译运行通过,难度适中,且经过助教老师审定,能够满足课…

作者头像 李华
网站建设 2026/10/2 8:33:07

中文NER实战:BERT-BiLSTM-CRF源码解析与可复现训练指南

简介:本资源面向中文命名实体识别(NER)的入门与进阶学习者,提供一套基于PyTorch实现的BERT-BiLSTM-CRF完整项目,适合毕业设计、期末大作业与课程设计场景,也便于新手通过注释理解模型原理。压缩包共22个文件…

作者头像 李华
网站建设 2026/10/2 8:33:05

YOLOv10焊缝缺陷检测实战:从工艺约束到轻量化部署

简介:本资源是一套面向工业质检场景的YOLOv10焊缝质量检测完整方案,适用于计算机视觉初学者、自动化检测工程师及智能制造领域研究者,解决焊缝缺陷(如裂纹、气孔、未熔合等)的快速识别与分类问题。压缩包共2000个文件&…

作者头像 李华