文章目录
- 1 前言
- 2 什么是入侵检测系统?
- 3 为什么选择Transformer?
- 4 数据预处理
- 5 模型架构
- 5.1. 输入嵌入层(Input Embedding Layer)
- 5.2. 位置编码层(Positional Encoding Layer)
- 5.3. Transformer编码器层(Transformer Encoder Layer)
- 5.4. 解码层(Decoder Layer)(非Transformer的解码器)
- 5.5.模型的前向传播(Forward Pass)
- 6 模型训练
- 7 结果和分析
- 全部代码
1 前言
随着网络攻击的日益猖獗,保护网络安全变得愈发重要。传统的入侵检测系统(IDS)在应对复杂和多变的攻击模式时显得力不从心。为了应对这一挑战,我们提出了一种基于Transformer的入侵检测系统,以提高检测精度和鲁棒性。
2 什么是入侵检测系统?
入侵检测系统(IDS)是一种监控网络流量、识别和响应潜在安全威胁的工具。它们通过分析流量模式来检测异常行为,从而保护网络安全。然而,随着攻击技术的不断进化,传统的IDS面临着识别新型和复杂攻击的挑战。
CICIDS2017数据集介绍:
https://blog.csdn.net/yuangan1529/article/details/115024003
CICIDS2017数据集下载:
http://205.174.165.80/CICDataset/CIC-IDS-2017/Dataset/CIC-IDS-2017/PCAPs/
下载这个即可:
3 为什么选择Transformer?
Transformer模型最初由Vaswani等人在自然语言处理(NLP)领域提出,以其在处理序列数据方面的优越性能而闻名。与传统的循环神经网络(RNN)和长短期记忆网络(LSTM)相比,Transformer能够更高效地捕捉序列数据中的长距离依赖关系。这一特性使其在网络流量分析中表现出色。
4 数据预处理
我们首先对数据进行了充分的预处理。我们使用了CICIDS2017数据集,这是一个广泛用于网络入侵检测研究的标准数据集。数据预处理步骤包括:
- 数据清洗:去除重复数据和处理缺失值。
- 特征选择:利用相关性分析和基于模型的特征重要性筛选出重要特征。
- 数据标准化:将特征值归一化到相同的范围内,以提高模型训练的稳定性和收敛速度。
5 模型架构
基于Transformer架构,包括以下几个关键部分:
- 输入嵌入:将网络流量数据转换为固定维度的向量表示,同时保留其序列信息。
- 位置编码:通过位置编码保留特征序列的顺序信息。
- 自注意力机制:应用自注意力层,捕捉特征之间的全局依赖关系。
- 编码器-解码器结构:利用堆叠的编码器和解码器层提取特征并进行分类。
- 输出层:通过softmax层输出分类概率。
5.1. 输入嵌入层(Input Embedding Layer)
输入嵌入层将原始的网络流量特征映射到一个固定维度的向量空间中。
self.embedding = nn.Linear(input_dim, model_dim)
- 公式:
E = X W e + b e E = XW_e + b_e E=XWe+be
其中,( X ) 是输入特征矩阵,( W_e ) 和 ( b_e ) 分别是嵌入层的权重矩阵和偏置向量,( E ) 是嵌入向量。
5.2. 位置编码层(Positional Encoding Layer)
位置编码层通过添加位置编码向量来保留序列信息。位置编码向量由正弦和余弦函数生成。
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_len=5000):
super(PositionalEncoding, self).__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-torch.log(torch.tensor(10000.0)) / d_model))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0).transpose(0, 1)
self.register_buffer('pe', pe)
def forward(self, x):
return x + self.pe[:x.size(0), :]
- 公式:
P E ( p o s , 2 i ) = sin ( p o s 1000 0 2 i / d m o d e l ) PE_{(pos, 2i)} = \sin \left( \frac{pos}{10000^{2i/d_{model}}} \right) PE(pos,2i)=sin(100002i/dmodelpos)
P E ( p o s , 2 i + 1 ) = cos ( p o s 1000 0 2 i / d m o d e l ) PE_{(pos, 2i+1)} = \cos \left( \frac{pos}{10000^{2i/d_{model}}} \right) PE(pos,2i+1)=cos(100002i/dmodelpos)
其中,( pos ) 是位置,( i ) 是维度索引。
max_len=5000
中的5000表示序列的最大长度。在Transformer模型中,位置编码用于为输入序列中的每个位置添加一个向量表示其位置信息。这个向量是根据位置编码函数生成的,函数中的参数包括位置和维度索引。
位置编码的作用是为模型提供序列中各个位置的相对位置信息。这对于理解序列中的顺序和间隔是至关重要的。在自注意力机制中,序列中不同位置之间的关系是由位置编码来表示的,而不是像循环神经网络或卷积神经网络那样,通过固定的滑动窗口或循环结构来捕获序列中的顺序信息。
为什么将max_len
设置为5000呢?这主要是为了应对在训练和推理过程中可能遇到的最大序列长度。通常情况下,我们会将max_len
设置为训练数据集中序列的最大长度,以确保所有序列都能够被正确编码。在实际应用中,如果序列长度超过了max_len
,可以通过截断或其他方法进行处理。
下面举一个例子来说明位置编码的作用:
假设有一个长度为4的序列:[ a, b, c, d ],并且我们使用一个4维的位置编码。
位置编码的生成过程如下:
- 对于每个位置 ( pos ),生成一个长度为4的位置编码向量 ( \text{PE}_{(pos)} )。
- 对于每个维度索引 ( i ),根据位置 ( pos ) 计算该维度的位置编码值。
例如,对于维度索引 ( i = 0 ) 和位置 ( pos = 1 ):
[ \text{PE}_{(1, 0)} = \sin \left( \frac{1}{10000^{0/4}} \right) = \sin(1) ]
[ \text{PE}_{(1, 1)} = \cos \left( \frac{1}{10000^{0/4}} \right) = \cos(1) ]
[ \text{PE}_{(1, 2)} = \sin \left( \frac{1}{10000^{2/4}} \right) = \sin(1/100) ]
[ \text{PE}_{(1, 3)} = \cos \left( \frac{1}{10000^{2/4}} \right) = \cos(1/100) ]
这样,每个位置都被赋予了一个唯一的位置编码向量,这些向量将会在模型的训练和推理过程中与输入的特征向量相结合,从而帮助模型更好地理解序列中各个位置的相对关系。
5.3. Transformer编码器层(Transformer Encoder Layer)
Transformer编码器层由多个自注意力层和前馈神经网络层堆叠而成。
encoder_layers = nn.TransformerEncoderLayer(d_model=model_dim, nhead=num_heads)
self.transformer_encoder = nn.TransformerEncoder(encoder_layers, num_layers)
-
自注意力机制公式:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dkQKT)V
其中,( Q, K, V ) 分别是查询矩阵、键矩阵和值矩阵,( d_k ) 是键的维度。 -
前馈神经网络公式:
FFN ( x ) = max ( 0 , x W 1 + b 1 ) W 2 + b 2 \text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2 FFN(x)=max(0,xW1+b1)W2+b2
其中,( W_1, W_2 ) 和 ( b_1, b_2 ) 是前馈神经网络的权重矩阵和偏置向量。
5.4. 解码层(Decoder Layer)(非Transformer的解码器)
解码层将编码器的输出转换为最终的分类结果。
self.decoder = nn.Linear(model_dim, num_classes)
- 公式:
y ^ = E W d + b d \hat{y} = EW_d + b_d y^=EWd+bd
其中,( E ) 是编码器的输出,( W_d ) 和 ( b_d ) 分别是解码层的权重矩阵和偏置向量,( \hat{y} ) 是预测的分类结果。
5.5.模型的前向传播(Forward Pass)
def forward(self, x):
x = self.embedding(x)
x = self.pos_encoder(x)
x = self.transformer_encoder(x)
x = self.decoder(x)
return x
- 嵌入层输出:
E = X W e + b e E = XW_e + b_e E=XWe+be - 位置编码输出:
E ′ = E + P E E' = E + PE E′=E+PE - 编码器输出:
Z = TransformerEncoder ( E ′ ) Z = \text{TransformerEncoder}(E') Z=TransformerEncoder(E′) - 解码层输出(非Transformer的解码器):
y ^ = Z W d + b d \hat{y} = ZW_d + b_d y^=ZWd+bd
6 模型训练
在模型训练过程中,我们使用了交叉熵损失函数和Adam优化器。通过在训练集和验证集上的迭代训练,逐步调整模型参数,以达到最佳性能。
7 结果和分析
我们的模型在CICIDS2017数据集上的表现优异,显著提高了入侵检测的准确性和鲁棒性。以下是一些关键结果:
- 准确率:模型在测试集上的准确率达到了98.7%。
- 召回率:针对不同类型攻击的召回率均超过了97%。
- F1分数:综合考虑精确率和召回率,模型的F1分数达到了98.2%。
全部代码
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2