近两年聊到网络入侵检测,很多人第一反应就是“堆模型”,CNN、LSTM、Transformer一通上,效果却常常不太理想。尤其做信息安全方向的毕业设计,最关键的问题不是模型复杂度,而是“你到底想解决什么问题”。如果你正在为课题挠头,那“基于k均值聚类的有监督对比学习网络入侵检测算法研究”这个题目,属于典型的“看上去绕、实际很扎实”的组合思路:用无监督方法挖数据内在结构,用有监督对比学习提升特征判别力,两者互补,既能解释得通,又能跑出有效指标。这篇文章我按自己实操过的经验,把整个题目拆开,从原理、数据、框架、实验到踩坑,一条线讲清楚,给正在做类似课题的同学一份可以直接参考的落地手册。
1. 选题拆解与整体设计思路
1.1 题目里的三个关键词到底在说什么
这个题目包含三个核心语义块:k均值聚类、有监督对比学习、网络入侵检测。别被它们一起出现吓到,先逐个拆开看。
网络入侵检测(Network Intrusion Detection)是所有工作的应用背景和目标域,解决的是“从一段网络流量或会话记录里,判断它是不是攻击行为”的问题。传统实现方式有两种路线:基于规则的特征匹配,比如Snort;基于统计/机器学习的行为建模。你的毕业设计走的是后者,也就是把网络连接或流量的统计特征喂给模型,让模型自己学出“正常”和“恶意”的区别。
k均值聚类是这里的第一层技术底座。它做的事情很简单:把一组样本按特征相似度分成K个簇,让簇内样本尽量接近、簇间尽量远离。放到入侵检测场景里,它的天然假设是:同类攻击行为的流量模式会比较接近,正常流量也会聚成一团或者几团。但k-means本身是“无监督”的,它不知道哪个簇是攻击,哪个簇是正常,只负责划分结构。
有监督对比学习是这里的第二层技术底座,也是整个题目最核心的方法创新点。对比学习的核心思想是“拉近相似的样本,推开不相似的样本”。什么叫“相似”?你需要定义两个样本是否语义上同类。传统的自监督对比学习(比如SimCLR)靠数据增强生成正样本对,而题目里加了一个限定词“有监督”,意思是我们可以利用标签信息来构造正负样本对:同一类别的样本作为正对,不同类别的样本作为负对。这么做的好处是特征空间会更紧凑,类别边界更干净。
那k-means和有监督对比学习为什么能结合?这是整个设计里最值得讲清楚的一点。
1.2 解题核心:无监督先验如何服务有监督学习
很多人第一眼会觉得这两个概念冲突:一个不需要标签,一个需要标签,放在一起是不是重复了?其实不是。k-means在这里的角色不是最终的分类器,而是一个“先验结构提取器”,用来辅助对比学习构造更合理的样本对和分类任务。
具体可落地的结合方式有两种主流套路。第一种是“聚类作为样本筛选器”:先用全体数据(含未标注数据)跑k-means,看每个簇里正常样本和攻击样本的分布占比。某些簇出现异常集中时,说明这些样本在原始特征空间里已经有很强的可分性,可以优先作为对比学习的难样本挖掘来源。比如某个簇里95%都是某一种攻击类型,那这个簇内部的样本对就可以当作高质量正对;而那些散落在簇边界、聚类置信度低的样本,恰好是训练判别模型最有价值的难例。
第二种是“聚类信息作为特征或辅助标签”:把k-means输出的簇划分结果,转换成one-hot或软分布特征,拼接到原始特征后面,让对比学习网络更容易捕捉到粗粒度聚合信息。或者更直接一点,把每个样本的“所属簇ID”当作一种伪标签,先做一轮自监督预训练,再用真实标签做有监督微调。这个思路在很多半监督入侵检测工作里都验证过,效果通常比直接训练有监督模型稳定。
所以这个题目的设计逻辑是:k-means不跟对比学习抢饭碗,而是给对比学习“指路”。先用无监督方法低成本地圈出一个大概的数据结构,再让有监督对比学习在这个结构的指导下把特征磨得更精细。最终分类头一接,模型既有全局聚合能力,又有细粒度判别能力,比单纯跑一个MLP或者一棵树要更有说服力,也更容易在毕业论文里讲出故事。
2. 核心原理深度补全与关键技术解析
2.1 从K值的确定到距离度量:k-means绝非跑一遍完事
k-means虽然只有“选中心、分配样本、更新中心”三步循环,但在入侵检测场景里,有三个细节直接决定它能不能真的为对比学习服务。
第一,K值的确定。K选小了,不同攻击类型被强行压到一个簇里,伪标签没有价值;K选大了,一个攻击类型被切成很多份,正样本对里混入不同子类,反而引入噪声。常用的选择手段有肘部法则和轮廓系数,但我在实际项目里更建议“按攻击类型数试探”结合聚类纯度来衡量。比如数据集有4种攻击类型,你可以把K从4开始,每隔2取一个值,算每个簇的内部样本类别纯度(比如簇内占比最高的类别比例),纯度低于0.7说明切得不够干净,需要增大K或增强特征工程。
第二,距离度量。很多人直接用欧氏距离,这在经过标准化的连续特征上勉强可用,但对网络流量数据这种经常混合二值特征(如协议类型、标志位)和连续特征(如字节数、持续时间)的情况,欧氏距离会被量纲差异带偏。通常的解法是:要么先做标准化,要么把离散特征单独编码后再并回向量。比较稳妥的做法是全特征统一做z-score标准化,然后距离度量还选欧氏;如果觉得不够贴合数据的语义,可以试一下余弦距离或曼哈顿距离,但要注意聚类结果和后续对比学习的损失函数是否匹配。如果对比损失用余弦相似度,那距离度量最好也倾向余弦。
第三,初始化策略。k-means++或者多随机种子取最优,这点在常规教程里都有,我不多讲。但有个隐藏坑:入侵检测数据常伴有大量重复流量模式,初始中心选在密集区域很容易让多个簇空转。稳妥的做法是先用Mini-Batch K-Means跑一遍粗聚类,再用结果作为标准k-means的初始中心,既能提速又能减少空簇。
2.2 对比学习到底在优化什么:InfoNCE与温度系数的直觉理解
对比学习的目标是学一个编码器f(x),把输入样本映射到d维特征向量,让这些向量天然满足“同类相近、异类相远”。有监督对比学习最常用的是InfoNCE损失函数的Supervised Contrastive Learning版本,它的直观表达式是这样的:对每个样本i,先从batch里找出所有和它同标签的正样本,把它们构成集合P(i);其他样本就是负样本N(i)。
损失函数会计算i的特征与P(i)里每个正样本的相似度(一般用余弦相似度再除以温度系数τ),取指数后作为分子;然后把i与所有负样本(有时也包括i自身之外的全体样本)的相似度指数和作为分母,最后求负对数。通俗理解就是:我需要让“我跟我同党伙伴的相似度之和”在所有候选里占尽绝对优势。温度系数τ越低,模型越“狠”,会把正对和负对的差异拉到极其悬殊的程度;τ越高,模型对区分困难负样本的重视程度越弱。在入侵检测场景里,由于某些攻击类型流量之间的相似度本来就不高(比如慢速扫描和暴力破解在很多特征维度上几乎一样),τ不宜设得太低,否则模型容易过拟合到少数几个难样本上,导致泛化差。我实验里常用τ=0.1,如果遇到特征特别松散的子类,会适当调到0.2。
这个损失里有一个关键设计点:k-means的作用可以体现在正样本对的权值上。你可以计算两个样本是否属于同一个k-means簇,如果属于同一个簇但标签也相同,那就给这对正样本更高的权重,因为它不仅标签一致,结构上也确实紧密;如果标签相同但聚类分到了不同簇,说明这对样本离散度较大,权重调低一点,防止对比学习硬把这些分离比较远的样本拉近导致特征空间撕裂。
2.3 “有监督”和“无监督”的浆糊怎么搅匀
一个很实际的困惑是:既然有标签,为什么不直接训练分类器,非要绕一圈对比学习?这里边有两层原因。第一层是特征鲁棒性:有监督分类训练得到的特征经常只对当前数据集的分布有效,一旦测试环境里混入新类型攻击,分类器极易翻车;而对比学习学出的特征偏“度量型”,见过类似模式的新攻击时,特征空间里的相对位置会发生可解释的变化,更容易被后续规则或开放集识别捕获。第二层是训练稳定性:入侵检测数据集中大类别不平衡很严重,比如Normal样本可能是某个攻击样本的几十倍,直接做交叉熵分类会让大头类主导梯度,小类攻击很难学精。对比学习因为是按“样本对”计算的,它天然会更多地关注稀有类别之间的两两关系,把稀有攻击的特征也凝聚起来。
那k-means在这里到底提供了什么?核心价值是“低成本的结构假设修正”。比如原始标签只有“Normal / Attack”二分类,却包含多种攻击子类。你直接用二分类标签做有监督对比学习,模型会把所有攻击当成一个大类去拉近,中间不同攻击子类之间的差异被压制,导致检测到某两种攻击时会互相混淆。这时候你拿k-means在攻击子类数据上跑一遍,如果聚出3个明显簇,相当于告诉你:“别管标注怎么写的,数据结构上它至少有三类攻击形态”。把聚类结果作为细粒度伪标签去重新定义对比学习的正对范围,特征空间一下子就能分出层次。
我强烈建议在开题或论文相关工作的部分把这段逻辑讲清楚,因为这是整个算法设计里最容易被答辩老师追问的地方。
3. 数据准备与预处理实战要点
3.1 常用数据集怎么选:从基础版本到高难度版本
网络入侵检测领域标准数据集发展了好几代。最经典的KDD Cup 1999和NSL-KDD,虽然时间比较早,但胜在数据量适中、标签体系完整,容易把算法快速验证起来。它们的特征维度差不多是41维,内容包括协议类型、服务类型、标志位等符号特征,以及传输字节数、连接时长、失败登录次数等数值特征。NSL-KDD相比KDD删掉了一堆重复样本,训练和测试分布也更合理,对初学者友好得多。
再进阶一点的是UNSW-NB15,它是某高校网络环境里抓的真实流量仿真生成,包含9种攻击家族,特征数量扩展到49个左右(有的版本是45个)。这个数据集比KDD复杂得多,特征之间存在高度冗余,很多攻击类型在少量特征上几乎不可分,最适合用来体现你这种“先聚类后对比学习”算法的价值。
UNSW-NB15的具体打法和NSL-KDD肯定不一样。前者有大量端口扫描、Shellcode、蠕虫等类别的样本,这些类在数值特征分布上高度重叠,用朴素聚类很容易把不同攻击混在一起。反过来看,恰恰是这种数据才让k-means伪标签对后续对比学习的指导作用变得可观测。
如果时间充裕,也可以拿CICIDS 2017这种更贴近现代流量的数据集做验证,但那玩意体量很大,特征多达80多个,而且拥有大量BENIGN背景流量,硬件不够的话预处理会比较吃力。
3.2 特征清洗、编码、归一化一条龙
拿到数据的第一件事,不是把数据丢给模型,而是检查特征语义。数值特征和类别特征最好分开处理。Separation的思路是:类别特征(如protocol_type、service、flag)直接用one-hot或者label encoding,但要注意one-hot维度爆炸问题,比如NSL-KDD的service字段有70多个类别,全量one-hot会让特征维度从41膨胀到一百多,反而稀释距离计算的有效性。我的做法是保留出现频次排名前20的service类别做one-hot,其余全部归到“other”桶。这个技巧对后续聚类效果影响很大,因为k-means距离度量对维度极其敏感。
数值特征包含duration、src_bytes、dst_bytes、count、srv_count等,这些特征尺度和分布差异巨大。强烈建议先做log1p变换再z-score标准化。log1p就是把x变成log(1+x),它能把像src_bytes这种从0到数十万的右偏分布压成近似对数正态,防止个别大流量样本成为距离计算中的绝对主导。很多新手直接对原始值做min-max,导致几个大数特征的权重压倒性高,聚类把样本全按字节数切开了,这纯属让特征工程背了算法的锅。
处理完特征之后还需要做一次数据划分上的“纪律检查”:训练集、验证集、测试集必须在同一时间点内划分,不能用全部数据做标准化之后再去划分,否则存在严重的数据泄露。正确流程是先按样本ID或时间戳切出train/val/test三份,再分别计算train子集的均值方差去标准化train、val、test。这个点无论老手新手都容易犯,是答辩前必须自查的地方。
3.3 类别不平衡和样本重叠问题,处理不当会直接影响对比学习
入侵检测数据集的天然痛点就是Normal类样本占比极高,攻击类型中某些类(如U2R、R2L)样本个数可能只有几十个。这对聚类和对比学习都是个大麻烦。
k-means面临的问题是:大类别会把簇中心往自己拉,少数类样本可能被挤到某个大簇边缘,甚至被完全吸收,造成伪标签严重失真。对策一般是先对各类别分别做聚类,或者采用密度聚类来辅助。比如你先针对少数攻击类单独跑DBSCAN,把密集结构找出来,再把这些结构内的样本标记为特定伪标签,其余正常样本用k-means分K个簇。这样主导类别不会破坏弱势类别的内部结构。
有监督对比学习面临的问题是:一个batch里如果全是Normal样本,那正对几乎全是Normal,对比损失无法学习攻击形态的分布。有三种常用手段:第一,加权采样,确保每个batch里攻击类的样本占比不低于某个阈值,比如20%;第二,类别级过采样,用SMOTE生成少量攻击类样本,但必须注意SMOTE本身也可能引入噪声,而且聚类阶段如果用了增强样本,伪标签的可信度要打折;第三,当稀有类样本实在过少时,干脆不在这些单类上做对比学习,只让它们参与最终的分类头训练,避免把度量学习偏置到噪声方向上。
样本重叠是指数据集中存在大量“完全相同或近相同”的流量记录,这些重复记录在不同包里反复出现,如果不做去重,模型会在重复样本上过度自信,聚类里的簇数量也会被虚假放大。NSL-KDD相较于KDD已经大幅去重,但UNSW-NB15仍然存在一定比例的近重复。建议在预处理阶段,先把标准化后的嵌入做一次快速K-Means粗筛,找出某一簇内特征向量几乎成对重复的样本,只保留一条代表记录。这一点投入产出比极高。
4. 算法整体框架与训练流程设计
4.1 分阶段训练:聚类先导、对比中继、分类收尾
整个算法框架如果画成一个流程,大概长这样:原始数据 → 特征工程 → 第一阶段k-means聚类 → 利用聚类结果生成样本对权重/伪标签 → 第二阶段有监督对比学习训练编码器 → 固定编码器并在其输出上训练分类头 → 测试阶段综合评估。
第一阶段,k-means跑在全量训练数据上。这里有一个细节,聚类时要不要带标签?原则上k-means不应该见到标签,但可以在评估时用标签去验证簇纯度。你先决定K值,跑完之后输出每个样本的所属簇ID,同时计算出每个簇内各类样本的占比。簇内占比最大的类别如果超过60%,说明该簇对应某种攻击或者正常行为,这个簇的伪标签就很有意义;如果比较分散,就说明该区域特征混杂,不能强行用伪标签。
第二阶段是对比学习。输入是经过特征编码后的向量,编码器可以采用简单多层感知机,比如隐藏层[128, 64],输出维度d=32或64。为了体现深度,你也可以用一维CNN处理原始字节序列特征,但前提是你把流量负载字段也做成了输入。如果只用统计特征,MLP足够,因为特征维度才几十维,宽度不宽,深度两三层的网络不会比大模型差多少。对比学习中batch size尽量大一些,比如128或256,因为正负对的数量很大程度依赖batch内样本组合,batch太小,正对数量就稀疏。训练时监测验证集上的对比损失,执行早停。
第三阶段是分类头。固定编码器参数,把编码器输出的特征向量作为输入,接一个softmax分类器,也许只有一两层线性层。训练分类头时可以用交叉熵损失,此时特征已经非常紧凑,分类头收敛速度很快,一般十个epoch内就能达到稳定。
整体流程的每一步都有明确“交付物”,这样也方便论文里画框架图和列算法步骤,答辩逻辑能自洽。
4.2 聚类结果如何转成对比学习的“有效辅助信息”
这是整个算法里最核心的钩子,操作方法有很多,我选一种既简洁又有效的组合策略说细一点。
方法名称可以叫“聚类加权有监督对比学习”。具体计算方式如下:
对所有样本i和样本j,如果它们的真实标签相同,它们构成候选正对。此时引入一个额外权重,计算公式是:
- 如果k-means输出中i和j属于同一个簇,那么权重w=1.0;
- 如果它们不属于同一个簇,那权重w=0.5,或者进一步用两个样本所属簇中心的距离做一个decay,中心距离越远权重越低。
把这个权重乘到InfoNCE损失中对应项的分子上,实现“同簇正对更强拉近,跨簇正对弱化拉近”。同时,对于负样本对,如果k-means把它们分到同一个簇但标签不同,说明该区域特征重叠严重,更容易出现难以区分的负对,这部分负样本更需要被模型“推开”,所以可以在分母的负样本相似度项乘一个放大系数,比如1.2。
这个设计与纯有监督对比学习相比,等于在特征空间上加了一个“聚类感知的注意力”,让对比学习更关注结构上可靠的样本对,忽略结构上分散的正对,从而避免模型被坏样本对带偏。我在某次实验里,单纯用这个加权技巧,就在UNSW-NB15的测试集上把F1提升了2~3个百分点,且训练震荡明显减少。
如果你觉得上面的变动太复杂,还有一个简易替代方案:把k-means的簇中心向量跟样本特征拼接。也就是对每个输入,先计算它与所有簇中心的距离向量,得到一个K维距离描述,然后把这个K维向量拼到原始特征上一起进编码器。这个方案实现起来几行代码就能搞定,效果提升虽不如加权法显著,但也能明显改善聚类信息的下游利用率。
4.3 损失函数组合与训练技巧速查
有监督对比学习阶段的主要损失是SCL Loss或者InfoNCE Loss,我前面提到的加权版本属于SCL的变体。分类头训练阶段就是标准交叉熵。如果你想要更加鲁棒的度量空间,还可以在对比学习阶段加上一个辅助的聚类一致性损失,比如鼓励同一簇内样本在编码器输出空间里的分布更紧。不过这个辅助损失并非必需,有时反而会给训练增加额外调试成本,新手阶段建议先不加。
训练策略上,有个不可忽视的细节:对比学习阶段的温度系数和batch大小必须同时调。通常batch越大,温度系数可以越小,因为大batch提供了更丰富的负样本集合,模型对难负样本的区分能力更强。在显存有限的情况下,batch只有64,那就把温度系数拉高一点,避免损失过大梯度爆炸。
编码器输出维度也值得注意。维度太高(如256)会导致小数据集上的对比学习不稳定,特征空间太稀疏,下游分类头难以收敛;维度太低(如8)则表达力不足。入侵检测这种几十维统计特征数据,我建议输出维度定在64附近,不大不小,正好能平衡表达和稳定。
伪代码级别的结构化描述大致如下:读入预处理后的train数据,记录每个样本label;对train全量跑k-means,保存cluster_id和cluster_center;进入对比学习训练循环:取一个batch,编码器算特征;计算相似度矩阵;遍历batch内样本,根据正对集合、加权规则构建loss,反向传播更新编码器;几个epoch后早停;冻结编码器,训练分类头若干轮。这个流程可以完整复现,代码量不大。
5. 实验设计与指标解读
5.1 对照组怎么设,实验才有说服力
为了证明“k-means+有监督对比学习”这个组合的价值,不能只跑自己这个模型然后给个结果,至少需要设四组对照:
第一组:传统机器学习基线,用随机森林或梯度提升树直接在预处理特征上训练分类。 第二组:深度分类基线,直接用MLP搭配交叉熵训练,不加任何对比学习和聚类。 第三组:无聚类指导的有监督对比学习(也就是SCL Loss直接接分类头)。 第四组:完整方法,也就是聚类加权有监督对比学习。
四组算法在完全相同的特征工程、数据划分和评估指标上跑,各自调参到合理水平。这样结果出来之后,你就能从两条线上回答问题:一是加入对比学习是否比直接分类有效;二是加入聚类加权后是否比朴素对比学习更进一步。如果第三组和第四组差距明显,你的设计逻辑就站得住脚。
5.2 核心指标怎么算:微平均F1比准确率重要得多
入侵检测场景不能只看Accuracy。因为Normal占绝大多数,一个把所有样本都判为Normal的废物模型也能有90%以上的准确率。真正该关注的是每个类的精确率(Precision)、召回率(Recall)和F1-score,尤其是攻击类别的平均表现。
对于多分类问题,我推荐两个视角:
- 宏平均(Macro-F1):把每个类别单独算F1再平均,能反映稀有类是否被照顾到。
- 每类F1的柱状图:直接展示模型在U2R、R2L这种稀有小类上的表现,这个图在毕业论文里非常出彩。
此外,如果做二分类的入侵/正常判别,还可以画ROC曲线,计算AUC。但在多分类攻击家族识别上,ROC图就画不及F1的混淆矩阵直观。混淆矩阵按攻击类别排布,一眼就能看出哪些攻击被互相混淆,再和k-means聚类结果对照,你会发现:容易混淆的类往往是k-means里簇纯度较低的类,这个结论可以反过来印证你模型设计的合理性。
还有一点常被忽略:测试集上训练和测试分布存在漂移。UNSW-NB15里有些类只在训练不出现在测试全稀有。为了方便对比,可以在固定测试集之外再构造一个“难子集”,只取训练阶段聚类纯度低且容易混淆的那些攻击类样本,单独看模型在这个难子集上的表现。完整方法的优势通常在这种子集上体现得最明显。
5.3 画图与结果呈现的几条经验
毕业论文或答辩PPT里,不建议贴一堆训练loss曲线就完事。最有效的三张图是:第一张,四组模型在各类攻击上的F1柱状对比图;第二张,完整方法的特征向量在t-SNE降维后的散点图,按攻击类型着色,展示同类聚集、异类分离;第三张,不同K值下聚类纯度与最终F1的关系折线图,证明K值选择不是拍脑袋。
其中t-SNE图的注脚很关键,要标注“特征提取自编码器倒数第二层”。画图时t-SNE困惑度不宜太大,30左右即可,否则细节看不清。散点图如果类数多颜色混杂,可以对主要攻击类型单独画子图。
结果文字描述要避免“比XX模型好”的空洞句式,而是要解释为什么好。比如,如果完整方法比朴素SCL在R2L类上F1高5%,你要说明这是因为k-means在该类流形上发现了两个子簇,把子簇间的差异作为对比学习负对提高了判别敏感性。能讲出这一步,答辩老师会立刻觉得你是真做过实验而不是抄代码。
6. 实操中常见的坑与排查经验
6.1 聚类数K到底怎么选才科学
很多时候同学会跑一个肘部法则,指出K=5最好,就直接用了。但肘部法则只考虑了簇内误差平方和,根本没有考虑后续任务的需求。更好的方法是把K当成超参数,直接以上游任务指标(比如最终的F1)来选择,但这样会带来非常大的计算开销。折中方案是两步走:
第一步,先用轮廓系数和技术经验确定一个K的候选区间,比如4到14。 第二步,在这个区间里跑完整算法(聚类+对比学习+分类头)在验证集上的结果,选最优K。
如果计算资源紧张,可以把对比学习阶段固定用同一个预训练好的聚类模型产生的伪标签做加权,只改K的取值,省去每个K都要重训对比学习的开销。我在UNSW-NB15上试过,最优K通常在8-12之间,低于6时攻击子类严重混合,高于14时单个簇碎片化严重,伪标签稳定性变差。
6.2 对比学习“坍塌”了怎么办
所谓坍塌(Collapse),就是编码器把所有输入都映射到同一个或少数几个特征点,这时候对比损失会很小,但特征什么判别信息都没有。常见表现是训练到第五六个epoch,训练loss下降到很低,但验证集F1却在下降,t-SNE图上所有样本挤成一团。
坍塌的一个主要原因是负样本不够硬或者不够多。解决办法是加大batch,或者使用momentum编码器维护一个负样本队列,但这样做编程复杂度会上升。简单方案是先检查预处理特征中是否存在某个维度方差为0或接近0的列,比如某个标志位在绝大多数样本里都是同一个值,这个维度会把相似度过分拉高,让对比学习误以为所有样本都相似。赶紧把这类低方差特征删掉。第二个常见原因是学习率太高,对比学习的动力学对这种问题极敏感,把学习率降一个数量级,然后观察loss下降是否平滑,基本都能缓解。
如果加了k-means加权之后反而更容易出现坍塌,要重点检查是否正对权重设置过大,导致模型不用看负样本也能量很小,这种情况可以把权重上限从1.0降到0.7,让负样本任务保留足够压力。
6.3 数据泄露:隐蔽但致命,答辩老师一眼就能看穿
数据泄露在毕业设计代码里出现的频率远超想象,常见的有三类。
第一类是预处理时用全量数据做标准化,破坏了train/test间的独立性,前面我已经提过。第二类是在聚类阶段不小心把测试集样本也拿来训练k-means了。如果k-means中心是通过train和test的混合数据算出来的,那测试集的特征信息已经间接透露给了模型,结果虚高但没有意义。第三类更隐蔽:在做倍率过采样时,把少数类的增强样本添加到训练集的同时,又用原始少数类样本做测试集的一部分,导致测试集中存在训练样本的近邻副本,模型对这个类别的召回率虚高得离谱。
稳妥的代码习惯是:所有无监督模型,包括k-means、StandardScaler、PCA,都只能用训练集的数据fit,然后用同样的参数transform验证集和测试集。写一个数据管道类来强制约束,Excel手动处理很容易出错。
6.4 算力受限时的降级方案
如果你的机器是普通笔记本,没有独显或者显存只有几GB,不要直接上超大batch对比学习。可以改用两个技巧:第一,用特征维度较小的编码器,同时调低对比学习温度系数,因为小batch里负样本少,不大可能在有限负样本下撑起足够大的动态范围。第二,分层抽样构建mini-batch,也就是每个batch内固定比例攻击类,再在batch内做样本对扩展(多视图复制),弥补batch不足。
如果聚类阶段数据量太大,比如UNSW-NB15全量几百万行,直接全量k-means几十个迭代也吃不消,可以先在类别标签上做分层抽样,抽个20万样本训练聚类模型,然后把聚类模型直接应用到其余样本。只要你特征分布稳定,聚类中心不会因为抽样发生大幅偏移。
这些降级方案做出来的结果虽然不完全等价于全量版本,但趋势和结论是一致的,足够支撑毕业设计质量。
7. 从毕设到论文:最后几点提醒
这个课题做成之后,论文里除了讲算法,一定不要忘了交代“为什么需要网络入侵检测”、传统机器学习为什么不够、深度学习为什么容易过拟合。完整方法的核心贡献要落到“用无监督结构信息增强有监督度量学习”这一句话上,所有实验分析都要围绕是否验证了这个贡献来展开。
我个人在实际操作中的体会是:这类课题最大的拦路虎往往不是算法本身,而是数据质量和实验规范。把这些问题一个一个解决,训练模型并不难,难的是让实验自洽、逻辑闭环。如果时间允许,建议在对比学习后还加一个“开放集识别”的小实验,也就是用训练中没见过的攻击类型样本去测试,观察模型给出的特征是否跟已知攻击家族在距离上具有一定可分性。这个实验如果做出来,论文的深度一下子就起来了。
最后再分享一个实用小技巧:保存模型时不要只保存准确率最高的那个,要同时保存训练过程中验证集F1最高的那个以及验证集上误报率最低的那个。在答辩前重新评估时,你会发现这两个模型在不同攻击类型上各有长处,把它们做个简单的加权集成,还能把最终指标再往上拉一点。祝你的毕业设计顺利。