PyTorch实战:KDD_Cup99入侵检测数据集二分类任务保姆级教程

张开发
2026/4/12 14:27:49 15 分钟阅读

分享文章

PyTorch实战:KDD_Cup99入侵检测数据集二分类任务保姆级教程
PyTorch实战KDD_Cup99入侵检测数据集二分类任务保姆级教程网络安全领域的数据科学家们常常需要处理海量的网络流量数据而KDD_Cup99数据集作为经典的入侵检测基准数据集至今仍被广泛用于机器学习模型的验证。本文将带你从零开始使用PyTorch框架完成一个完整的二分类任务实战涵盖数据预处理、模型构建、训练优化等全流程。1. 数据集准备与理解KDD_Cup99数据集源自1999年DARPA入侵检测评估项目包含模拟军事网络环境中各种攻击类型的网络连接记录。对于初学者而言理解这个数据集的结构和特点是首要任务。数据集包含41个特征和1个类别标签其中数值型特征如连接持续时间(duration)、源字节数(src_bytes)等类别型特征如协议类型(protocol_type)、服务类型(service)等标签标记为normal.或具体的攻击类型关键注意事项训练集包含23种标签1种正常22种攻击测试集包含38种标签1种正常37种攻击有19种攻击类型仅在测试集中出现# 数据集基本信息 print(f训练集样本数: {len(train_data)}) print(f测试集样本数: {len(test_data)}) print(f特征数量: {len(feature_columns)})2. 数据预处理实战数据预处理是机器学习项目中最为关键的环节之一对于KDD_Cup99这样的复杂数据集尤为如此。我们需要解决类别不平衡、特征尺度差异、类别编码等问题。2.1 特征工程处理首先对原始数据进行以下处理删除无用特征第19列(num_outbound_cmds)全为0直接删除类别特征编码对protocol_type、service、flag等类别特征进行标签编码数值特征归一化将所有数值特征缩放到[0,1]范围from sklearn.preprocessing import LabelEncoder, MinMaxScaler # 类别特征编码 cat_features [1, 2, 3] # protocol_type, service, flag for col in cat_features: le LabelEncoder() data[col] le.fit_transform(data[col]) # 数值特征归一化 num_features [col for col in range(41) if col not in cat_features and col ! 19] scaler MinMaxScaler() data[num_features] scaler.fit_transform(data[num_features])2.2 标签处理策略针对二分类任务我们需要将复杂的多类别标签简化为正常(normal.) → 1所有攻击类型 → 0# 二分类标签处理 data[label] data[class].apply(lambda x: 1 if x normal. else 0)3. PyTorch模型构建现在我们可以开始构建神经网络模型。考虑到数据集特征较多但样本量庞大我们采用一个中等规模的MLP网络。3.1 网络架构设计import torch.nn as nn class IntrusionDetectionModel(nn.Module): def __init__(self, input_size): super().__init__() self.net nn.Sequential( nn.Linear(input_size, 128), nn.ReLU(), nn.Dropout(0.2), nn.Linear(128, 256), nn.ReLU(), nn.Dropout(0.2), nn.Linear(256, 128), nn.ReLU(), nn.Linear(128, 2) ) def forward(self, x): return self.net(x)3.2 数据加载器准备PyTorch的DataLoader能有效管理批量数据加载from torch.utils.data import TensorDataset, DataLoader # 转换为PyTorch张量 features torch.FloatTensor(data.drop([class, label], axis1).values) labels torch.LongTensor(data[label].values) # 创建数据集和数据加载器 dataset TensorDataset(features, labels) train_loader DataLoader(dataset, batch_size64, shuffleTrue)4. 模型训练与评估4.1 训练配置我们使用交叉熵损失和Adam优化器并添加学习率调度import torch.optim as optim from torch.optim.lr_scheduler import ReduceLROnPlateau model IntrusionDetectionModel(input_size40) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) scheduler ReduceLROnPlateau(optimizer, min, patience3)4.2 训练循环实现def train_epoch(model, loader, criterion, optimizer, device): model.train() running_loss 0.0 correct 0 total 0 for inputs, labels in loader: inputs, labels inputs.to(device), labels.to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() _, predicted torch.max(outputs.data, 1) total labels.size(0) correct (predicted labels).sum().item() return running_loss/len(loader), correct/total4.3 模型评估指标除了准确率我们还应该关注以下指标指标公式意义精确率TP/(TPFP)预测为正例中实际为正的比例召回率TP/(TPFN)实际正例中被正确预测的比例F1分数2*(精确率*召回率)/(精确率召回率)精确率和召回率的调和平均from sklearn.metrics import classification_report def evaluate(model, loader, device): model.eval() all_preds [] all_labels [] with torch.no_grad(): for inputs, labels in loader: inputs, labels inputs.to(device), labels.to(device) outputs model(inputs) _, preds torch.max(outputs, 1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) print(classification_report(all_labels, all_preds))5. 进阶优化技巧5.1 类别不平衡处理KDD_Cup99数据集存在严重的类别不平衡问题。我们可以采用以下策略加权损失函数为少数类别分配更高权重过采样/欠采样调整样本分布集成方法如Bagging或Boosting# 计算类别权重 class_counts data[label].value_counts() weights 1. / class_counts weights weights / weights.sum() * len(class_counts) # 应用到损失函数 criterion nn.CrossEntropyLoss(weighttorch.FloatTensor(weights).to(device))5.2 特征选择优化原始41个特征中部分可能对分类贡献不大。我们可以使用特征重要性分析from sklearn.ensemble import RandomForestClassifier # 使用随机森林评估特征重要性 rf RandomForestClassifier() rf.fit(features.numpy(), labels.numpy()) # 可视化特征重要性 plt.figure(figsize(12, 6)) plt.bar(range(len(rf.feature_importances_)), rf.feature_importances_) plt.xticks(ticksrange(len(feature_columns)), labelsfeature_columns, rotation90) plt.title(Feature Importance) plt.show()5.3 模型架构改进可以考虑以下改进方向更深的网络结构增加隐藏层数和神经元数量批归一化层加速训练并提高稳定性注意力机制让模型关注重要特征集成学习结合多个模型的预测结果class ImprovedModel(nn.Module): def __init__(self, input_size): super().__init__() self.net nn.Sequential( nn.Linear(input_size, 256), nn.BatchNorm1d(256), nn.ReLU(), nn.Dropout(0.3), nn.Linear(256, 512), nn.BatchNorm1d(512), nn.ReLU(), nn.Dropout(0.3), nn.Linear(512, 256), nn.BatchNorm1d(256), nn.ReLU(), nn.Linear(256, 2) ) def forward(self, x): return self.net(x)6. 实际部署考量当模型训练完成后我们需要考虑如何在实际环境中部署和使用它模型序列化保存训练好的模型参数推理优化使用TorchScript提高推理效率监控系统持续监控模型性能定期更新随着网络环境变化更新模型# 保存模型 torch.save(model.state_dict(), intrusion_detection_model.pth) # 加载模型 loaded_model IntrusionDetectionModel(input_size40) loaded_model.load_state_dict(torch.load(intrusion_detection_model.pth)) loaded_model.eval()在真实项目中我发现将模型封装为API服务是最高效的部署方式。使用Flask或FastAPI创建REST端点可以方便地集成到现有安全系统中。同时建议设置一个定期重新训练的机制因为网络攻击模式会随时间演变。

更多文章