diff --git a/LYZ/BiLSTM.py b/LYZ/BiLSTM.py
new file mode 100644
index 0000000..32f1078
--- /dev/null
+++ b/LYZ/BiLSTM.py
@@ -0,0 +1,185 @@
+"""
+Task: 基于Bi-LSTM和注意力机制的文本情感分类
+Author: ChengJunkai @github.com/Cheng0829
+Email: chengjunkai829@gmail.com
+Date: 2022/09/14
+Reference: Tae Hwan Jung(Jeff Jung) @graykode
+"""
+
+import numpy as np
+import torch, time, os, sys
+import torch.nn as nn
+import torch.optim as optim
+import torch.nn.functional as F
+import matplotlib.pyplot as plt
+
+'''1.数据预处理'''
+
+
+def pre_process(sentences):
+ word_sequence = " ".join(sentences).split()
+ word_list = []
+ '''
+ 如果用list(set(word_sequence))来去重,得到的将是一个随机顺序的列表(因为set无序),
+ 这样得到的字典不同,保存的上一次训练的模型很有可能在这一次不能用
+ (比如上一次的模型预测碰见i:0,love:1,就输出you:2,但这次模型you在字典3号位置,也就无法输出正确结果)
+ '''
+ for word in word_sequence:
+ if word not in word_list:
+ word_list.append(word)
+ word_dict = {w: i for i, w in enumerate(word_list)}
+ word_dict["''"] = len(word_dict)
+ word_list = word_list.append("''")
+ vocab_size = len(word_dict) # 词库大小16
+ max_size = 0
+ for sen in sentences:
+ if len(sen.split()) > max_size:
+ max_size = len(sen.split()) # 最大长度3
+ for i in range(len(sentences)):
+ if len(sentences[i].split()) < max_size:
+ sentences[i] = sentences[i] + " ''" * (max_size - len(sentences[i].split()))
+
+ return sentences, word_list, word_dict, vocab_size, max_size
+
+
+def make_batch(sentences):
+ # 对于每个句子,返回包含句子内每个单词序号的列表
+ inputs = [np.array([word_dict[n] for n in sen.split()]) for sen in sentences] # [6,3]
+ targets = [out for out in labels]
+ inputs = torch.LongTensor(np.array(inputs)).to(device)
+ targets = torch.LongTensor(np.array(targets)).to(device)
+ '''情感分类构建嵌入矩阵,没有eye()'''
+ return inputs, targets
+
+
+class BiLSTM_Attention(nn.Module):
+ def __init__(self):
+ super(BiLSTM_Attention, self).__init__()
+ '''情感分类构建嵌入矩阵,没有eye()'''
+ self.embedding = nn.Embedding(vocab_size, embedding_dim)
+ self.lstm = nn.LSTM(embedding_dim, n_hidden, bidirectional=True)
+ self.out = nn.Linear(2 * n_hidden, num_classes)
+
+ def forward(self, X): # X: [6, 3]
+ # input : [batch_size, n_step, embedding_dim] [6,3,2]
+ input = self.embedding(X)
+ # input : [n_step, batch_size, embedding_dim] [3,6,2]
+ # input : [输入序列长度(时间步长度),样本数,嵌入向量维度]
+ input = input.permute(1, 0, 2)
+ # hidden_state : [num_layers(=1)*num_directions(=2), batch_size, n_hidden]
+ # hidden_state : [层数*网络方向,样本数,隐藏层的维度(隐藏层神经元个数)]
+ hidden_state = torch.zeros(1 * 2, len(X), n_hidden).to(device)
+ # cell_state : [num_layers*num_directions, batch_size, hidden_size]
+ # cell_state : [层数*网络方向,样本数,隐藏层的维度(隐藏层神经元个数)]
+ cell_state = torch.zeros(1 * 2, len(X), n_hidden).to(device)
+ # final_hidden_state, final_cell_state : [num_layers(=1)*num_directions(=2), batch_size, n_hidden]
+ ltsm_output, (final_hidden_state, final_cell_state) = self.lstm(input, (hidden_state, cell_state))
+ # ltsm_output : [batch_size, n_step, n_hidden*num_directions(=2)]
+ ltsm_output = ltsm_output.permute(1, 0, 2)
+ attn_output, attention = self.attention_net(ltsm_output, final_hidden_state)
+ # model : [batch_size, num_classes], attention : [batch_size, n_step]
+ return self.out(attn_output), attention
+
+ '''两次bmm加权求和,相当于两次for循环'''
+
+ # lstm_output : [batch_size, n_step, n_hidden*num_directions(=2)] [6,3,16]
+ # final_hidden_state : [num_layers(=1)*num_directions(=2), batch_size, n_hidden] [2,6,8]
+ def attention_net(self, lstm_output, final_hidden_state):
+ # final_hidden_state : [batch_size, n_hidden*num_directions(=2), 1(=n_layer)] [6,16,1]
+ final_hidden_state = final_hidden_state.view(-1, 2 * n_hidden, 1)
+
+ '''第一次bmm加权求和:: lstm_output和final_hidden_state生成注意力权重attn_weights'''
+ # [6,3,16]*[6,16,1] -> [6,3,1] -> attn_weights : [batch_size, n_step] [6,3]
+ attn_weights = torch.bmm(lstm_output, final_hidden_state).squeeze(2) # 第3维度降维
+ softmax_attn_weights = F.softmax(attn_weights, 1) # 按列求值 [6,3]
+
+ '''第二次bmm加权求和 : lstm_output和注意力权重attn_weights生成上下文向量context,即融合了注意力的模型输出'''
+ # [batch_size, n_hidden*num_directions, n_step] * [batch_size,n_step,1] \
+ # = [batch_size, n_hidden*num_directions, 1] : [6,16,3] * [6,3,1] -> [6,16,1] -> [6,16]
+ context = torch.bmm(lstm_output.transpose(1, 2), softmax_attn_weights.unsqueeze(2)).squeeze(2)
+ softmax_attn_weights = softmax_attn_weights.to('cpu') # numpy变量只能在cpu上
+
+ '''各个任务求出context之后的步骤不同,LSTM的上下文不需要和Seq2Seq中的一样和decoder_output连接'''
+ return context, softmax_attn_weights.data.numpy()
+
+
+if __name__ == '__main__':
+ chars = 30 * '*'
+ embedding_dim = 3 # embedding size
+ n_hidden = 8 # number of hidden units in one cell
+ num_classes = 2 # 0 or 1
+ '''GPU比CPU慢的原因大致为:
+ 数据传输会有很大的开销,而GPU处理数据传输要比CPU慢,
+ 而GPU在矩阵计算上的优势在小规模神经网络中无法明显体现出来
+ '''
+ device = ['cuda:0' if torch.cuda.is_available() else 'cpu'][0]
+ # 3 words sentences (=sequence_length is 3)
+ sentences = ["i love you", "he loves me", "don't leave",
+ "i hate you", "sorry for that", "this is awful"]
+ labels = [1, 1, 1, 0, 0, 0] # 1 is good, 0 is not good.
+
+ '''1.数据预处理'''
+ sentences, word_list, word_dict, vocab_size, max_size = pre_process(sentences)
+ inputs, targets = make_batch(sentences)
+
+ '''2.构建模型'''
+ model = BiLSTM_Attention()
+ print(model)
+ model.to(device)
+ criterion = nn.CrossEntropyLoss() # 交叉熵损失
+ optimizer = optim.Adam(model.parameters(), lr=0.001)
+
+ if os.path.exists('model_param.pt'):
+ # 加载模型参数到模型结构
+ model.load_state_dict(torch.load('model_param.pt', map_location=device))
+
+ '''3.训练'''
+ print('{}\nTrain\n{}'.format('*' * 30, '*' * 30))
+ loss_record = []
+ for epoch in range(10000):
+ optimizer.zero_grad()
+ output, attention = model(inputs)
+ output = output.to(device)
+ loss = criterion(output, targets)
+ loss.backward()
+ optimizer.step()
+ # print(loss)
+ if loss >= 0.001: # 连续30轮loss小于0.01则提前结束训练
+ loss_record = []
+ else:
+ loss_record.append(loss.item())
+ if len(loss_record) == 30:
+ torch.save(model.state_dict(), 'model_param.pt')
+ break
+
+ if (epoch + 1) % 1000 == 0:
+ print('Epoch:', '%04d' % (epoch + 1), 'Loss = {:.6f}'.format(loss))
+ torch.save(model.state_dict(), 'model_param.pt')
+
+ '''4.测试'''
+ print('{}\nTest\n{}'.format('*' * 30, '*' * 30))
+ test_text = 'sorry i hate you'
+ # 返回包含每个单词序号的列表矩阵(为了有2个维度,还要加一个中括号升维)
+ tests = [np.array([word_dict[n] for n in test_text.split()])]
+ test_batch = torch.LongTensor(np.array(tests)).to(device)
+ predict, attn_test = model(test_batch)
+ predict = predict.data.max(1, keepdim=True)[1]
+ print('The emotion of "%s" is ' % test_text, end='')
+ if predict[0][0] == 0:
+ print('bad!')
+ else:
+ print('good!')
+
+ '''5.可视化注意力权重矩阵'''
+ fig = plt.figure(figsize=(0.5 * len(sentences), 0.5 * len(sentences[0]))) # [batch_size, n_step]
+ ax = fig.add_subplot(1, 1, 1)
+ # attention : (6, 3)
+ ax.matshow(attention, cmap='viridis')
+ word_show = ['单词'] * len(sentences[0])
+ word_show = [word_show[i] + str(i + 1) for i in range(len(sentences[0]))] # ['word_1', 'word_2', 'word_3']
+ ax.set_xticklabels([''] + word_show, fontdict={'fontsize': 14}, fontproperties='SimSun')
+ sentence_show = ['句子'] * len(sentences)
+ sentence_show = [sentence_show[i] + str(i + 1) for i in range(
+ len(sentence_show))] # ['sentence_1', 'sentence_2', 'sentence_3', 'sentence_4', 'sentence_5', 'sentence_6']
+ ax.set_yticklabels([''] + sentence_show, fontdict={'fontsize': 14}, fontproperties='SimSun')
+ plt.show()
diff --git a/LYZ/FCN_Transformer.py b/LYZ/FCN_Transformer.py
new file mode 100644
index 0000000..e56962c
--- /dev/null
+++ b/LYZ/FCN_Transformer.py
@@ -0,0 +1,530 @@
+# -*- coding: utf-8 -*-
+"""
+Transformer编码器网络并行构建两个并行卷积神经网络(CNN)来对流量数据进行识别。将CNN用于空间特征表示, Transformer用于时间特征表示。
+
+由于数据的顺序性质, 我们还将使用Transformer尝试尽可能准确地模拟情绪中音调转换之间的时间关系。
+
+堆叠的CNN网络结合了来自变压器编码器的多头自关注层。
+
+**利用CNN在空间特征表示方面的优势和Transformer在序列编码方面的优势
+
+改进:并行化CNN,或者借鉴bert双向结构
+#### Setup
+"""
+
+import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import os, glob, time
+import pickle
+from timeit import default_timer as timer
+
+# matplot lib complains about librosa
+import warnings
+warnings.filterwarnings('ignore')
+
+
+# classes index
+traffic_dict ={
+ 0: 'Normal',
+ 1: 'BFSSH',
+ 2: 'Infilt',
+ 3: 'HttpDoS',
+ 4: 'DDoS'
+}
+
+# network traffic attributes
+traffic_attributes = {
+ '01': 'normal', # 正常流量
+ '02': 'anomaly' # abnormal
+}
+
+"""## Load Data
+"""
+
+# path to data for glob
+DATA_DIR = 'D:\\PyProject\\malware_traffic\\3_Packet\\'
+
+def load_data():
+ """
+ 加载数据
+ :return:
+ """
+ t1 = timer()
+ sessions = []
+ labels = []
+ num_pkls = len(glob.glob(DATA_DIR + 'ISCX2012_labels_*.pkl')) # 匹配路径
+ for i in range(num_pkls):
+ # if i != 1:
+ # continue
+ session_pkl = DATA_DIR + 'ISCX2012_pcaps_' + str(i) + '.pkl'
+ session_lists = pickle.load(open(session_pkl, 'rb')) # 反序列化对象
+ sessions.extend(session_lists.values.tolist()) # 追加元素
+
+ label_pkl = DATA_DIR + 'ISCX2012_labels_' + str(i) + '.pkl'
+ label_lists = pickle.load(open(label_pkl, 'rb'))
+ labels.extend(label_lists.values.tolist())
+ print(i)
+ t2 = timer()
+ print("load data tims: ", t2 - t1)
+
+ labels = np.array(labels)
+ normal_indices = np.where(labels == 0)[0] # 结果所在的 行, 是个array
+ # 数据量太大, 不好训练。以下注释代码可以选择100000条正常流量进入训练(建议在数据预处理阶段选择一定数量的正常数据——节约内存开支)
+ normal_indices = np.random.choice(normal_indices, 100000, replace=False) # 注释代码
+ attack_indices = [np.where(labels == i)[0] for i in range(1, 5)] # label 1~4 所在行, 是个 list
+ # np.random.choice 会重复抽样, 若想不重复, 增加参数:replace=False
+ test_normal_indices = np.random.choice(normal_indices, int(len(normal_indices) * 0.4), replace=False)
+ test_attack_indices = np.concatenate( # 模态融合
+ [np.random.choice(attack_indices[i], int(len(attack_indices[i]) * 0.4), replace=False) for i in range(4)])
+ test_indices = np.concatenate([test_normal_indices, test_attack_indices]).astype(int)
+ # train_indices = np.array(list(set(np.arange(len(labels))) - set(test_indices)))
+ attack_indices = np.concatenate(attack_indices).astype(int) # 注释代码
+ indices = np.concatenate([normal_indices, attack_indices]).astype(int) # 注释代码
+ train_indices = np.array(list(set(indices) - set(test_indices))) # 注释代码
+
+ return sessions, labels, train_indices, test_indices
+
+
+
+"""# Architecture Overview
+
+# CNN Motivation
+** 构建两个并行卷积神经网络(CNN)来对流量数据进行空间特征表示
+
+# Transformer-Encoder Motivation
+**使用了Transformer-Encoder层
+**I maxpool 映射到Transformer, 以大大减少网络需要学习的参数数量
+"""
+
+
+class ByteBlock(nn.Module):
+ """
+ 1D FCN: 1维全卷积神经网络
+
+ in_channels:输入通道数, 在一维卷积中由于不存在通道数, 因此in_channels的数值为词向量的维度, 如果一个单词用128维向量表示, 那么in_channels = 128
+
+ out_channels:输出通道数, 表示经过卷积之后, 一个词向量嵌入维度应该为多少。如果out_channels = 64, 那么经过本次卷积之后的每个词的嵌入维度为64。
+
+ kernel_size:卷积核大小, 表示本次卷积核的维度, 一般是赋值为int类型。kernel_size=3, 表示每次卷积计算操作涉及到3个词, 也就是卷积核维度被设为(in_channels, kernel_size)。
+ - 在Pytorch中, 对于一条语句序列数据的每个词都是用一个列向量表示
+
+ stride:滑动步长, 表示在卷积方向上滑动的步长。stride=2, 表示在当前卷积的范围为123, 下一个卷积范围就是345。
+
+ padding:填补操作, 表示在对特征矩阵剩余部分不足卷积时的操作。
+ - str --> padding =“valid”:表示不填充, 剩余部分丢弃。 padding =“same”:表示在右侧填充之后要求输入输出序列长度一致
+ - int --> padding = k: 表示在右侧填充k列
+ """
+ def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
+ subsample=(2, 1), pool_length=(2, 2)):
+ super(ByteBlock, self).__init__()
+
+ layers = []
+ for i in range(len(nb_filter)):
+ layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
+ padding=0, stride=subsample[i]))
+ layers.append(nn.Tanh())
+ if pool_length[i]:
+ layers.append(nn.MaxPool1d(pool_length[i]))
+ in_channels = nb_filter[i]
+
+ self.block = nn.Sequential(*layers)
+ self.global_pool = nn.AdaptiveMaxPool1d(1)
+
+
+ def forward(self, x):
+ x = self.block(x)
+ x = self.global_pool(x).squeeze(dim=2)
+ x = torch.nn.functional.leaky_relu(x)
+ return x
+
+class FCN_Transformer(nn.Module):
+ # Define all layers present in the network
+ def __init__(self,num_emotions):
+ super().__init__()
+
+ ################ TRANSFORMER BLOCK #############################
+ self.transformer_maxpool = nn.MaxPool1d(2)
+
+ # define single transformer encoder layer
+ transformer_layer = nn.TransformerEncoderLayer(
+ d_model=128, # 输入特征维度
+ nhead=4, # 注意力头数
+ dim_feedforward=512, # 前馈神经网络中隐藏层的维度。
+ dropout=0.2,
+ activation='relu'
+ )
+
+ # Using 4 identical stacked encoder layers
+ self.transformer_encoder = nn.TransformerEncoder(transformer_layer, num_layers=4)
+
+ # 1 sequential conv1D layers
+ self.conv1Dblock1 = ByteBlock(128, (128, 256), (5, 5), (1, 1), (2, 2))
+ self.conv1Dblock2 = ByteBlock(128, (192, 320), (7, 5), (1, 1), (2, 2))
+
+ self.fc1_linear = nn.Linear(512*2+40,num_emotions)
+
+ ### Softmax layer for the n output logits from final FC linear layer
+ self.softmax_out = nn.Softmax(dim=1)
+
+ # define one complete parallel fwd pass of input feature tensor thru 2*conv+1*transformer blocks
+ def forward(self,x):
+
+ conv1d_embedding1 = self.conv1Dblock1(x) # x == N/batch * channel * freq * time
+
+ conv1d_embedding1 = torch.flatten(conv1d_embedding1, start_dim=1)
+
+ conv1d_embedding2 = self.conv1Dblock2(x)
+
+ conv1d_embedding2 = torch.flatten(conv1d_embedding2, start_dim=1)
+
+
+ ########## 4-encoder-layer Transformer block ##############
+ x_maxpool = self.transformer_maxpool(x)
+
+ x_maxpool_reduced = torch.squeeze(x_maxpool,1)
+
+ # convert maxpooled feature map format: batch * freq * time ---> time * batch * freq format
+ # because transformer encoder layer requires tensor in format: time * batch * embedding (freq)
+ x = x_maxpool_reduced.permute(2,0,1)
+ # print("x_maxpool_reduced: ",x_maxpool_reduced.shape)
+
+ transformer_output = self.transformer_encoder(x)
+
+ transformer_embedding = torch.mean(transformer_output, dim=0) # dim
+
+ complete_embedding = torch.cat([conv1d_embedding1, conv1d_embedding2,transformer_embedding], dim=1)
+
+ output_logits = self.fc1_linear(complete_embedding)
+
+ output_softmax = self.softmax_out(output_logits)
+
+ return output_logits, output_softmax
+
+
+"""# 查看模型结构
+"""
+from torchsummary import summary
+
+# need device to instantiate model
+device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+
+# instantiate model for 8 emotions and move to CPU for summary
+model = FCN_Transformer(len(traffic_dict)).to(device)
+print("\nmodel: \n", model)
+# include input feature map dims in call to summary()
+summary(model, input_size=(128,200,512))
+
+
+"""## Define Loss/Criterion
+"""
+# define loss function; CrossEntropyLoss() fairly standard for multiclass problems
+def criterion(predictions, targets):
+ return nn.CrossEntropyLoss()(input=predictions, target=targets)
+
+"""## Choose Optimizer
+https://github.com/IliaZenkov/transformer-cnn-emotion-recognition/blob/main/Parallel_is_All_You_Want.py
+有说为什么选SGD
+# optimizer = torch.optim.SGD(model.parameters(),lr=0.01, weight_decay=1e-3, momentum=0.8)
+"""
+optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
+
+
+"""## Define Training Step
+定义了一个函数来返回单个训练步骤, 定义了模型的一次迭代。
+ 1、正向传递输出logits和softmax概率。
+ 2、记录softmax概率以跟踪准确性。
+ 3、将输出logits传递给损失函数以计算损失。
+ 4、调用带损失函数的反向传递(反向传播错误)。
+ 5、告诉优化器对网络参数应用一个更新步骤。
+ 6、为下一次迭代将优化器中的累积梯度归零。
+"""
+# define function to create a single step of the training phase
+def make_train_step(model, criterion, optimizer):
+
+ # define the training step of the training phase
+ def train_step(X,Y):
+
+ # forward pass
+ output_logits, output_softmax = model(X)
+ predictions = torch.argmax(output_softmax,dim=1)
+ accuracy = torch.sum(Y==predictions)/float(len(Y))
+
+ # compute loss on logits because nn.CrossEntropyLoss implements log softmax
+ loss = criterion(output_logits, Y)
+
+ # compute gradients for the optimizer to use
+ loss.backward()
+
+ # update network parameters based on gradient stored (by calling loss.backward())
+ optimizer.step()
+
+ # zero out gradients for next pass
+ # pytorch accumulates gradients from backwards passes
+ optimizer.zero_grad()
+
+ return loss.item(), accuracy*100
+ return train_step
+
+"""## Define Validation Step
+定义一个函数, 在10%的X,y张量对上返回一个验证步骤, 以了解模型在训练时的泛化性, 以便确定是否以及何时停止它并调整超参数。
+通过将model设置为验证模式来确保在验证过程中不更新网络参数。不要在验证阶段通过设置torch.no_grad()来浪费资源计算梯度。
+"""
+def make_validate_fnc(model,criterion):
+ def validate(X,Y):
+
+ # don't want to update any network parameters on validation passes: don't need gradient
+ # wrap in torch.no_grad to save memory and compute in validation phase:
+ with torch.no_grad():
+
+ # set model to validation phase i.e. turn off dropout and batchnorm layers
+ model.eval()
+
+ # get the model's predictions on the validation set
+ output_logits, output_softmax = model(X)
+ predictions = torch.argmax(output_softmax,dim=1)
+
+ # calculate the mean accuracy over the entire validation set
+ accuracy = torch.sum(Y==predictions)/float(len(Y))
+
+ # compute error from logits (nn.crossentropy implements softmax)
+ loss = criterion(output_logits,Y)
+
+ return loss.item(), accuracy*100, predictions
+ return validate
+
+"""# Make Checkpoint Functions
+在每个epoch之后保存模型状态的检查点。当对模型的性能感到满意时, 可以中断训练并加载适当的模型二进制文件。
+
+-硬件/软件故障恢复培训
+-通过调整后从检查点进行训练来保存计算重新训练
+-通过保持模型最高性能版本的快照, 轻松实现早期停止
+"""
+def make_save_checkpoint():
+ def save_checkpoint(optimizer, model, epoch, filename):
+ checkpoint_dict = {
+ 'optimizer': optimizer.state_dict(),
+ 'model': model.state_dict(),
+ 'epoch': epoch
+ }
+ torch.save(checkpoint_dict, filename)
+ return save_checkpoint
+
+def load_checkpoint(optimizer, model, filename):
+ checkpoint_dict = torch.load(filename)
+ epoch = checkpoint_dict['epoch']
+ model.load_state_dict(checkpoint_dict['model'])
+ if optimizer is not None:
+ optimizer.load_state_dict(checkpoint_dict['optimizer'])
+ return epoch
+
+"""# Build Training Loop
+使用训练和验证步骤函数构建完整的训练循环。
+
+
+训练循环逻辑:
+
+ --Setup--
+ 实例化 model.
+ 实例化模型训练和验证步骤, loss function 和 optimizer.
+ Move model to GPU.
+
+ --Epoch--
+ 在每个epoch后验证阶段完成后, 将模型设置为训练模式。
+ Shuffle 每个epoch的训练集, 重置epoch损失和精度。
+
+ --Iteration--
+ 维每次迭代创建 mini_batch 的 X_train, y_train 张量, 并将张量移动到GPU。
+ Take 1 train step with X_train, y_train minibatch tensors.
+ 汇总每次迭代的准确性和损失, 但只在每个epoch之后记录。
+
+ --Epoch--
+ 计算并记录整个epoch的验证精度, 以跟踪学习进度。
+ 在每个epoch之后打印训练指标。
+"""
+
+# get training set size to calculate # iterations and minibatch indices
+train_size = X_train.shape[0]
+
+# pick minibatch size (of 32... always)
+minibatch = 32
+
+# set device to GPU
+device = 'cuda' if torch.cuda.is_available() else 'cpu'
+print(f'{device} selected')
+
+# instantiate model and move to GPU for training
+model = FCN_Transformer(num_emotions=len(traffic_dict)).to(device)
+print('Number of trainable params: ',sum(p.numel() for p in model.parameters()) )
+
+# instantiate the checkpoint save function
+save_checkpoint = make_save_checkpoint()
+
+# instantiate the training step function
+train_step = make_train_step(model, criterion, optimizer=optimizer)
+
+# instantiate the validation loop function
+validate = make_validate_fnc(model,criterion)
+
+# instantiate lists to hold scalar performance metrics to plot later
+train_losses=[]
+valid_losses = []
+
+# create training loop for one complete epoch (entire training set)
+def train(optimizer, model, num_epochs, X_train, Y_train, X_valid, Y_valid):
+
+ for epoch in range(num_epochs):
+
+ # set model to train phase
+ model.train()
+
+ # shuffle entire training set in each epoch to randomize minibatch order
+ ind = np.random.permutation(train_size)
+
+ # shuffle the training set for each epoch:
+ X_train = X_train[ind,:,:,:]
+ Y_train = Y_train[ind]
+
+ # instantiate scalar values to keep track of progress after each epoch so we can stop training when appropriate
+ epoch_acc = 0
+ epoch_loss = 0
+ num_iterations = int(train_size / minibatch)
+
+ # create a loop for each minibatch of 32 samples:
+ for i in range(num_iterations):
+
+ # we have to track and update minibatch position for the current minibatch
+ # if we take a random batch position from a set, we almost certainly will skip some of the data in that set
+ # track minibatch position based on iteration number:
+ batch_start = i * minibatch
+ # ensure we don't go out of the bounds of our training set:
+ batch_end = min(batch_start + minibatch, train_size)
+ # ensure we don't have an index error
+ actual_batch_size = batch_end-batch_start
+
+ # get training minibatch with all channnels and 1D feature dims
+ X = X_train[batch_start:batch_end,:,:,:]
+ # get training minibatch labels
+ Y = Y_train[batch_start:batch_end]
+
+ # instantiate training tensors
+ X_tensor = torch.tensor(X, device=device).float()
+ Y_tensor = torch.tensor(Y, dtype=torch.long,device=device)
+
+ # Pass input tensors thru 1 training step (fwd+backwards pass)
+ loss, acc = train_step(X_tensor,Y_tensor)
+
+ # aggregate batch accuracy to measure progress of entire epoch
+ epoch_acc += acc * actual_batch_size / train_size
+ epoch_loss += loss * actual_batch_size / train_size
+
+ # keep track of the iteration to see if the model's too slow
+ print('\r'+f'Epoch {epoch}: iteration {i}/{num_iterations}',end='')
+
+ # create tensors from validation set
+ X_valid_tensor = torch.tensor(X_valid,device=device).float()
+ Y_valid_tensor = torch.tensor(Y_valid,dtype=torch.long,device=device)
+
+ # calculate validation metrics to keep track of progress; don't need predictions now
+ valid_loss, valid_acc, _ = validate(X_valid_tensor,Y_valid_tensor)
+
+ # accumulate scalar performance metrics at each epoch to track and plot later
+ train_losses.append(epoch_loss)
+ valid_losses.append(valid_loss)
+
+ # Save checkpoint of the model
+ checkpoint_filename = './checkpoints/FCN_TransformerFINAL-{:03d}.pkl'.format(epoch)
+ save_checkpoint(optimizer, model, epoch, checkpoint_filename)
+
+ # keep track of each epoch's progress
+ print(f'\nEpoch {epoch} --- loss:{epoch_loss:.3f}, Epoch accuracy:{epoch_acc:.2f}%, Validation loss:{valid_loss:.3f}, Validation accuracy:{valid_acc:.2f}%')
+
+# choose number of epochs higher than reasonable so we can manually stop training
+num_epochs = 100
+
+# train it!
+train(optimizer, model, num_epochs, X_train, y_train, X_valid, y_valid)
+
+"""# Check the Loss Curve's Behaviour
+Let's see if we missed something egregious during training.
+"""
+plt.title('Loss Curve for Model')
+plt.ylabel('Loss', fontsize=16)
+plt.xlabel('Epoch', fontsize=16)
+plt.plot(train_losses[:],'b')
+plt.plot(valid_losses[:],'r')
+plt.legend(['Training loss','Validation loss'])
+plt.show()
+
+
+"""
+# 加载训练好的模型进行验证
+"""
+# pick load folder
+load_folder = './checkpoints'
+
+# pick the epoch to load
+epoch = '60'
+model_name = f'FCN_TransformerFINAL-{epoch}.pkl'
+
+# make full load path
+load_path = os.path.join(load_folder, model_name)
+
+## instantiate empty model and populate with params from binary
+model = FCN_Transformer(len(traffic_dict))
+load_checkpoint(optimizer, model, load_path)
+
+print(f'Loaded model from {load_path}')
+
+"""# Evaluate the Model on Hold-Out Test Set
+"""
+
+# reinitialize validation function with model from chosen checkpoint
+validate = make_validate_fnc(model,criterion)
+
+# Convert 4D test feature set array to tensor and move to GPU
+X_test_tensor = torch.tensor(X_test,device=device).float()
+# Convert 4D test label set array to tensor and move to GPU
+y_test_tensor = torch.tensor(y_test,dtype=torch.long,device=device)
+
+# Get the model's performance metrics using the validation function we defined
+test_loss, test_acc, predicted_emotions = validate(X_test_tensor,y_test_tensor)
+
+print(f'Test accuracy is {test_acc:.2f}%')
+
+"""
+# Analyze Performance on Test Set
+"""
+
+from sklearn.metrics import confusion_matrix
+import seaborn as sn
+
+# because model tested on GPU, move prediction tensor to CPU then convert to array
+predicted_emotions = predicted_emotions.cpu().numpy()
+# use labels from test set
+emotions_groundtruth = y_test
+
+# build confusion matrix and normalized confusion matrix
+conf_matrix = confusion_matrix(emotions_groundtruth, predicted_emotions)
+conf_matrix_norm = confusion_matrix(emotions_groundtruth, predicted_emotions,normalize='true')
+
+# set labels for matrix axes from emotions
+emotion_names = [emotion for emotion in traffic_dict.values()]
+
+# make a confusion matrix with labels using a DataFrame
+confmatrix_df = pd.DataFrame(conf_matrix, index=emotion_names, columns=emotion_names)
+confmatrix_df_norm = pd.DataFrame(conf_matrix_norm, index=emotion_names, columns=emotion_names)
+
+# plot confusion matrices
+plt.figure(figsize=(16,6))
+sn.set(font_scale=1.8) # emotion label and title size
+plt.subplot(1,2,1)
+plt.title('Confusion Matrix')
+sn.heatmap(confmatrix_df, annot=True, annot_kws={"size": 18}) #annot_kws is value font
+plt.subplot(1,2,2)
+plt.title('Normalized Confusion Matrix')
+sn.heatmap(confmatrix_df_norm, annot=True, annot_kws={"size": 13}) #annot_kws is value font
+
+plt.show()
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/ChangeLog.txt b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/ChangeLog.txt
new file mode 100644
index 0000000..4ed8402
--- /dev/null
+++ b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/ChangeLog.txt
@@ -0,0 +1,14 @@
+2013-11-09 SplitCap 2.1
+
+ * Support for reading PCAP data from stdin with "-r -", for example in order to run:
+ tcpdump -i eth0 -w - | mono SplitCap.exe -r -
+
+2013-06-25 SplitCap 2.0
+
+ * Changed from "\\" to System.IO.Path.DirectorySeparatorChar in order to run better
+ on Linux and other non-Windows platforms.
+ Hint: use Mono framework to run SplitCap in Linux.
+ Installation in Ubuntu with: apt-get install libmono2.0-cil
+
+ * Added "-s seconds " and "-s packets " to split pcap files based on
+ time or packet count (much like editcap).
\ No newline at end of file
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/LICENSE-SplitCap.txt b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/LICENSE-SplitCap.txt
new file mode 100644
index 0000000..e1ec0e5
--- /dev/null
+++ b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/LICENSE-SplitCap.txt
@@ -0,0 +1,19 @@
+Copyright 2008-2011, Erik Hjelmvik
+SplitCap is available from http://www.netresec.com/?page=SplitCap
+
+SOFTWARE LICENSE
+
+SplitCap is licensed under the GNU General Public License Version 3.
+http://www.gnu.org/licenses/gpl.html
+
+SplitCap uses the assemblies PacketParser and PcapFileHandler, which both stem
+from the NetworkMiner open source network forensics application available at:
+http://networkminer.sourceforge.net/
+
+The SplitCap open source project space is available on SourceForge:
+http://sourceforge.net/projects/splitcap/
+
+
+SplitCap was initially created as part of the Statistical Protocol IDentification
+research project carried out by Erik Hjelmvik with fundings from .SE.
+More info on .SE is available at: http://www.iis.se/en/
\ No newline at end of file
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/NetworkWrapper.dll b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/NetworkWrapper.dll
new file mode 100644
index 0000000..dc4a758
Binary files /dev/null and b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/NetworkWrapper.dll differ
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PacketParser.dll b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PacketParser.dll
new file mode 100644
index 0000000..241d55c
Binary files /dev/null and b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PacketParser.dll differ
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PcapFileHandler.dll b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PcapFileHandler.dll
new file mode 100644
index 0000000..877d8a2
Binary files /dev/null and b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/PcapFileHandler.dll differ
diff --git a/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/SplitCap.exe b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/SplitCap.exe
new file mode 100644
index 0000000..f0ce620
Binary files /dev/null and b/LYZ/Pacp-deal/0_Tool/SplitCap_2-1/SplitCap.exe differ
diff --git a/LYZ/Pacp-deal/0_Tool/finddupe.exe b/LYZ/Pacp-deal/0_Tool/finddupe.exe
new file mode 100644
index 0000000..479854c
Binary files /dev/null and b/LYZ/Pacp-deal/0_Tool/finddupe.exe differ
diff --git a/LYZ/Pacp-deal/1-1_ProcessFlow.py b/LYZ/Pacp-deal/1-1_ProcessFlow.py
new file mode 100644
index 0000000..41475a8
--- /dev/null
+++ b/LYZ/Pacp-deal/1-1_ProcessFlow.py
@@ -0,0 +1,55 @@
+# Author: @vinesmsuic
+#
+#
+
+import os
+import shutil
+from tqdm import tqdm
+import random
+import argparse
+
+def parser():
+ parser = argparse.ArgumentParser(description="Copying files")
+ parser.add_argument("--limit", type=int, required=False, default=-1, help="only copy a number of files each folder")
+ return parser.parse_args()
+
+def main():
+ args = parser()
+
+ src_dir = os.path.join('2_Flow','AllLayers')
+ dst_dir = os.path.join('2_Flow_Processed','AllLayers')
+
+ if not os.path.exists(dst_dir):
+ os.makedirs(dst_dir)
+
+ folders = os.listdir(src_dir)
+ for folder in folders:
+
+ if not os.path.exists(os.path.join(dst_dir,folder)):
+ os.makedirs(os.path.join(dst_dir,folder))
+
+ if(os.path.isdir(os.path.join(dst_dir,folder))):
+
+ print("Now Processing Folder: ", folder)
+
+ copying_folders = os.listdir(os.path.join(src_dir,folder))
+
+ random.seed(72)
+ random.shuffle(copying_folders)
+
+ if(args.limit!= -1):
+ if(len(copying_folders) > args.limit):
+ copying_folders = copying_folders[:args.limit]
+ elif(len(copying_folders) < args.limit):
+ print("Folder "+str(folder), "does not have required "+str(args.limit) + "files. Folder only has "+str(len(copying_folders)) + " files.")
+
+
+
+ for f in tqdm(copying_folders):
+ full_file_name = os.path.join(src_dir, folder, f)
+ if os.path.isfile(full_file_name):
+ shutil.copy(full_file_name, os.path.join(dst_dir, folder))
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/LYZ/Pacp-deal/1_Pcap/Facetime.pcap b/LYZ/Pacp-deal/1_Pcap/Facetime.pcap
new file mode 100644
index 0000000..0ee8a28
Binary files /dev/null and b/LYZ/Pacp-deal/1_Pcap/Facetime.pcap differ
diff --git a/LYZ/Pacp-deal/1_Pcap2Flow.ps1 b/LYZ/Pacp-deal/1_Pcap2Flow.ps1
new file mode 100644
index 0000000..5e1c981
--- /dev/null
+++ b/LYZ/Pacp-deal/1_Pcap2Flow.ps1
@@ -0,0 +1,17 @@
+foreach($f in gci 1_Pcap *.pcap)
+{
+ echo "Now processing file : $f"
+ 0_Tool\SplitCap_2-1\SplitCap -p 100000 -b 100000 -r $f.FullName -s flow -o 2_Flow\AllLayers\$($f.BaseName)-ALL
+ #0_Tool\SplitCap_2-1\SplitCap -p 100000 -b 100000 -r $f.FullName -s flow -o 2_Flow\L7\$($f.BaseName)-L7 -y L7
+
+ echo "Done Spliting! Now Clearing 0KB size files..."
+ # Delete pcap files length equal to 0
+ gci 2_Flow\AllLayers\$($f.BaseName)-ALL | ?{$_.Length -eq 0} | del
+ echo "-------------------------------------------------"
+}
+
+echo "Now Eliminating duplicate flows..."
+# Eliminate duplicate Flows
+0_Tool\finddupe -del 2_Flow\AllLayers
+echo "-------------------------------------------------"
+echo "Finished"
diff --git a/LYZ/Pacp-deal/2_Flow/.gitkeep b/LYZ/Pacp-deal/2_Flow/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-117_16403_1-2-0-211_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-117_16403_1-2-0-211_16403.pcap
new file mode 100644
index 0000000..c4c56b6
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-117_16403_1-2-0-211_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-122_16403_1-2-1-2_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-122_16403_1-2-1-2_16403.pcap
new file mode 100644
index 0000000..33bd884
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-122_16403_1-2-1-2_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-12_16403_1-2-0-120_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-12_16403_1-2-0-120_16403.pcap
new file mode 100644
index 0000000..0737a51
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-12_16403_1-2-0-120_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-133_16403_1-2-0-227_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-133_16403_1-2-0-227_16403.pcap
new file mode 100644
index 0000000..c79680f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-133_16403_1-2-0-227_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-140_16403_1-2-0-249_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-140_16403_1-2-0-249_16403.pcap
new file mode 100644
index 0000000..eeec342
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-140_16403_1-2-0-249_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-147_16403_1-2-181-5_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-147_16403_1-2-181-5_16403.pcap
new file mode 100644
index 0000000..7c547a1
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-147_16403_1-2-181-5_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-149_16403_1-2-0-244_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-149_16403_1-2-0-244_16403.pcap
new file mode 100644
index 0000000..9675651
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-149_16403_1-2-0-244_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-1-177_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-1-177_16403.pcap
new file mode 100644
index 0000000..e349e8a
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-1-177_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-181-17_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-181-17_16403.pcap
new file mode 100644
index 0000000..3d45d0f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-153_16403_1-2-181-17_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-160_16403_1-2-0-254_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-160_16403_1-2-0-254_16403.pcap
new file mode 100644
index 0000000..4b3dce5
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-160_16403_1-2-0-254_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-176_16403_1-2-1-202_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-176_16403_1-2-1-202_16403.pcap
new file mode 100644
index 0000000..8c89364
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-176_16403_1-2-1-202_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-20_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-20_16403.pcap
new file mode 100644
index 0000000..951331d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-20_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-34_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-34_16403.pcap
new file mode 100644
index 0000000..2606044
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-182_16403_1-2-1-34_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-199_16403_1-2-1-52_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-199_16403_1-2-1-52_16403.pcap
new file mode 100644
index 0000000..cea6e2e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-199_16403_1-2-1-52_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-19_16403_1-2-0-113_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-19_16403_1-2-0-113_16403.pcap
new file mode 100644
index 0000000..c763436
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-19_16403_1-2-0-113_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-21_16403_1-2-0-129_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-21_16403_1-2-0-129_16403.pcap
new file mode 100644
index 0000000..3652731
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-21_16403_1-2-0-129_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-234_16403_1-2-1-100_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-234_16403_1-2-1-100_16403.pcap
new file mode 100644
index 0000000..84990f7
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-234_16403_1-2-1-100_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-248_16403_1-2-1-86_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-248_16403_1-2-1-86_16403.pcap
new file mode 100644
index 0000000..b232955
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-248_16403_1-2-1-86_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-37_16403_1-2-180-146_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-37_16403_1-2-180-146_16403.pcap
new file mode 100644
index 0000000..d423549
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-37_16403_1-2-180-146_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-43_16403_1-2-180-168_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-43_16403_1-2-180-168_16403.pcap
new file mode 100644
index 0000000..9ae1e15
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-43_16403_1-2-180-168_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-45_16403_1-2-180-153_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-45_16403_1-2-180-153_16403.pcap
new file mode 100644
index 0000000..1eb02a2
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-45_16403_1-2-180-153_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-58_16403_1-2-0-152_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-58_16403_1-2-0-152_16403.pcap
new file mode 100644
index 0000000..38cf532
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-58_16403_1-2-0-152_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-74_16403_1-2-0-182_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-74_16403_1-2-0-182_16403.pcap
new file mode 100644
index 0000000..e636b97
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-74_16403_1-2-0-182_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-77_16403_1-2-0-171_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-77_16403_1-2-0-171_16403.pcap
new file mode 100644
index 0000000..7573349
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-77_16403_1-2-0-171_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap
new file mode 100644
index 0000000..682dd96
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-80_16403_1-2-0-174_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-80_16403_1-2-0-174_16403.pcap
new file mode 100644
index 0000000..1525fbb
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-80_16403_1-2-0-174_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-87_16403_1-2-0-192_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-87_16403_1-2-0-192_16403.pcap
new file mode 100644
index 0000000..5166335
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-87_16403_1-2-0-192_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-96_16403_1-2-0-235_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-96_16403_1-2-0-235_16403.pcap
new file mode 100644
index 0000000..3d5deb6
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-96_16403_1-2-0-235_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-99_16403_1-2-0-207_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-99_16403_1-2-0-207_16403.pcap
new file mode 100644
index 0000000..8690ba8
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-0-99_16403_1-2-0-207_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-128_16403_1-2-181-234_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-128_16403_1-2-181-234_16403.pcap
new file mode 100644
index 0000000..3092014
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-128_16403_1-2-181-234_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-142_16403_1-2-2-17_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-142_16403_1-2-2-17_16403.pcap
new file mode 100644
index 0000000..c4c997c
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-142_16403_1-2-2-17_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-181_16403_1-2-182-33_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-181_16403_1-2-182-33_16403.pcap
new file mode 100644
index 0000000..f6b97d1
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-181_16403_1-2-182-33_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-200_16403_1-2-182-41_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-200_16403_1-2-182-41_16403.pcap
new file mode 100644
index 0000000..bc82353
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-200_16403_1-2-182-41_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-209_16403_1-2-2-78_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-209_16403_1-2-2-78_16403.pcap
new file mode 100644
index 0000000..6362bb3
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-209_16403_1-2-2-78_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-212_16403_1-2-182-66_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-212_16403_1-2-182-66_16403.pcap
new file mode 100644
index 0000000..490cf07
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-212_16403_1-2-182-66_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-216_16403_1-2-2-52_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-216_16403_1-2-2-52_16403.pcap
new file mode 100644
index 0000000..356ab12
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-216_16403_1-2-2-52_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-217_16403_1-2-2-53_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-217_16403_1-2-2-53_16403.pcap
new file mode 100644
index 0000000..7d4e291
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-217_16403_1-2-2-53_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-223_16403_1-2-182-221_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-223_16403_1-2-182-221_16403.pcap
new file mode 100644
index 0000000..5bc08dc
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-223_16403_1-2-182-221_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-228_16403_1-2-182-92_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-228_16403_1-2-182-92_16403.pcap
new file mode 100644
index 0000000..992f92d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-228_16403_1-2-182-92_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-27_16403_1-2-181-137_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-27_16403_1-2-181-137_16403.pcap
new file mode 100644
index 0000000..126614b
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-27_16403_1-2-181-137_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-33_16403_1-2-181-141_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-33_16403_1-2-181-141_16403.pcap
new file mode 100644
index 0000000..8ac311d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-33_16403_1-2-181-141_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-72_16403_1-2-1-166_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-72_16403_1-2-1-166_16403.pcap
new file mode 100644
index 0000000..e35015b
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-72_16403_1-2-1-166_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-88_16403_1-2-1-196_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-88_16403_1-2-1-196_16403.pcap
new file mode 100644
index 0000000..5e72160
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-88_16403_1-2-1-196_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-91_16403_1-2-1-185_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-91_16403_1-2-1-185_16403.pcap
new file mode 100644
index 0000000..5d08770
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-1-91_16403_1-2-1-185_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-101_16403_1-2-10-209_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-101_16403_1-2-10-209_16403.pcap
new file mode 100644
index 0000000..17ca860
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-101_16403_1-2-10-209_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-10-220_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-10-220_16403.pcap
new file mode 100644
index 0000000..a3eb6de
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-10-220_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-11-113_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-11-113_16403.pcap
new file mode 100644
index 0000000..ae18b9a
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-109_16403_1-2-11-113_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-130_16403_1-2-190-236_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-130_16403_1-2-190-236_16403.pcap
new file mode 100644
index 0000000..340736d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-130_16403_1-2-190-236_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-131_16403_1-2-10-225_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-131_16403_1-2-10-225_16403.pcap
new file mode 100644
index 0000000..4a0a526
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-131_16403_1-2-10-225_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-132_16403_1-2-10-226_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-132_16403_1-2-10-226_16403.pcap
new file mode 100644
index 0000000..3468a2d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-132_16403_1-2-10-226_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-148_16403_1-2-11-0_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-148_16403_1-2-11-0_16403.pcap
new file mode 100644
index 0000000..68d5852
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-148_16403_1-2-11-0_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-14_16403_1-2-10-120_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-14_16403_1-2-10-120_16403.pcap
new file mode 100644
index 0000000..60b0258
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-14_16403_1-2-10-120_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-160_16403_1-2-10-254_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-160_16403_1-2-10-254_16403.pcap
new file mode 100644
index 0000000..52dea6c
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-160_16403_1-2-10-254_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-161_16403_1-2-11-176_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-161_16403_1-2-11-176_16403.pcap
new file mode 100644
index 0000000..b814533
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-161_16403_1-2-11-176_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-185_16403_1-2-191-26_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-185_16403_1-2-191-26_16403.pcap
new file mode 100644
index 0000000..162e05c
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-185_16403_1-2-191-26_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-204_16403_1-2-11-59_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-204_16403_1-2-11-59_16403.pcap
new file mode 100644
index 0000000..f6222dd
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-204_16403_1-2-11-59_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-207_16403_1-2-191-71_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-207_16403_1-2-191-71_16403.pcap
new file mode 100644
index 0000000..d4143b4
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-207_16403_1-2-191-71_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-20_16403_1-2-10-146_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-20_16403_1-2-10-146_16403.pcap
new file mode 100644
index 0000000..8051b4f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-20_16403_1-2-10-146_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-220_16403_1-2-11-58_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-220_16403_1-2-11-58_16403.pcap
new file mode 100644
index 0000000..ef960c6
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-220_16403_1-2-11-58_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-238_16403_1-2-11-76_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-238_16403_1-2-11-76_16403.pcap
new file mode 100644
index 0000000..75ee008
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-238_16403_1-2-11-76_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-244_16403_1-2-11-97_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-244_16403_1-2-11-97_16403.pcap
new file mode 100644
index 0000000..da2d550
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-244_16403_1-2-11-97_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-252_16403_1-2-11-90_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-252_16403_1-2-11-90_16403.pcap
new file mode 100644
index 0000000..173528e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-252_16403_1-2-11-90_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-2_16403_1-2-10-113_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-2_16403_1-2-10-113_16403.pcap
new file mode 100644
index 0000000..4e8a04e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-2_16403_1-2-10-113_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-45_16403_1-2-10-153_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-45_16403_1-2-10-153_16403.pcap
new file mode 100644
index 0000000..71e20a3
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-45_16403_1-2-10-153_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-47_16403_1-2-10-155_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-47_16403_1-2-10-155_16403.pcap
new file mode 100644
index 0000000..951e840
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-47_16403_1-2-10-155_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-86_16403_1-2-10-178_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-86_16403_1-2-10-178_16403.pcap
new file mode 100644
index 0000000..63cced2
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-10-86_16403_1-2-10-178_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-11_16403_1-2-100-119_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-11_16403_1-2-100-119_16403.pcap
new file mode 100644
index 0000000..e0dfbca
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-11_16403_1-2-100-119_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-128_16403_1-2-209-143_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-128_16403_1-2-209-143_16403.pcap
new file mode 100644
index 0000000..ebcac36
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-128_16403_1-2-209-143_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-130_16403_1-2-100-224_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-130_16403_1-2-100-224_16403.pcap
new file mode 100644
index 0000000..9ba679f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-130_16403_1-2-100-224_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-134_16403_1-2-100-244_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-134_16403_1-2-100-244_16403.pcap
new file mode 100644
index 0000000..c9001fa
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-134_16403_1-2-100-244_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-135_16403_1-2-100-245_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-135_16403_1-2-100-245_16403.pcap
new file mode 100644
index 0000000..43a28d6
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-135_16403_1-2-100-245_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-101-12_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-101-12_16403.pcap
new file mode 100644
index 0000000..c4cb98c
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-101-12_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-209-1_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-209-1_16403.pcap
new file mode 100644
index 0000000..eed9fa5
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-160_16403_1-2-209-1_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-165_16403_1-2-209-33_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-165_16403_1-2-209-33_16403.pcap
new file mode 100644
index 0000000..895f731
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-165_16403_1-2-209-33_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-194_16403_1-2-209-47_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-194_16403_1-2-209-47_16403.pcap
new file mode 100644
index 0000000..abca031
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-194_16403_1-2-209-47_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-214_16403_1-2-101-209_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-214_16403_1-2-101-209_16403.pcap
new file mode 100644
index 0000000..24d8742
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-214_16403_1-2-101-209_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-216_16403_1-2-209-66_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-216_16403_1-2-209-66_16403.pcap
new file mode 100644
index 0000000..4b0d26e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-216_16403_1-2-209-66_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-245_16403_1-2-101-83_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-245_16403_1-2-101-83_16403.pcap
new file mode 100644
index 0000000..fb602d5
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-245_16403_1-2-101-83_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-32_16403_1-2-208-141_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-32_16403_1-2-208-141_16403.pcap
new file mode 100644
index 0000000..6705d1b
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-32_16403_1-2-208-141_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-41_16403_1-2-100-135_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-41_16403_1-2-100-135_16403.pcap
new file mode 100644
index 0000000..dca458e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-41_16403_1-2-100-135_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-44_16403_1-2-100-168_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-44_16403_1-2-100-168_16403.pcap
new file mode 100644
index 0000000..c0a3f52
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-44_16403_1-2-100-168_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-48_16403_1-2-100-142_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-48_16403_1-2-100-142_16403.pcap
new file mode 100644
index 0000000..6f79756
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-48_16403_1-2-100-142_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-62_16403_1-2-208-172_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-62_16403_1-2-208-172_16403.pcap
new file mode 100644
index 0000000..d8ce127
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-62_16403_1-2-208-172_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-69_16403_1-2-208-179_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-69_16403_1-2-208-179_16403.pcap
new file mode 100644
index 0000000..c7ad7ad
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-69_16403_1-2-208-179_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-72_16403_1-2-208-179_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-72_16403_1-2-208-179_16403.pcap
new file mode 100644
index 0000000..9f8d9b1
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-72_16403_1-2-208-179_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-86_16403_1-2-100-194_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-86_16403_1-2-100-194_16403.pcap
new file mode 100644
index 0000000..538f759
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-100-86_16403_1-2-100-194_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-14_16403_1-2-101-108_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-14_16403_1-2-101-108_16403.pcap
new file mode 100644
index 0000000..c05a4f0
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-14_16403_1-2-101-108_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-165_16403_1-2-102-171_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-165_16403_1-2-102-171_16403.pcap
new file mode 100644
index 0000000..351f844
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-165_16403_1-2-102-171_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-16_16403_1-2-101-124_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-16_16403_1-2-101-124_16403.pcap
new file mode 100644
index 0000000..b788fa5
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-16_16403_1-2-101-124_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-170_16403_1-2-102-9_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-170_16403_1-2-102-9_16403.pcap
new file mode 100644
index 0000000..ab24167
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-170_16403_1-2-102-9_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-182_16403_1-2-102-20_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-182_16403_1-2-102-20_16403.pcap
new file mode 100644
index 0000000..8640769
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-182_16403_1-2-102-20_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-185_16403_1-2-102-23_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-185_16403_1-2-102-23_16403.pcap
new file mode 100644
index 0000000..75789ae
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-185_16403_1-2-102-23_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-187_16403_1-2-102-38_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-187_16403_1-2-102-38_16403.pcap
new file mode 100644
index 0000000..e2de0d6
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-187_16403_1-2-102-38_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-195_16403_1-2-210-47_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-195_16403_1-2-210-47_16403.pcap
new file mode 100644
index 0000000..aa2b04c
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-195_16403_1-2-210-47_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-214_16403_1-2-102-68_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-214_16403_1-2-102-68_16403.pcap
new file mode 100644
index 0000000..eecbd5d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-214_16403_1-2-102-68_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-227_16403_1-2-102-82_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-227_16403_1-2-102-82_16403.pcap
new file mode 100644
index 0000000..3cf7214
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-227_16403_1-2-102-82_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-230_16403_1-2-102-216_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-230_16403_1-2-102-216_16403.pcap
new file mode 100644
index 0000000..5c52cf3
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-230_16403_1-2-102-216_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-232_16403_1-2-102-100_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-232_16403_1-2-102-100_16403.pcap
new file mode 100644
index 0000000..c57c86f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-232_16403_1-2-102-100_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-234_16403_1-2-102-72_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-234_16403_1-2-102-72_16403.pcap
new file mode 100644
index 0000000..7c64d53
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-234_16403_1-2-102-72_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-236_16403_1-2-210-102_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-236_16403_1-2-210-102_16403.pcap
new file mode 100644
index 0000000..a37528e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-236_16403_1-2-210-102_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-101-159_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-101-159_16403.pcap
new file mode 100644
index 0000000..c8a8630
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-101-159_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-209-175_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-209-175_16403.pcap
new file mode 100644
index 0000000..0230a3f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-47_16403_1-2-209-175_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-59_16403_1-2-101-153_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-59_16403_1-2-101-153_16403.pcap
new file mode 100644
index 0000000..1de7c23
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-59_16403_1-2-101-153_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-68_16403_1-2-209-165_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-68_16403_1-2-209-165_16403.pcap
new file mode 100644
index 0000000..9084002
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-68_16403_1-2-209-165_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-8_16403_1-2-101-116_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-8_16403_1-2-101-116_16403.pcap
new file mode 100644
index 0000000..7741b3f
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-101-8_16403_1-2-101-116_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-114_16403_1-2-102-209_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-114_16403_1-2-102-209_16403.pcap
new file mode 100644
index 0000000..9ed8a0d
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-114_16403_1-2-102-209_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-115_16403_1-2-102-223_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-115_16403_1-2-102-223_16403.pcap
new file mode 100644
index 0000000..7eba0e5
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-115_16403_1-2-102-223_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-120_16403_1-2-102-228_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-120_16403_1-2-102-228_16403.pcap
new file mode 100644
index 0000000..8df004e
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-120_16403_1-2-102-228_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-155_16403_1-2-211-24_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-155_16403_1-2-211-24_16403.pcap
new file mode 100644
index 0000000..c4affb7
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers - 副本/Facetime-ALL/Facetime.pcap.UDP_1-1-102-155_16403_1-2-211-24_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow/AllLayers/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap b/LYZ/Pacp-deal/2_Flow/AllLayers/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap
new file mode 100644
index 0000000..682dd96
Binary files /dev/null and b/LYZ/Pacp-deal/2_Flow/AllLayers/Facetime-ALL/Facetime.pcap.UDP_1-1-0-7_16403_1-2-180-145_16403.pcap differ
diff --git a/LYZ/Pacp-deal/2_Flow2Packet.py b/LYZ/Pacp-deal/2_Flow2Packet.py
new file mode 100644
index 0000000..b540c5a
--- /dev/null
+++ b/LYZ/Pacp-deal/2_Flow2Packet.py
@@ -0,0 +1,160 @@
+# Author: @vinesmsuic
+#
+#
+
+import dpkt
+import numpy as np
+import pandas as pd
+import os
+from tqdm import tqdm
+import argparse
+import random
+
+def parser():
+ parser = argparse.ArgumentParser(description="Selecting Parameter of Packets and Bytes.")
+ parser.add_argument("--packet", type=int, required=True, help="number of required packets")
+ parser.add_argument("--byte", type=int, required=True, help="number of trimmed byte")
+ parser.add_argument("--limit", type=int, required=False, default=-1, help="only extract packets from the largest N flows")
+ return parser.parse_args()
+
+# Sanitization
+def zero_mask_packet(eth_packet):
+
+ #Mask MAC Address to 00:00:00:00:00:00
+ eth_packet.src = b'\x00\x00\x00\x00\x00\x00'
+ eth_packet.dst = b'\x00\x00\x00\x00\x00\x00'
+
+ if(eth_packet.data.__class__.__name__ == 'IP6'):
+ #Mask IPv6 Address to 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
+ eth_packet.data.src = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+ eth_packet.data.dst = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+ else:
+ #Mask IPv4 Address to 0.0.0.0
+ eth_packet.data.src = b'\x00\x00\x00\x00'
+ eth_packet.data.dst = b'\x00\x00\x00\x00'
+
+ return eth_packet
+
+# Extract Information
+def get_packets(pcap, packetnum, target_length):
+
+ r_num = 0
+ packetlist = []
+
+ # For each packet in the pcap process the contents
+ for ts, buf in pcap:
+
+ r_num += 1
+
+ eth_packet = dpkt.ethernet.Ethernet(buf)
+ eth_packet = zero_mask_packet(eth_packet)
+
+ byte_buf = bytes(eth_packet)
+
+ trimmed_buf = trimming(byte_buf, target_length=target_length)
+
+ packetlist.append(trimmed_buf)
+
+ if(r_num == packetnum):
+ break
+
+ # If number of packets is lesser than our requirements, pad a whole packet of zeros
+ if(r_num < packetnum):
+ for _ in range(packetnum - r_num):
+ paddings = bytes(target_length)
+ packetlist.append(paddings)
+
+ return packetlist
+
+
+def trimming(byte, target_length):
+
+ # Appending zeros in a packet if byte length < target length
+ if(len(byte) < target_length):
+ needed_length = target_length - len(byte)
+ zeros = bytearray(needed_length)
+ return (byte+zeros)
+
+ # Trim byte in a packet if byte length > target length
+ elif(len(byte) > target_length):
+ return (byte[:target_length])
+
+ # Else byte length = target length. Do nothing.
+ else:
+ return byte
+
+
+def packet_from_file(file, packetnum, target_length):
+ with open(file, 'rb') as f:
+ pcap = dpkt.pcap.Reader(f)
+ packets = get_packets(pcap, packetnum=packetnum, target_length=target_length)
+ #print(np.shape(packets))
+ return packets
+
+
+def main():
+ args = parser()
+
+ directory = os.path.join('2_Flow', 'AllLayers')
+
+ for folder in os.listdir(directory):
+
+ if(os.path.isdir(os.path.join(directory,folder))):
+
+
+ print("Now Processing Folder: ", folder)
+
+ # Create Dataframe Object
+ folder_df = pd.DataFrame(columns = ['Path','Bytes'])
+
+ searching_folders = os.listdir(os.path.join(directory,folder))
+
+ #####################################
+ # TODO:
+ #
+ #
+ ##if(args.sort == 1):
+ #Sort the searching folders by size (largerst to smallest)
+ ##searching_folders = sorted(searching_folders, key=lambda f: os.path.getsize(os.path.abspath(os.path.join(directory, folder, f))), reverse=True)
+ ##else:
+ random.seed(72)
+ random.shuffle(searching_folders)
+
+ ######################################
+
+
+ if(args.limit!= -1):
+ if(len(searching_folders) > args.limit):
+ searching_folders = searching_folders[:args.limit]
+ elif(len(searching_folders) < args.limit):
+ print("Folder "+str(folder), "does not have required "+str(args.limit) + "files. Folder only has "+str(len(searching_folders)) + " files.")
+
+
+
+ for f in tqdm(searching_folders):
+
+ if f.endswith(".pcap"):
+ # print(os.path.join(directory, folder, f))
+ path_to_file = os.path.join(directory, folder, f)
+ packets = packet_from_file(path_to_file, packetnum=args.packet, target_length=args.byte)
+ # Create Dataframe Object
+ folder_df = folder_df.append({'Path' : path_to_file, 'Bytes' : packets}, ignore_index = True)
+
+ continue
+ else:
+ continue
+
+ print("Row entries of "+str(folder)+": ",folder_df.shape[0])
+
+ save_path = os.path.join('3_Packet' , folder)+"-p"+str(args.packet)+"-b"+str(args.byte)+"-l"+str(abs(args.limit))+".pkl"
+
+ folder_df.to_pickle(save_path)
+ print("Saved to file: ", save_path)
+ print("-"*20)
+
+ continue
+ else:
+ continue
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p2-b300-l1.pkl b/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p2-b300-l1.pkl
new file mode 100644
index 0000000..6415926
Binary files /dev/null and b/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p2-b300-l1.pkl differ
diff --git a/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p5-b500-l1.pkl b/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p5-b500-l1.pkl
new file mode 100644
index 0000000..ba500c2
Binary files /dev/null and b/LYZ/Pacp-deal/3_Packet/Facetime-ALL-p5-b500-l1.pkl differ
diff --git a/LYZ/Pacp-deal/3_Packet2Image.py b/LYZ/Pacp-deal/3_Packet2Image.py
new file mode 100644
index 0000000..7b5aede
--- /dev/null
+++ b/LYZ/Pacp-deal/3_Packet2Image.py
@@ -0,0 +1,65 @@
+# Author: @vinesmsuic
+#
+#
+import numpy as np
+import pandas as pd
+import os
+import pickle
+from PIL import Image
+import binascii
+from tqdm import tqdm
+
+def to_hex(byte_list):
+ bytelist = []
+ for b in byte_list:
+ bytelist.append(binascii.hexlify(bytes(b)))
+
+ return bytelist
+
+def matrix_from_hex(hex_list):
+ matrice = []
+ for hex_str in hex_list:
+ matrix = np.array([int(hex_str[i:i+2],16) for i in range(0, len(hex_str), 2)])
+ matrix = np.uint8(matrix)
+ matrice.append(matrix)
+
+ matrice = np.stack(matrice, axis=0)
+ return matrice
+
+def get_save_path(one_row_df, save_folder):
+ base = os.path.basename(one_row_df['Path'])
+ filename = os.path.splitext(base)[0]
+
+ ImagePath = os.path.join(save_folder,filename)
+ return ImagePath
+
+
+def main():
+ searching_folder = "3_Packet"
+ saving_folder = "4_Image"
+
+ for f in os.listdir(searching_folder):
+ if f.endswith(".pkl"):
+
+ folder = os.path.join(saving_folder, os.path.splitext(f)[0])
+ if not os.path.exists(folder):
+ os.makedirs(folder)
+
+ print("Saving to: " + str(folder))
+
+ file = open(os.path.join(searching_folder, f), 'rb')
+ df = pickle.load(file)
+ file.close()
+
+ df['Hex'] = df['Bytes'].apply(to_hex)
+ df['Matrice'] = df['Hex'].apply(matrix_from_hex)
+
+ for index, row in tqdm(df.iterrows()):
+ ImagePath = get_save_path(row, folder)
+ im = Image.fromarray(row['Matrice'])
+ im.save(str(ImagePath)+".png")
+
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/LYZ/Pacp-deal/README.md b/LYZ/Pacp-deal/README.md
new file mode 100644
index 0000000..33fd51f
--- /dev/null
+++ b/LYZ/Pacp-deal/README.md
@@ -0,0 +1,58 @@
+# Pcap-To-Img
+A Modified version of USTC-TK2016 Tools
+* For Windows only
+
+# Before Preprocessing
+
+## Convert PcapNG Files to Pcap Files
+If you are using PcapNG (`.pcapng`) Files
+> Sometimes pcapng will also shown as `.pcap` file.
+
+* `editcap` program is available from [Wireshark](https://www.wireshark.org/).
+* [Usage of editcap](https://www.wireshark.org/docs/man-pages/editcap.html)
+
+```powershell
+editcap -F libpcap dump.pcapng dump.pcap
+```
+
+* Please see [How To handle PcapNG files](https://www.netresec.com/?page=Blog&month=2012-12&post=HowTo-handle-PcapNG-files) for more detail.
+
+
+## Usage of Tools
+
+* `SplitCap` : [https://www.netresec.com/?page=SplitCap](https://www.netresec.com/?page=SplitCap)
+* `finddupe` : [https://www.sentex.ca/~mwandel/finddupe/](https://www.sentex.ca/~mwandel/finddupe/)
+
+
+## Run Powershell as Administrator
+
+```Powershell
+set-ExecutionPolicy RemoteSigned
+```
+
+# Preprocessing
+
+Split Pcap files into Flows
+```Powershell
+.\1_Pcap2Flow.ps1
+```
+
+```Powershell
+python .\2_Flow2Packet.py
+```
+
+```
+usage: 2_Flow2Packet.py [-h] --packet PACKET --byte BYTE [--limit LIMIT]
+
+Selecting Parameter of Packets and Bytes.
+
+optional arguments:
+ -h, --help show this help message and exit
+ --packet PACKET number of required packets
+ --byte BYTE number of trimmed byte
+ --limit LIMIT only extract packets from the largest N flows
+```
+
+```Powershell
+python .\3_Packet2Image.py
+```
\ No newline at end of file
diff --git a/LYZ/a.py b/LYZ/a.py
new file mode 100644
index 0000000..0ca6f64
--- /dev/null
+++ b/LYZ/a.py
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import os, glob, time
+import pickle
+from timeit import default_timer as timer
+
+# matplot lib complains about librosa
+import warnings
+warnings.filterwarnings('ignore')
+
+
+# classes index
+traffic_dict ={
+ 0: 'Normal',
+ 1: 'BFSSH',
+ 2: 'Infilt',
+ 3: 'HttpDoS',
+ 4: 'DDoS'
+}
+
+# network traffic attributes
+traffic_attributes = {
+ '01': 'normal', # 正常流量
+ '02': 'anomaly' # abnormal
+}
+
+"""## Load Data
+"""
+
+# path to data for glob
+DATA_DIR = 'D:\\PyProject\\malware_traffic\\3_Packet\\'
+
+def load_data():
+ """
+ 加载数据
+ :return:
+ """
+ t1 = timer()
+ sessions = []
+ labels = []
+ num_pkls = len(glob.glob(DATA_DIR + 'ISCX2012_labels_*.pkl')) # 匹配路径
+ for i in range(num_pkls):
+ # if i != 1:
+ # continue
+ session_pkl = DATA_DIR + 'ISCX2012_pcaps_' + str(i) + '.pkl'
+ session_lists = pickle.load(open(session_pkl, 'rb')) # 反序列化对象
+ sessions.extend(session_lists.values.tolist()) # 追加元素
+
+ label_pkl = DATA_DIR + 'ISCX2012_labels_' + str(i) + '.pkl'
+ label_lists = pickle.load(open(label_pkl, 'rb'))
+ labels.extend(label_lists.values.tolist())
+ print(i)
+ t2 = timer()
+ print("load data tims: ", t2 - t1)
+
+ labels = np.array(labels)
+ normal_indices = np.where(labels == 0)[0] # 结果所在的 行, 是个array
+ # 数据量太大, 不好训练。以下注释代码可以选择100000条正常流量进入训练(建议在数据预处理阶段选择一定数量的正常数据——节约内存开支)
+ normal_indices = np.random.choice(normal_indices, 100000, replace=False) # 注释代码
+ attack_indices = [np.where(labels == i)[0] for i in range(1, 5)] # label 1~4 所在行, 是个 list
+ # np.random.choice 会重复抽样, 若想不重复, 增加参数:replace=False
+ test_normal_indices = np.random.choice(normal_indices, int(len(normal_indices) * 0.4), replace=False)
+ test_attack_indices = np.concatenate( # 模态融合
+ [np.random.choice(attack_indices[i], int(len(attack_indices[i]) * 0.4), replace=False) for i in range(4)])
+ test_indices = np.concatenate([test_normal_indices, test_attack_indices]).astype(int)
+ # train_indices = np.array(list(set(np.arange(len(labels))) - set(test_indices)))
+ attack_indices = np.concatenate(attack_indices).astype(int) # 注释代码
+ indices = np.concatenate([normal_indices, attack_indices]).astype(int) # 注释代码
+ train_indices = np.array(list(set(indices) - set(test_indices))) # 注释代码
+
+ return sessions, labels, train_indices, test_indices
+
+
+
+"""# Architecture Overview
+
+# CNN Motivation
+** 构建两个并行卷积神经网络(CNN)来对流量数据进行空间特征表示
+
+# Transformer-Encoder Motivation
+**使用了Transformer-Encoder层
+**I maxpool 映射到Transformer, 以大大减少网络需要学习的参数数量
+"""
+
+
+class ByteBlock(nn.Module):
+ """
+ 1D FCN: 1维全卷积神经网络
+
+ in_channels:输入通道数, 在一维卷积中由于不存在通道数, 因此in_channels的数值为词向量的维度, 如果一个单词用128维向量表示, 那么in_channels = 128
+
+ out_channels:输出通道数, 表示经过卷积之后, 一个词向量嵌入维度应该为多少。如果out_channels = 64, 那么经过本次卷积之后的每个词的嵌入维度为64。
+
+ kernel_size:卷积核大小, 表示本次卷积核的维度, 一般是赋值为int类型。kernel_size=3, 表示每次卷积计算操作涉及到3个词, 也就是卷积核维度被设为(in_channels, kernel_size)。
+ - 在Pytorch中, 对于一条语句序列数据的每个词都是用一个列向量表示
+
+ stride:滑动步长, 表示在卷积方向上滑动的步长。stride=2, 表示在当前卷积的范围为123, 下一个卷积范围就是345。
+
+ padding:填补操作, 表示在对特征矩阵剩余部分不足卷积时的操作。
+ - str --> padding =“valid”:表示不填充, 剩余部分丢弃。 padding =“same”:表示在右侧填充之后要求输入输出序列长度一致
+ - int --> padding = k: 表示在右侧填充k列
+ """
+ def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
+ subsample=(2, 1), pool_length=(2, 2)):
+ super(ByteBlock, self).__init__()
+
+ layers = []
+ for i in range(len(nb_filter)):
+ layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
+ padding=0, stride=subsample[i]))
+ layers.append(nn.Tanh())
+ if pool_length[i]:
+ layers.append(nn.MaxPool1d(pool_length[i]))
+ in_channels = nb_filter[i]
+
+ self.block = nn.Sequential(*layers)
+ self.global_pool = nn.AdaptiveMaxPool1d(1)
+
+
+ def forward(self, x):
+ x = self.block(x)
+ x = self.global_pool(x).squeeze(dim=2)
+ x = torch.nn.functional.leaky_relu(x)
+ return x
+
+class FCN_Transformer(nn.Module):
+ # Define all layers present in the network
+ def __init__(self,num_emotions):
+ super().__init__()
+
+ ################ TRANSFORMER BLOCK #############################
+ # maxpool the input feature map/tensor to the transformer
+ # a rectangular kernel worked better here for the rectangular input spectrogram feature map/tensor
+ self.transformer_maxpool = nn.MaxPool1d(2)
+
+ # define single transformer encoder layer
+ # self-attention + feedforward network from "Attention is All You Need" paper
+ # Input size: sequence length, batch size, feature size = 128
+ transformer_layer = nn.TransformerEncoderLayer(
+ d_model=128, # input feature (frequency) dim after maxpooling 128*y -> 64*140 (freq*time) 输入特征维度
+ nhead=4, # 4 self-attention layers in each multi-head self-attention layer in each encoder block 注意力头数
+ dim_feedforward=512, # 2 linear layers in each encoder block's feedforward network: dim 64-->512--->64 前馈神经网络中隐藏层的维度。
+ dropout=0.4,
+ activation='relu' # ReLU: avoid saturation/tame gradient/reduce compute time
+ )
+
+ # Using 4 instead of the 6 identical stacked encoder layrs used in Attention is All You Need paper
+ # Complete transformer block contains 4 full transformer encoder layers (each w/ multihead self-attention+feedforward)
+ self.transformer_encoder = nn.TransformerEncoder(transformer_layer, num_layers=4)
+
+ ############### 1ST PARALLEL 1D CONVOLUTION BLOCK ############
+ # 1 sequential conv1D layers: (1,128,282) --> (x, y, z)
+ self.conv1Dblock1 = ByteBlock(128, (128, 256), (5, 5), (1, 1), (2, 2))
+ ############### 2ND PARALLEL 1D CONVOLUTION BLOCK ############
+ # 1 sequential conv1D layers: (1,128,282) --> (x, y, z)
+ self.conv1Dblock2 = ByteBlock(128, (192, 320), (7, 5), (1, 1), (2, 2))
+ ################# FINAL LINEAR BLOCK ####################
+ # Linear softmax layer to take final concatenated embedding tensor
+ # from parallel 1D convolutional and transformer blocks, output classes logits
+ self.fc1_linear = nn.Linear(512*2+40,num_emotions)
+
+ ### Softmax layer for the 8 output logits from final FC linear layer
+ self.softmax_out = nn.Softmax(dim=1) # dim==1 is the freq embedding
+
+ # define one complete parallel fwd pass of input feature tensor thru 2*conv+1*transformer blocks
+ def forward(self,x):
+
+ ############ 1st parallel Conv1D block: 4 Convolutional layers ############################
+ # create final feature embedding from 1st convolutional layer
+ # input features pased through 4 sequential 1D convolutional layers
+ print("x: ",x.type())
+ conv1d_embedding1 = self.conv1Dblock1(x) # x == N/batch * channel * freq * time
+
+ # flatten final 64*1*4 feature map from convolutional layers to length 256 1D array
+ # skip the 1st (N/batch) dimension when flattening
+ conv1d_embedding1 = torch.flatten(conv1d_embedding1, start_dim=1)
+
+ ############ 2nd parallel Conv1D block: 4 Convolutional layers #############################
+ # create final feature embedding from 2nd convolutional layer
+ # input features pased through 4 sequential 1D convolutional layers
+ conv1d_embedding2 = self.conv1Dblock2(x) # x == N/batch * channel * freq * time
+
+ # flatten final 64*1*4 feature map from convolutional layers to length 256 1D array
+ # skip the 1st (N/batch) dimension when flattening
+ conv1d_embedding2 = torch.flatten(conv1d_embedding2, start_dim=1)
+
+
+ ########## 4-encoder-layer Transformer block w/ 64-->512-->64 feedfwd network ##############
+ # maxpool input feature map: 1*40*282 w/ 1*4 kernel --> 1*40*70
+ x_maxpool = self.transformer_maxpool(x)
+
+ # remove channel dim: 1*x*y --> x*y
+ x_maxpool_reduced = torch.squeeze(x_maxpool,1)
+
+ # convert maxpooled feature map format: batch * freq * time ---> time * batch * freq format
+ # because transformer encoder layer requires tensor in format: time * batch * embedding (freq)
+ x = x_maxpool_reduced.permute(2,0,1)
+ print("x_maxpool_reduced: ",x_maxpool_reduced.shape)
+ # finally, pass reduced input feature map x into transformer encoder layers
+ transformer_output = self.transformer_encoder(x)
+
+ # create final feature emedding from transformer layer by taking mean in the time dimension (now the 0th dim)
+ # transformer outputs 64*140 (freq embedding*time) feature map, take mean of all columns i.e. take time average
+ transformer_embedding = torch.mean(transformer_output, dim=0) # dim
+
+ ############# concatenate freq embeddings from convolutional and transformer blocks ######
+ # concatenate embedding tensors output by parallel 2*conv and 1*transformer blocks
+ complete_embedding = torch.cat([conv1d_embedding1, conv1d_embedding2,transformer_embedding], dim=1)
+
+ ######### final FC linear layer, need logits for loss #########################
+ output_logits = self.fc1_linear(complete_embedding)
+
+ ######### Final Softmax layer: use logits from FC linear, get softmax for prediction ######
+ output_softmax = self.softmax_out(output_logits)
+
+ # need output logits to compute cross entropy loss, need softmax probabilities to predict class
+ return output_logits, output_softmax
+
+
+"""# 查看模型结构
+"""
+from torchsummary import summary
+
+# need device to instantiate model
+device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+
+# instantiate model for 8 emotions and move to CPU for summary
+model = FCN_Transformer(len(traffic_dict)).to(device)
+
+# print("\nmodel: \n", model,"\n")
+data = torch.randint(255, size=(128, 128, 100)) # batch_size, flow_len, packet_len
+print("data: ", data.type())
+model(data)
+
+# include input feature map dims in call to summary()
+# summary(model, input_size=(128,282))
+
+
+
+
diff --git a/LYZ/b.py b/LYZ/b.py
new file mode 100644
index 0000000..ceade97
--- /dev/null
+++ b/LYZ/b.py
@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*-
+
+
+import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import os, glob
+import warnings; warnings.filterwarnings('ignore') #matplot lib complains about librosa
+
+
+# RAVDESS native sample rate is 48k
+sample_rate = 48000
+
+# Mel Spectrograms are not directly used as a feature in this model
+# Mel Spectrograms are used in calculating MFCCs, which are a higher-level representation of pitch transition
+# MFCCs work better - left the mel spectrogram function here in case anyone wants to experiment
+def feature_melspectrogram(
+ waveform,
+ sample_rate,
+ fft = 1024,
+ winlen = 512,
+ window='hamming',
+ hop=256,
+ mels=128,
+ ):
+
+ # Produce the mel spectrogram for all STFT frames and get the mean of each column of the resulting matrix to create a feature array
+ # Using 8khz as upper frequency bound should be enough for most speech classification tasks
+ melspectrogram = librosa.feature.melspectrogram(
+ y=waveform,
+ sr=sample_rate,
+ n_fft=fft,
+ win_length=winlen,
+ window=window,
+ hop_length=hop,
+ n_mels=mels,
+ fmax=sample_rate/2)
+
+ # convert from power (amplitude**2) to decibels
+ # necessary for network to learn - doesn't converge with raw power spectrograms
+ melspectrogram = librosa.power_to_db(melspectrogram, ref=np.max)
+
+ return melspectrogram
+
+def feature_mfcc(
+ waveform,
+ sample_rate,
+ n_mfcc = 40,
+ fft = 1024,
+ winlen = 512,
+ window='hamming',
+ #hop=256, # increases # of time steps; was not helpful
+ mels=128
+ ):
+
+ # Compute the MFCCs for all STFT frames
+ # 40 mel filterbanks (n_mfcc) = 40 coefficients
+ mfc_coefficients=librosa.feature.mfcc(
+ y=waveform,
+ sr=sample_rate,
+ n_mfcc=n_mfcc,
+ n_fft=fft,
+ win_length=winlen,
+ window=window,
+ #hop_length=hop,
+ n_mels=mels,
+ fmax=sample_rate/2
+ )
+
+ return mfc_coefficients
+
+def get_features(waveforms, features, samplerate):
+
+ # initialize counter to track progress
+ file_count = 0
+
+ # process each waveform individually to get its MFCCs
+ for waveform in waveforms:
+ mfccs = feature_mfcc(waveform, sample_rate)
+ features.append(mfccs)
+ file_count += 1
+ # print progress
+ print('\r'+f' Processed {file_count}/{len(waveforms)} waveforms',end='')
+
+ # return all features from list of waveforms
+ return features
+
+def get_waveforms(file):
+
+ # load an individual sample audio file
+ # read the full 3 seconds of the file, cut off the first 0.5s of silence; native sample rate = 48k
+ # don't need to store the sample rate that librosa.load returns
+ waveform, _ = librosa.load(file, duration=3, offset=0.5, sr=sample_rate)
+
+ # make sure waveform vectors are homogenous by defining explicitly
+ waveform_homo = np.zeros((int(sample_rate*3,)))
+ waveform_homo[:len(waveform)] = waveform
+
+ # return a single file's waveform
+ return waveform_homo
+
+# RAVDESS dataset emotions
+# shift emotions left to be 0 indexed for PyTorch
+emotions_dict ={
+ '0':'surprised',
+ '1':'neutral',
+ '2':'calm',
+ '3':'happy',
+ '4':'sad',
+ '5':'angry',
+ '6':'fearful',
+ '7':'disgust'
+}
+
+# Additional attributes from RAVDESS to play with
+emotion_attributes = {
+ '01': 'normal',
+ '02': 'strong'
+}
+
+class parallel_all_you_want(nn.Module):
+ # Define all layers present in the network
+ def __init__(self,num_emotions):
+ super().__init__()
+
+ ################ TRANSFORMER BLOCK #############################
+ # maxpool the input feature map/tensor to the transformer
+ # a rectangular kernel worked better here for the rectangular input spectrogram feature map/tensor
+ self.transformer_maxpool = nn.MaxPool2d(kernel_size=[1,4], stride=[1,4])
+
+ # define single transformer encoder layer
+ # self-attention + feedforward network from "Attention is All You Need" paper
+ # 4 multi-head self-attention layers each with 64-->512--->64 feedforward network
+ transformer_layer = nn.TransformerEncoderLayer(
+ d_model=40, # input feature (frequency) dim after maxpooling 128*563 -> 64*140 (freq*time)
+ nhead=4, # 4 self-attention layers in each multi-head self-attention layer in each encoder block
+ dim_feedforward=512, # 2 linear layers in each encoder block's feedforward network: dim 64-->512--->64
+ dropout=0.4,
+ activation='relu' # ReLU: avoid saturation/tame gradient/reduce compute time
+ )
+
+ # I'm using 4 instead of the 6 identical stacked encoder layrs used in Attention is All You Need paper
+ # Complete transformer block contains 4 full transformer encoder layers (each w/ multihead self-attention+feedforward)
+ self.transformer_encoder = nn.TransformerEncoder(transformer_layer, num_layers=4)
+
+ ############### 1ST PARALLEL 2D CONVOLUTION BLOCK ############
+ # 3 sequential conv2D layers: (1,40,282) --> (16, 20, 141) -> (32, 5, 35) -> (64, 1, 8)
+ self.conv2Dblock1 = nn.Sequential(
+
+ # 1st 2D convolution layer
+ nn.Conv2d(
+ in_channels=1, # input volume depth == input channel dim == 1
+ out_channels=16, # expand output feature map volume's depth to 16
+ kernel_size=3, # typical 3*3 stride 1 kernel
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(16), # batch normalize the output feature map before activation
+ nn.ReLU(), # feature map --> activation map
+ nn.MaxPool2d(kernel_size=2, stride=2), #typical maxpool kernel size
+ nn.Dropout(p=0.3), #randomly zero 30% of 1st layer's output feature map in training
+
+ # 2nd 2D convolution layer identical to last except output dim, maxpool kernel
+ nn.Conv2d(
+ in_channels=16,
+ out_channels=32, # expand output feature map volume's depth to 32
+ kernel_size=3,
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(32),
+ nn.ReLU(),
+ nn.MaxPool2d(kernel_size=4, stride=4), # increase maxpool kernel for subsequent filters
+ nn.Dropout(p=0.3),
+
+ # 3rd 2D convolution layer identical to last except output dim
+ nn.Conv2d(
+ in_channels=32,
+ out_channels=64, # expand output feature map volume's depth to 64
+ kernel_size=3,
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(64),
+ nn.ReLU(),
+ nn.MaxPool2d(kernel_size=4, stride=4),
+ nn.Dropout(p=0.3),
+ )
+ ############### 2ND PARALLEL 2D CONVOLUTION BLOCK ############
+ # 3 sequential conv2D layers: (1,40,282) --> (16, 20, 141) -> (32, 5, 35) -> (64, 1, 8)
+ self.conv2Dblock2 = nn.Sequential(
+
+ # 1st 2D convolution layer
+ nn.Conv2d(
+ in_channels=1, # input volume depth == input channel dim == 1
+ out_channels=16, # expand output feature map volume's depth to 16
+ kernel_size=3, # typical 3*3 stride 1 kernel
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(16), # batch normalize the output feature map before activation
+ nn.ReLU(), # feature map --> activation map
+ nn.MaxPool2d(kernel_size=2, stride=2), #typical maxpool kernel size
+ nn.Dropout(p=0.3), #randomly zero 30% of 1st layer's output feature map in training
+
+ # 2nd 2D convolution layer identical to last except output dim, maxpool kernel
+ nn.Conv2d(
+ in_channels=16,
+ out_channels=32, # expand output feature map volume's depth to 32
+ kernel_size=3,
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(32),
+ nn.ReLU(),
+ nn.MaxPool2d(kernel_size=4, stride=4), # increase maxpool kernel for subsequent filters
+ nn.Dropout(p=0.3),
+
+ # 3rd 2D convolution layer identical to last except output dim
+ nn.Conv2d(
+ in_channels=32,
+ out_channels=64, # expand output feature map volume's depth to 64
+ kernel_size=3,
+ stride=1,
+ padding=1
+ ),
+ nn.BatchNorm2d(64),
+ nn.ReLU(),
+ nn.MaxPool2d(kernel_size=4, stride=4),
+ nn.Dropout(p=0.3),
+ )
+
+ ################# FINAL LINEAR BLOCK ####################
+ # Linear softmax layer to take final concatenated embedding tensor
+ # from parallel 2D convolutional and transformer blocks, output 8 logits
+ # Each full convolution block outputs (64*1*8) embedding flattened to dim 512 1D array
+ # Full transformer block outputs 40*70 feature map, which we time-avg to dim 40 1D array
+ # 512*2+40 == 1064 input features --> 8 output emotions
+ self.fc1_linear = nn.Linear(512*2+40,num_emotions)
+
+ ### Softmax layer for the 8 output logits from final FC linear layer
+ self.softmax_out = nn.Softmax(dim=1) # dim==1 is the freq embedding
+
+ # define one complete parallel fwd pass of input feature tensor thru 2*conv+1*transformer blocks
+ def forward(self,x):
+
+ ############ 1st parallel Conv2D block: 4 Convolutional layers ############################
+ # create final feature embedding from 1st convolutional layer
+ # input features pased through 4 sequential 2D convolutional layers
+ conv2d_embedding1 = self.conv2Dblock1(x) # x == N/batch * channel * freq * time
+
+ # flatten final 64*1*4 feature map from convolutional layers to length 256 1D array
+ # skip the 1st (N/batch) dimension when flattening
+ conv2d_embedding1 = torch.flatten(conv2d_embedding1, start_dim=1)
+
+ ############ 2nd parallel Conv2D block: 4 Convolutional layers #############################
+ # create final feature embedding from 2nd convolutional layer
+ # input features pased through 4 sequential 2D convolutional layers
+ conv2d_embedding2 = self.conv2Dblock2(x) # x == N/batch * channel * freq * time
+
+ # flatten final 64*1*4 feature map from convolutional layers to length 256 1D array
+ # skip the 1st (N/batch) dimension when flattening
+ conv2d_embedding2 = torch.flatten(conv2d_embedding2, start_dim=1)
+
+
+ ########## 4-encoder-layer Transformer block w/ 64-->512-->64 feedfwd network ##############
+ # maxpool input feature map: 1*40*282 w/ 1*4 kernel --> 1*40*70
+ x_maxpool = self.transformer_maxpool(x)
+
+ # remove channel dim: 1*40*70 --> 40*70
+ x_maxpool_reduced = torch.squeeze(x_maxpool,1)
+
+ # convert maxpooled feature map format: batch * freq * time ---> time * batch * freq format
+ # because transformer encoder layer requires tensor in format: time * batch * embedding (freq)
+ x = x_maxpool_reduced.permute(2,0,1)
+
+ # finally, pass reduced input feature map x into transformer encoder layers
+ transformer_output = self.transformer_encoder(x)
+
+ # create final feature emedding from transformer layer by taking mean in the time dimension (now the 0th dim)
+ # transformer outputs 64*140 (freq embedding*time) feature map, take mean of all columns i.e. take time average
+ transformer_embedding = torch.mean(transformer_output, dim=0) # dim 40x70 --> 40
+
+ ############# concatenate freq embeddings from convolutional and transformer blocks ######
+ # concatenate embedding tensors output by parallel 2*conv and 1*transformer blocks
+ complete_embedding = torch.cat([conv2d_embedding1, conv2d_embedding2,transformer_embedding], dim=1)
+
+ ######### final FC linear layer, need logits for loss #########################
+ output_logits = self.fc1_linear(complete_embedding)
+
+ ######### Final Softmax layer: use logits from FC linear, get softmax for prediction ######
+ output_softmax = self.softmax_out(output_logits)
+
+ # need output logits to compute cross entropy loss, need softmax probabilities to predict class
+ return output_logits, output_softmax
+
+"""## 网络张量分析
+We zero-pad 1 the input feature map to each convolutional layer to get back from the layer the same shape tensor as we input: zero-pad 1 adds 2 to each of (H, W) dims, and the 3x3, stride 1 kernels cuts off (kernel - stride == 2) dims from each of (H,W). **Zero-pad 1 --> 3x3 stride 1 kernel effectively throws away the zero pads to get same input/output shape from each conv2D block.**
+
+At the end of first convolutional layer in each block we have a maxpool kernel of size 2x2, stride 2 which will take 1 of 4 pixels in its winddow. For the input feature map the maxpool kernel will progress 128/2 = 64 times over the rows and 563/2=281 times over the columns. **Nonoverlapping maxpool kernel reduces each output dim to input dim/kernel size.** We then expand the output channels to 16 making an output feature map of (16x64x281).
+
+The next two convolutional layers in each block have a maxpool kernel size 8x8, stride 8. Same math as above, maxpool reduces each dim/8. 2nd conv layer takes (16x64x281) --> (32x8x35). 3rd and final conv layer takes (32x8x35) --> (64x1x4).
+
+**Note that in (N,C,H,W) format, for MFCCs H = MFCC (pitch), W = time step.**
+
+**Complete flow through each convolutional block (C,H,W):**
+
+ Layer 1 ---> 1x128x563 --> PAD-1 --> 1x130x565 --> FILTER --> 16x128x563 --> MAXPOOL 2x2 stride 2 --> 16x64x281
+
+ Layer 2 ---> 16x64x281 --> PAD-1 --> 16x66x283 --> FILTER --> 32x64x281 --> MAXPOOL 8x8 stride 8 --> 32x8x35
+
+ Layer 3 ---> 32x8x35 --> PAD-1 --> 32x10x37 --> FILTER --> 64x8x35 --> MAXPOOL 8x8 stride 8 --> 64x1x4
+
+ Flatten ---> 64x1x4 --> Final convolutional embedding length 256 1D array
+
+
+**Complete flow through transformer encoder block (C,H,W):**
+
+ Maxpool 2x4 stride 2x4 ---> 1x128x563 --> 1x64x140
+
+ Drop channel ---> 1x64x140 --> 64x140 (H,W)
+
+ Change dims ---> 64x140 --> 140x64 (W,H)
+
+ 4*Transformer encoder ---> 140x64 --> 2x64 (W,H)
+
+ Time average ---> 2x64 --> 1x64 --> Final transformer embedding length 64 1D array
+
+**FC Linear network (C,H,W):**
+
+ Concatenate ---> 256x256x64 --> 576
+
+ FC Linear layer ---> 576 --> Final linear logits output length 8 1D array
+
+ Softmax layer: 8 ----> 1 predicted emotion / max probability class
+
+
+We can confirm our network's tensor shapes and flow using the excellent torchsummary package which provides a PyTorch implementation of Keras' model.summary method:
+"""
+
+from torchsummary import summary
+
+# need device to instantiate model
+device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+
+# instantiate model for 8 emotions and move to CPU for summary
+model = parallel_all_you_want(len(emotions_dict)).to(device)
+
+
+data = torch.randint(255, size=(2, 1, 40, 282)).float()
+print("data: ", data.type())
+model(data)
+
+# include input feature map dims in call to summary()
+summary(model, input_size=(1,40,282))
+
+
diff --git a/LYZ/cnn_gru.py b/LYZ/cnn_gru.py
new file mode 100644
index 0000000..8cbffde
--- /dev/null
+++ b/LYZ/cnn_gru.py
@@ -0,0 +1,414 @@
+
+# 主网络
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torch.utils.data as data
+import numpy as np
+import pickle
+import glob
+from timeit import default_timer as timer
+import time
+import warnings
+
+# 用 BiGRU 网络试试
+from model import *
+
+# 不输出“Warning”信息
+# warnings.filterwarnings("ignore")
+"""
+出现过错误的地方,反映了基础不牢
+交叉熵:https://blog.csdn.net/dss_dssssd/article/details/84036913
+label 转 one-hot:https://blog.csdn.net/qq_34914551/article/details/88700334
+"""
+
+LSTM_UNITS = 92
+MINI_BATCH = 10
+TRAIN_STEPS_PER_EPOCH = 12000
+VALIDATION_STEPS_PER_EPOCH = 800
+DATA_DIR = 'D:\\PyProject\\malware_traffic\\3_Packet\\'
+CHECKPOINTS_DIR = './checkpoints/'
+
+dict_5class = {0: 'Normal', 1: 'BFSSH', 2: 'Infilt', 3: 'HttpDoS', 4: 'DDoS'}
+
+PACKET_NUM_PER_SESSION = 14
+PACKET_LEN = 100
+
+
+class ByteBlock(nn.Module):
+ """
+ 卷积神经网络
+ """
+ def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
+ subsample=(2, 1), pool_length=(2, 2)):
+ super(ByteBlock, self).__init__()
+
+ layers = []
+ for i in range(len(nb_filter)):
+ layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
+ padding=0, stride=subsample[i]))
+ layers.append(nn.Tanh())
+ if pool_length[i]:
+ layers.append(nn.MaxPool1d(pool_length[i]))
+ in_channels = nb_filter[i]
+
+ self.block = nn.Sequential(*layers)
+ self.global_pool = nn.AdaptiveMaxPool1d(1)
+ self.fc = nn.Linear(nb_filter[-1], 128)
+
+ def forward(self, x):
+ x = self.block(x)
+ x = self.global_pool(x).squeeze(dim=2)
+ x = torch.nn.functional.relu(self.fc(x))
+ return x
+
+
+class FlowDataset(data.Dataset):
+ def __init__(self, sessions, labels, indices):
+ self.sessions = sessions[indices]
+ self.labels = labels[indices]
+ self.indices = indices
+
+ def __len__(self):
+ return len(self.indices)
+
+ def __getitem__(self, index):
+ idx = self.indices[index]
+ session = torch.tensor(self.sessions[idx], dtype=torch.int64)
+ label = torch.tensor(self.labels[idx], dtype=torch.int64)
+ return session, label
+
+
+def update_confusion_matrix(confusion_matrix, actual_lb, predict_lb):
+ for idx, value in enumerate(actual_lb):
+ p_value = predict_lb[idx]
+ confusion_matrix[value, p_value] += 1
+ return confusion_matrix
+
+
+def truncate(f, n):
+ trunc_f = np.math.floor(f * 10 ** n) / 10 ** n
+ return '{:.2f}'.format(trunc_f)
+
+
+def binarize(x, sz=256):
+ return torch.nn.functional.one_hot(x, sz).float()
+
+
+class OneHotEncodingLayer(nn.Module):
+ def __init__(self, sz=256):
+ super(OneHotEncodingLayer, self).__init__()
+ self.size = sz
+
+ def forward(self, x):
+ return torch.nn.functional.one_hot(x, num_classes=self.size).float()
+
+
+"""
+# 可以改为 FlowDataLoader 中数据
+def mini_batch_generator(dataset, batch_size):
+ data_loader = data.DataLoader(dataset, batch_size=batch_size, shuffle=True)
+ while True:
+ for sessions, labels in data_loader:
+ Xbatch = torch.ones((batch_size, PACKET_NUM_PER_SESSION, PACKET_LEN), dtype=torch.int64) * -1
+ Ybatch = torch.ones((batch_size, 5), dtype=torch.int64) * -1
+ for batch_idx, (session, label) in enumerate(zip(sessions, labels)):
+ for i, packet in enumerate(session):
+ if i < PACKET_NUM_PER_SESSION:
+ for j, byte in enumerate(packet[:PACKET_LEN]):
+ Xbatch[batch_idx, i, (PACKET_LEN - 1 - j)] = byte
+ Ybatch[batch_idx] = torch.nn.functional.one_hot(label, num_classes=5)[0]
+ yield Xbatch, Ybatch
+"""
+
+
+class MyDataset(data.Dataset):
+ """
+ 数据转换编码(独热编码)
+ """
+ def __init__(self, sessions, labels, indices):
+ self.sessions = sessions
+ self.labels = labels
+ self.indices = indices
+ self.packet_num_per_session = PACKET_NUM_PER_SESSION
+ self.packet_len = PACKET_LEN
+
+ def __getitem__(self, index):
+ idx = self.indices[index]
+ X = torch.ones((self.packet_num_per_session, self.packet_len), dtype=torch.int64) * -1
+
+ for i, packet in enumerate(self.sessions[idx]):
+ if i < self.packet_num_per_session:
+ for j, byte in enumerate(packet[:self.packet_len]):
+ X[i, (self.packet_len - 1 - j)] = byte
+
+ # label = self.labels[idx].astype(np.int64) # CrossEntropyLoss 会自动把标签转换成onehot形式
+ # y = torch.nn.functional.one_hot(torch.from_numpy(label), num_classes=5)[0]
+ y = self.labels[idx][0].astype(np.int64)
+ return X, y
+
+ def __len__(self):
+ return len(self.indices)
+
+
+class MyModel(nn.Module):
+ """
+ 模型定义
+ """
+ def __init__(self, flow_len, packet_len, gru_units):
+ super(MyModel, self).__init__()
+ self.packet_len = packet_len
+ self.flow_len = flow_len
+ self.batch_size = 10
+ self.gru_hidden_size = gru_units
+
+ self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
+ self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
+ self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
+
+ self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
+ self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5) # # 其实像特征聚类,输出聚类数
+ # self.output = nn.Softmax(dim=1)
+
+ def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
+ embeddings_list = self.embedding(x) # [10, 14, 100, 256]
+ encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
+ for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
+ # print("embeddings 1: ", embeddings.shape)
+ # embeddings = embeddings.permute(0, 2, 1)
+ # print("embeddings 2: ", embeddings.shape)
+ encoder1 = self.block2(embeddings) # [14, 128]
+ # print("encoder 1: ", encoder1.shape)
+ encoder2 = self.block3(embeddings) # [14, 128]
+ # print("encoder 2: ", encoder2.shape)
+ encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
+ # print("encoder : ", encoder.shape)
+ encoder_list[ix] = encoder
+
+ # rnn 网络输入:[seq_len, batch_size, hidden_size]
+ encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
+ biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
+ biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
+ # print("biLSTM: ", biLSTM.shape)
+ attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
+ dense = self.dense_layer(attn_output)
+ # out = self.output(dense)
+ # out = dense[:, -1, :]
+ return dense
+
+ # lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
+ def attention_net(self, lstm_output, final_state):
+ # print("lstm_output: ", lstm_output.shape)
+ # print("final_state: ", final_state.shape)
+ # hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
+ hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
+ # attn_weights : [batch_size, n_step]
+ attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
+ soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
+ # [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
+ # = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
+ context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
+ return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
+
+
+def save_result(cf_ma, len_test, epochs=8):
+ """
+ 计算metrics_list,保存测试/训练结果
+ :param cf_ma:
+ :param len_test:
+ :param epochs:
+ :return:
+ """
+ metrics_list = []
+ for i in range(5):
+ if i == 0:
+ metrics_list.append(
+ [dict_5class[i], str(i), str(cf_ma[i, 0]), str(cf_ma[i, 1]), str(cf_ma[i, 2]), str(cf_ma[i, 3]),
+ str(cf_ma[i, 4]), '--', '--', '--'])
+ else:
+ acc = truncate((float(len_test - cf_ma[:, i].sum() - cf_ma[i, :].sum() + cf_ma[i, i] * 2) / len_test) * 100,
+ 2)
+ tpr = truncate((float(cf_ma[i, i]) / cf_ma[i].sum()) * 100, 2)
+ fpr = truncate((float(cf_ma[0, i]) / cf_ma[0].sum()) * 100, 2)
+ metrics_list.append(
+ [dict_5class[i], str(i), str(cf_ma[i, 0]), str(cf_ma[i, 1]), str(cf_ma[i, 2]), str(cf_ma[i, 3]),
+ str(cf_ma[i, 4]), str(acc), str(tpr), str(fpr)])
+ overall_acc = truncate(
+ (float(cf_ma[0, 0] + cf_ma[1, 1] + cf_ma[2, 2] + cf_ma[3, 3] + cf_ma[4, 4]) / len_test) * 100, 2)
+ overall_tpr = truncate((float(cf_ma[1, 1] + cf_ma[2, 2] + cf_ma[3, 3] + cf_ma[4, 4]) / cf_ma[1:].sum()) * 100, 2)
+ overall_fpr = truncate((float(cf_ma[0, 1:].sum()) / cf_ma[0, :].sum()) * 100, 2)
+
+ with open('iscx12_cnn_rnn_5class_attn.txt', 'a') as f:
+ f.write("\n")
+ t = time.strftime('%Y-%m-%d %X', time.localtime())
+ f.write(t + "\n")
+ f.write('CLASS_NUM: 5\n')
+ f.write('PACKET_LEN: ' + str(PACKET_LEN) + "\n")
+ f.write('PACKET_NUM_PER_SESSION: ' + str(PACKET_NUM_PER_SESSION) + "\n")
+ f.write('MINI_BATCH: ' + str(MINI_BATCH) + "\n")
+ f.write('TRAIN_EPOCHS: ' + str(epochs) + "\n")
+ f.write('DATA_DIR: ' + DATA_DIR + "\n")
+ f.write("label\tindex\t0\t1\t2\t3\t4\tACC\tTPR\tFPR\n")
+ for metrics in metrics_list:
+ f.write('\t'.join(metrics) + "\n")
+ f.write('Overall accuracy: ' + str(overall_acc) + "\n")
+ f.write('Overall TPR: ' + str(overall_tpr) + "\n")
+ f.write('Overall FPR: ' + str(overall_fpr) + "\n")
+ # f.write('Train time(second): ' + str(int(train_time)) + "\n")
+ # f.write('Test time(second): ' + str(int(test_time)) + "\n\n")
+ f.write("\n\n")
+
+
+def train(model, dataloader, criterion, optimizer, device):
+ model.train()
+ running_loss = 0.0
+ num = 0
+ for inputs, labels in dataloader:
+ inputs = inputs.to(device)
+ labels = labels.to(device)
+
+ optimizer.zero_grad() # 梯度清零
+
+ outputs = model(inputs)
+ num += 1
+ # print(“ {}/{} outputs & label shape: ".format(num,len(dataloader.data_loader)), outputs.shape, labels.shape)
+ loss = criterion(outputs, labels)
+
+ loss.backward()
+ optimizer.step()
+
+ running_loss += loss.item() * inputs.size(0)
+
+ return running_loss / len(dataloader.dataset)
+
+
+def evaluate(model, dataloader, criterion, device):
+ model.eval()
+ running_loss = 0.0
+ cf_ma = np.zeros((5, 5), dtype=int)
+ num = 0
+ with torch.no_grad():
+ for inputs, labels in dataloader:
+ inputs = inputs.to(device)
+ labels = labels.to(device)
+
+ outputs = model(inputs)
+ loss = criterion(outputs, labels)
+
+ running_loss += loss.item() * inputs.size(0)
+ predicted_labels = torch.argmax(outputs, dim=1).cpu().numpy()
+ true_labels = labels.cpu().numpy()
+
+ cf_ma = update_confusion_matrix(cf_ma, true_labels, predicted_labels)
+ num += predicted_labels.shape[0]
+
+ print("num len: ", num)
+ save_result(cf_ma, num)
+ return running_loss / len(dataloader.dataset), cf_ma
+
+
+def load_data():
+ """
+ 加载数据
+ :return:
+ """
+ t1 = timer()
+ sessions = []
+ labels = []
+ num_pkls = len(glob.glob(DATA_DIR + 'ISCX2012_labels_*.pkl')) # 匹配路径
+ for i in range(num_pkls):
+ # if i != 1:
+ # continue
+ session_pkl = DATA_DIR + 'ISCX2012_pcaps_' + str(i) + '.pkl'
+ session_lists = pickle.load(open(session_pkl, 'rb')) # 反序列化对象
+ sessions.extend(session_lists.values.tolist()) # 追加元素
+
+ label_pkl = DATA_DIR + 'ISCX2012_labels_' + str(i) + '.pkl'
+ label_lists = pickle.load(open(label_pkl, 'rb'))
+ labels.extend(label_lists.values.tolist())
+ print(i)
+ t2 = timer()
+ print("load data tims: ", t2 - t1)
+
+ labels = np.array(labels)
+ normal_indices = np.where(labels == 0)[0] # 结果所在的 行,是个array
+ # 数据量太大,不好训练。以下注释代码可以选择100000条正常流量进入训练(建议在数据预处理阶段选择一定数量的正常数据——节约内存开支)
+ normal_indices = np.random.choice(normal_indices, 100000, replace=False) # 注释代码
+ attack_indices = [np.where(labels == i)[0] for i in range(1, 5)] # label 1~4 所在行,是个 list
+ # np.random.choice 会重复抽样, 若想不重复,增加参数:replace=False
+ test_normal_indices = np.random.choice(normal_indices, int(len(normal_indices) * 0.4), replace=False)
+ test_attack_indices = np.concatenate( # 模态融合
+ [np.random.choice(attack_indices[i], int(len(attack_indices[i]) * 0.4), replace=False) for i in range(4)])
+ test_indices = np.concatenate([test_normal_indices, test_attack_indices]).astype(int)
+ # train_indices = np.array(list(set(np.arange(len(labels))) - set(test_indices)))
+ attack_indices = np.concatenate(attack_indices).astype(int) # 注释代码
+ indices = np.concatenate([normal_indices, attack_indices]).astype(int) # 注释代码
+ train_indices = np.array(list(set(indices) - set(test_indices))) # 注释代码
+
+ return sessions, labels, train_indices, test_indices
+
+
+# 定义超参数
+NUM_EPOCHS = 8
+LEARNING_RATE = 0.001
+
+# 创建模型实例
+model = MyModel(PACKET_NUM_PER_SESSION, PACKET_LEN, LSTM_UNITS)
+# model = PLA_Attention_Model(100, 100, 50, 100, 14)
+
+# 将模型移到GPU上(如果可用)
+device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+model.to(device)
+
+# 定义损失函数和优化器
+criterion = nn.CrossEntropyLoss()
+optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)
+
+# 创建训练集和验证集的数据加载器
+sessions, labels, train_indices, test_indices = load_data()
+
+train_dataset = MyDataset(sessions, labels, train_indices) # # num_workers=2,Windows不允许多个进程加载数据
+train_dataloader = data.DataLoader(train_dataset, batch_size=MINI_BATCH, shuffle=True, drop_last=True)
+
+val_dataset = MyDataset(sessions, labels, test_indices) # 丢弃不成 batch 数据,否则会报错
+val_dataloader = data.DataLoader(val_dataset, batch_size=MINI_BATCH, shuffle=False, drop_last=True)
+
+# 开始训练
+start_time = timer()
+
+for epoch in range(NUM_EPOCHS):
+ # 训练模型
+ train_loss = train(model, train_dataloader, criterion, optimizer, device)
+ # print(f"Train Loss: {truncate(train_loss, 4)}")
+ # 在验证集上评估模型
+ val_loss, confusion_matrix = evaluate(model, val_dataloader, criterion, device)
+
+ # 输出训练和验证的损失以及混淆矩阵
+ print(f"Epoch {epoch + 1}/{NUM_EPOCHS}")
+ print(f"Train Loss: {truncate(train_loss, 4)}")
+ print(f"Validation Loss: {truncate(val_loss, 4)}")
+ print("Confusion Matrix:")
+ for i in range(5):
+ for j in range(5):
+ print(confusion_matrix[i][j], end="\t")
+ print()
+ print("---------------------------------")
+
+end_time = timer()
+training_time = end_time - start_time
+
+print(f"Training Time: {truncate(training_time, 2)} seconds")
+
+"""
+Epoch 7/10
+Train Loss: 0.35
+Validation Loss: 0.35
+Confusion Matrix:
+39794 43 45 20 98
+472 2272 1 0 0
+3832 1 31 3 0
+1166 0 0 136 0
+56 0 1 0 8219
+---------------------------------
+Train Loss: 0.35
+"""
diff --git a/LYZ/cnn_gru_clutering.py b/LYZ/cnn_gru_clutering.py
new file mode 100644
index 0000000..32f07e2
--- /dev/null
+++ b/LYZ/cnn_gru_clutering.py
@@ -0,0 +1,422 @@
+
+# 主网络
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torch.utils.data as data
+from torch.nn.functional import normalize
+import numpy as np
+import pickle
+import glob
+from timeit import default_timer as timer
+import time
+import warnings
+
+# 用 BiGRU 网络试试
+from model import *
+
+# 不输出“Warning”信息
+# warnings.filterwarnings("ignore")
+"""
+出现过错误的地方,反映了基础不牢
+交叉熵:https://blog.csdn.net/dss_dssssd/article/details/84036913
+label 转 one-hot:https://blog.csdn.net/qq_34914551/article/details/88700334
+
+实验自适应据类
+"""
+
+LSTM_UNITS = 92
+MINI_BATCH = 10
+TRAIN_STEPS_PER_EPOCH = 12000
+VALIDATION_STEPS_PER_EPOCH = 800
+DATA_DIR = 'D:\\PyProject\\malware_traffic\\3_Packet\\'
+CHECKPOINTS_DIR = './checkpoints/'
+
+dict_5class = {0: 'Normal', 1: 'BFSSH', 2: 'Infilt', 3: 'HttpDoS', 4: 'DDoS'}
+class_num = 5
+
+PACKET_NUM_PER_SESSION = 14
+PACKET_LEN = 100
+
+
+class ByteBlock(nn.Module):
+ """
+ 卷积神经网络
+ """
+ def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
+ subsample=(2, 1), pool_length=(2, 2)):
+ super(ByteBlock, self).__init__()
+
+ layers = []
+ for i in range(len(nb_filter)):
+ layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
+ padding=0, stride=subsample[i]))
+ layers.append(nn.Tanh())
+ if pool_length[i]:
+ layers.append(nn.MaxPool1d(pool_length[i]))
+ in_channels = nb_filter[i]
+
+ self.block = nn.Sequential(*layers)
+ self.global_pool = nn.AdaptiveMaxPool1d(1)
+ self.fc = nn.Linear(nb_filter[-1], 128)
+
+ def forward(self, x):
+ x = self.block(x)
+ x = self.global_pool(x).squeeze(dim=2)
+ x = torch.nn.functional.relu(self.fc(x))
+ return x
+
+
+def update_confusion_matrix(confusion_matrix, actual_lb, predict_lb):
+ for idx, value in enumerate(actual_lb):
+ p_value = predict_lb[idx]
+ confusion_matrix[value, p_value] += 1
+ return confusion_matrix
+
+
+def truncate(f, n):
+ trunc_f = np.math.floor(f * 10 ** n) / 10 ** n
+ return '{:.2f}'.format(trunc_f)
+
+
+def binarize(x, sz=256):
+ return torch.nn.functional.one_hot(x, sz).float()
+
+
+class OneHotEncodingLayer(nn.Module):
+ def __init__(self, sz=256):
+ super(OneHotEncodingLayer, self).__init__()
+ self.size = sz
+
+ def forward(self, x):
+ return torch.nn.functional.one_hot(x, num_classes=self.size).float()
+
+
+class MyDataset(data.Dataset):
+ """
+ 数据转换编码(独热编码)
+ """
+ def __init__(self, sessions, labels, indices):
+ self.sessions = sessions
+ self.labels = labels
+ self.indices = indices
+ self.packet_num_per_session = PACKET_NUM_PER_SESSION
+ self.packet_len = PACKET_LEN
+
+ def __getitem__(self, index):
+ idx = self.indices[index]
+ X = torch.ones((self.packet_num_per_session, self.packet_len), dtype=torch.int64) * -1
+
+ for i, packet in enumerate(self.sessions[idx]):
+ if i < self.packet_num_per_session: # 每个数据会话留只取前 num 个
+ for j, byte in enumerate(packet[:self.packet_len]): # 每个数据包取前 PACKET_LEN 字节
+ X[i, (self.packet_len - 1 - j)] = byte
+
+ # label = self.labels[idx].astype(np.int64) # CrossEntropyLoss 会自动把标签转换成onehot形式
+ # y = torch.nn.functional.one_hot(torch.from_numpy(label), num_classes=5)[0]
+ y = self.labels[idx][0].astype(np.int64)
+ return X, y
+
+ def __len__(self):
+ return len(self.indices)
+
+
+class FEMnet(nn.Module):
+ """
+ Feature extraction module 定义
+ """
+ def __init__(self, flow_len, packet_len, gru_units):
+ super(FEMnet, self).__init__()
+ self.packet_len = packet_len
+ self.flow_len = flow_len
+ self.batch_size = 10
+ self.gru_hidden_size = gru_units
+ self.rep_dim = gru_units
+
+ self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
+ self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
+ self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
+
+ self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
+ # self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5)
+ # self.output = nn.Softmax(dim=1) # Linear 自带Softmax 分类
+
+ def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
+ embeddings_list = self.embedding(x) # [10, 14, 100, 256]
+ encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
+ for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
+ # print("embeddings 1: ", embeddings.shape)
+ # embeddings = embeddings.permute(0, 2, 1)
+ # print("embeddings 2: ", embeddings.shape)
+ encoder1 = self.block2(embeddings) # [14, 128]
+ # print("encoder 1: ", encoder1.shape)
+ encoder2 = self.block3(embeddings) # [14, 128]
+ # print("encoder 2: ", encoder2.shape)
+ encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
+ # print("encoder : ", encoder.shape)
+ encoder_list[ix] = encoder
+
+ # rnn 网络输入:[seq_len, batch_size, hidden_size]
+ encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
+ biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
+ biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
+ # print("biLSTM: ", biLSTM.shape)
+ attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
+ dense = self.dense_layer(attn_output)
+ # out = self.output(dense)
+ # out = dense[:, -1, :]
+ return dense
+
+ # lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
+ def attention_net(self, lstm_output, final_state):
+ # print("lstm_output: ", lstm_output.shape)
+ # print("final_state: ", final_state.shape)
+ # hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
+ hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
+ # attn_weights : [batch_size, n_step]
+ attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
+ soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
+ # [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
+ # = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
+ context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
+ return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
+
+
+class MyModel(nn.Module):
+ """
+ Feature extraction module定义
+ """
+ def __init__(self, binet, feature_dim, class_n):
+ super(MyModel, self).__init__()
+ self.binet = binet
+ self.feature_dim = feature_dim
+ self.cluster_num = class_n
+ """ 对比聚类 """
+ self.instance_projector = nn.Sequential( # 实例-单例
+ nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
+ nn.ReLU(),
+ nn.Linear(self.binet.rep_dim, self.feature_dim),
+ )
+ self.cluster_projector = nn.Sequential( # 聚类-集群
+ nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
+ nn.ReLU(),
+ nn.Linear(self.binet.rep_dim, self.cluster_num),
+ nn.Softmax(dim=1)
+ )
+
+ # 训练时执行
+ def forward(self, x_i, x_j): # x_i, x_j 来自同一数据的两种不同预处理方式得到的嵌入矩阵
+ h_i = self.resnet(x_i)
+ h_j = self.resnet(x_j)
+
+ z_i = normalize(self.instance_projector(h_i), dim=1)
+ z_j = normalize(self.instance_projector(h_j), dim=1)
+
+ c_i = self.cluster_projector(h_i)
+ c_j = self.cluster_projector(h_j)
+
+ return z_i, z_j, c_i, c_j
+
+ # 测试时执行
+ def forward_cluster(self, x):
+ h = self.resnet(x)
+ c = self.cluster_projector(h) # 聚类分布
+ c = torch.argmax(c, dim=1) # 得到每个样本的聚类标签。
+ return c
+
+
+def save_result(cf_ma, len_test, epochs=8):
+ """
+ 计算 metrics_list,保存测试/训练结果
+ :param cf_ma:
+ :param len_test:
+ :param epochs:
+ :return:
+ """
+ metrics_list = []
+ for i in range(5):
+ if i == 0:
+ metrics_list.append(
+ [dict_5class[i], str(i), str(cf_ma[i, 0]), str(cf_ma[i, 1]), str(cf_ma[i, 2]), str(cf_ma[i, 3]),
+ str(cf_ma[i, 4]), '--', '--', '--'])
+ else:
+ acc = truncate((float(len_test - cf_ma[:, i].sum() - cf_ma[i, :].sum() + cf_ma[i, i] * 2) / len_test) * 100,
+ 2)
+ tpr = truncate((float(cf_ma[i, i]) / cf_ma[i].sum()) * 100, 2)
+ fpr = truncate((float(cf_ma[0, i]) / cf_ma[0].sum()) * 100, 2)
+ metrics_list.append(
+ [dict_5class[i], str(i), str(cf_ma[i, 0]), str(cf_ma[i, 1]), str(cf_ma[i, 2]), str(cf_ma[i, 3]),
+ str(cf_ma[i, 4]), str(acc), str(tpr), str(fpr)])
+ overall_acc = truncate(
+ (float(cf_ma[0, 0] + cf_ma[1, 1] + cf_ma[2, 2] + cf_ma[3, 3] + cf_ma[4, 4]) / len_test) * 100, 2)
+ overall_tpr = truncate((float(cf_ma[1, 1] + cf_ma[2, 2] + cf_ma[3, 3] + cf_ma[4, 4]) / cf_ma[1:].sum()) * 100, 2)
+ overall_fpr = truncate((float(cf_ma[0, 1:].sum()) / cf_ma[0, :].sum()) * 100, 2)
+
+ # 获取当前日期
+ current_date = time.strftime("%Y%m%d", time.localtime())
+ # 构造文件名
+ file_name = f"evaluate_{current_date}.txt"
+
+ with open(file_name, 'a') as f:
+ f.write("\n")
+ t = time.strftime('%Y-%m-%d %X', time.localtime())
+ f.write(t + "\n")
+ f.write('CLASS_NUM: 5\n')
+ f.write('PACKET_LEN: ' + str(PACKET_LEN) + "\n")
+ f.write('PACKET_NUM_PER_SESSION: ' + str(PACKET_NUM_PER_SESSION) + "\n")
+ f.write('MINI_BATCH: ' + str(MINI_BATCH) + "\n")
+ f.write('TRAIN_EPOCHS: ' + str(epochs) + "\n")
+ f.write('DATA_DIR: ' + DATA_DIR + "\n")
+ f.write("label\tindex\t0\t1\t2\t3\t4\tACC\tTPR\tFPR\n")
+ for metrics in metrics_list:
+ f.write('\t'.join(metrics) + "\n")
+ f.write('Overall accuracy: ' + str(overall_acc) + "\n")
+ f.write('Overall TPR: ' + str(overall_tpr) + "\n")
+ f.write('Overall FPR: ' + str(overall_fpr) + "\n")
+ # f.write('Train time(second): ' + str(int(train_time)) + "\n")
+ # f.write('Test time(second): ' + str(int(test_time)) + "\n\n")
+ f.write("\n\n")
+
+
+def train(model, dataloader, criterion, optimizer, device):
+ model.train()
+ running_loss = 0.0
+ num = 0
+ for inputs, labels in dataloader:
+ inputs = inputs.to(device)
+ labels = labels.to(device)
+
+ optimizer.zero_grad() # 梯度清零
+
+ outputs = model(inputs)
+ num += 1
+ # print(“ {}/{} outputs & label shape: ".format(num,len(dataloader.data_loader)),
+ # outputs.shape, labels.shape)
+ loss = criterion(outputs, labels)
+
+ loss.backward()
+ optimizer.step()
+
+ running_loss += loss.item() * inputs.size(0)
+
+ return running_loss / len(dataloader.dataset)
+
+
+def evaluate(model, dataloader, criterion, device):
+ model.eval()
+ running_loss = 0.0
+ cf_ma = np.zeros((5, 5), dtype=int)
+ num = 0
+ with torch.no_grad():
+ for inputs, labels in dataloader:
+ inputs = inputs.to(device)
+ labels = labels.to(device)
+
+ outputs = model(inputs)
+ loss = criterion(outputs, labels)
+
+ running_loss += loss.item() * inputs.size(0)
+ predicted_labels = torch.argmax(outputs, dim=1).cpu().numpy()
+ true_labels = labels.cpu().numpy()
+
+ cf_ma = update_confusion_matrix(cf_ma, true_labels, predicted_labels)
+ num += predicted_labels.shape[0]
+
+ print("num len: ", num)
+ save_result(cf_ma, num)
+ return running_loss / len(dataloader.dataset), cf_ma
+
+
+def load_data():
+ """
+ 加载数据
+ :return:
+ """
+ t1 = timer()
+ sessions = []
+ labels = []
+ num_pkls = len(glob.glob(DATA_DIR + 'ISCX2012_labels_*.pkl')) # 匹配路径
+ for i in range(num_pkls):
+ # if i != 1:
+ # continue
+ session_pkl = DATA_DIR + 'ISCX2012_pcaps_' + str(i) + '.pkl'
+ session_lists = pickle.load(open(session_pkl, 'rb')) # 反序列化对象
+ sessions.extend(session_lists.values.tolist()) # 追加元素
+
+ label_pkl = DATA_DIR + 'ISCX2012_labels_' + str(i) + '.pkl'
+ label_lists = pickle.load(open(label_pkl, 'rb'))
+ labels.extend(label_lists.values.tolist())
+ print(i)
+ t2 = timer()
+ print("load data tims: ", t2 - t1)
+
+ labels = np.array(labels)
+ normal_indices = np.where(labels == 0)[0] # 结果所在的 行,是个array
+ # 数据量太大,不好训练。以下注释代码可以选择100000条正常流量进入训练(建议在数据预处理阶段选择一定数量的正常数据——节约内存开支)
+ normal_indices = np.random.choice(normal_indices, 100000, replace=False) # 注释代码
+ attack_indices = [np.where(labels == i)[0] for i in range(1, 5)] # label 1~4 所在行,是个 list
+ # np.random.choice 会重复抽样, 若想不重复,增加参数:replace=False
+ test_normal_indices = np.random.choice(normal_indices, int(len(normal_indices) * 0.4), replace=False)
+ test_attack_indices = np.concatenate( # 模态融合
+ [np.random.choice(attack_indices[i], int(len(attack_indices[i]) * 0.4), replace=False) for i in range(4)])
+ test_indices = np.concatenate([test_normal_indices, test_attack_indices]).astype(int)
+ # train_indices = np.array(list(set(np.arange(len(labels))) - set(test_indices)))
+ attack_indices = np.concatenate(attack_indices).astype(int) # 注释代码
+ indices = np.concatenate([normal_indices, attack_indices]).astype(int) # 注释代码
+ train_indices = np.array(list(set(indices) - set(test_indices))) # 注释代码
+
+ return sessions, labels, train_indices, test_indices
+
+
+# 定义超参数
+NUM_EPOCHS = 8
+LEARNING_RATE = 0.001
+
+# 创建模型实例
+fe_model = FEMnet(PACKET_NUM_PER_SESSION, PACKET_LEN, LSTM_UNITS)
+model = MyModel(fe_model, 128, class_num)
+# model = PLA_Attention_Model(100, 100, 50, 100, 14)
+
+# 将模型移到GPU上(如果可用)
+device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+model.to(device)
+
+# 定义损失函数和优化器
+criterion = nn.CrossEntropyLoss()
+optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)
+
+# 创建训练集和验证集的数据加载器
+sessions, labels, train_indices, test_indices = load_data()
+
+train_dataset = MyDataset(sessions, labels, train_indices) # # num_workers=2,Windows不允许多个进程加载数据
+train_dataloader = data.DataLoader(train_dataset, batch_size=MINI_BATCH, shuffle=True, drop_last=True)
+
+val_dataset = MyDataset(sessions, labels, test_indices) # 丢弃不成 batch 数据,否则会报错
+val_dataloader = data.DataLoader(val_dataset, batch_size=MINI_BATCH, shuffle=False, drop_last=True)
+
+# 开始训练
+start_time = timer()
+
+for epoch in range(NUM_EPOCHS):
+ # 训练模型
+ train_loss = train(model, train_dataloader, criterion, optimizer, device)
+ # print(f"Train Loss: {truncate(train_loss, 4)}")
+ # 在验证集上评估模型
+ val_loss, confusion_matrix = evaluate(model, val_dataloader, criterion, device)
+
+ # 输出训练和验证的损失以及混淆矩阵
+ print(f"Epoch {epoch + 1}/{NUM_EPOCHS}")
+ print(f"Train Loss: {truncate(train_loss, 4)}")
+ print(f"Validation Loss: {truncate(val_loss, 4)}")
+ print("Confusion Matrix:")
+ for i in range(5):
+ for j in range(5):
+ print(confusion_matrix[i][j], end="\t")
+ print()
+ print("---------------------------------")
+
+end_time = timer()
+training_time = end_time - start_time
+
+print(f"Training Time: {truncate(training_time, 2)} seconds")
+
diff --git a/LYZ/dataloader.py b/LYZ/dataloader.py
new file mode 100644
index 0000000..99c08b4
--- /dev/null
+++ b/LYZ/dataloader.py
@@ -0,0 +1,65 @@
+import os
+import os.path as osp
+import numpy as np
+import pandas as pd
+import torch
+import torch.utils.data as data
+from scapy.all import rdpcap # pcap 数据处理包
+import time
+import csv
+
+
+class NetworkFlowDataset(data.Dataset):
+ def __init__(self, pcapname, csvname):
+ super().__init__()
+ self.pcap_data = rdpcap(osp.join('data', pcapname))
+ self.label_data = pd.read_csv(osp.join('data', csvname), encoding='latin1')
+
+ def __len__(self):
+ return len(self.pcap_data)
+
+ def __getitem__(self, idx):
+ sample_raw = self.pcap_data[idx].load
+ sample = np.frombuffer(sample_raw, dtype=np.uint8)
+
+ label_raw = self.label_data[idx]['Label']
+ return sample, label_raw
+
+
+class NetworkFlowDataloader(object):
+ def __init__(self, opt, dataset):
+ super().__init__()
+ use_cuda = not torch.cuda.is_available()
+ kwargs = {'num_workers': opt.num_workers} if use_cuda else {}
+
+ self.data_loader = torch.utils.data.DataLoader(
+ dataset, batch_size=opt.batch_size, shuffle=True, **kwargs)
+
+ self.data_iter = self.data_loader.__iter__()
+
+ def next_batch(self):
+ try:
+ batch = self.data_iter.__next__()
+ except StopIteration:
+ self.data_iter = self.data_loader.__iter__()
+ batch = self.data_iter.__next__()
+
+ return batch
+
+
+if __name__ == '__main__':
+ import argparse
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-n', '--num-workers', type=int, default=4)
+ parser.add_argument('-e', '--epoch', type=int, default=10)
+ parser.add_argument('-b', '--batch-size', type=int, default=4)
+ parser.add_argument('-d', '--display-step', type=int, default=600)
+ opt = parser.parse_args()
+
+ start = time.time()
+ dataset = NetworkFlowDataset('Thursday-WorkingHours.pcap', 'Thursday-WorkingHours-Morning-WebAttacks.pcap_ISCX.csv')
+ data_loader = NetworkFlowDataloader(opt, dataset)
+
+ print('[+] Size of the dataset: %05d, dataloader: %03d'
+ % (len(dataset), len(data_loader.data_loader)))
diff --git a/LYZ/loss.py b/LYZ/loss.py
new file mode 100644
index 0000000..db97235
--- /dev/null
+++ b/LYZ/loss.py
@@ -0,0 +1,24 @@
+import torch
+import torch.nn as nn
+
+
+class Loss(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.loss = nn.BCELoss()
+
+ def forward(self, x, y):
+ return self.loss(x, y)
+
+
+if __name__ == '__main__':
+ batch_size = 3
+
+ x = torch.rand(batch_size, 1).cuda()
+ y = torch.rand(batch_size, 1).cuda()
+
+ criterion = Loss()
+ loss = criterion(x, y)
+
+ print(loss.shape)
+ print(loss)
diff --git a/LYZ/model.py b/LYZ/model.py
new file mode 100644
index 0000000..fda9f80
--- /dev/null
+++ b/LYZ/model.py
@@ -0,0 +1,76 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+
+class PLA_Attention_Model(nn.Module):
+ def __init__(self, byte_hidden_size, packet_hidden_size, packet_output_size, max_packet=1500, max_flow=128):
+ super().__init__()
+ self.byte_emb_size = 50
+ self.byte_hidden_size = byte_hidden_size # 100
+ self.packet_emb_size = 50
+ self.packet_hidden_size = packet_hidden_size # 100
+ self.packet_output_size = packet_output_size # 50
+ self.max_packet = max_packet
+ self.max_flow = max_flow
+
+ self.embedding = nn.Embedding(256 * 256, self.byte_emb_size)
+ self.byte_GRU = nn.GRU(self.byte_emb_size, self.byte_hidden_size, bias=False, bidirectional=True)
+ self.byte_attn = nn.Linear(self.byte_hidden_size * 2, self.packet_emb_size)
+ self.packet_GRU = nn.GRU(self.packet_emb_size, self.packet_hidden_size, bias=False, bidirectional=True)
+ self.packet_attn = nn.Linear(self.packet_hidden_size * 2, self.packet_output_size)
+ self.classify = nn.Linear(self.packet_output_size, 11)
+
+ # lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
+ def attention_net(self, lstm_output, final_state):
+ # print("lstm_output: ", lstm_output.shape)
+ # print("final_state: ", final_state.shape)
+ # hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
+ hidden = final_state.view(-1, self.byte_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
+ # attn_weights : [batch_size, n_step]
+ attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
+ soft_attn_weights = F.softmax(attn_weights, 1)
+ # [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
+ # = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
+ context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
+ return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
+
+ def forward(self, flow):
+ num_packet = flow.shape[0]
+ batch_size = flow.shape[1]
+ embedded_bytes_list = self.embedding(flow)
+ encoding_bytes_list = torch.zeros((num_packet, batch_size, self.packet_emb_size))#.cuda() # [4, 3, 120, 50]
+ for i, embedded_bytes in enumerate(embedded_bytes_list): # [3, 120, 50]
+ h0_bytes = torch.randn(2, batch_size, self.byte_hidden_size)#.cuda() # [2,3,100]
+ embedded_bytes = embedded_bytes.transpose(0, 1) # 交换 dim_0 和 dim_1 : [120, 3, 50]
+ # print(embedded_bytes.shape, h0_bytes.shape)
+ output, final_hidden_state = self.byte_GRU(embedded_bytes, h0_bytes) # [120, 3, 200], [2, 3, 100]
+ output = output.permute(1, 0, 2) # [3, 120, 200]
+ # print(output.shape)
+ # print("final: ", final_hidden_state.shape)
+ attn_output, attention = self.attention_net(output, final_hidden_state) # [3, 200]
+ # print("attn_output", attn_output.shape)
+ encoding_bytes_list[i] = self.byte_attn(attn_output) # [4, 3, 50] 最后一维维持不变
+
+ # print("2: ", encoding_bytes_list.shape) # [4, 3, 50]
+ h0_packet = torch.randn(2, batch_size, self.packet_hidden_size)#.cuda() # [2,3,100]
+ # print(h0_packet.shape)
+ output, final_hidden_state = self.packet_GRU(encoding_bytes_list, h0_packet)
+ # print("final_hidden_state: ", final_hidden_state.shape) # [2, 3, 100]
+ output = output.permute(1, 0, 2) # 维度排列转置 [3, 4, 200]
+ attn_output, attention = self.attention_net(output, final_hidden_state) # [3, 200]
+ print("attn_output2: ", attn_output.shape)
+ output = self.packet_attn(attn_output)
+ classify = self.classify(output)
+
+ return classify
+
+
+if __name__ == '__main__':
+ batch_size = 3
+ model = PLA_Attention_Model(100, 100, 50)#.cuda()
+ print(model)
+ data = torch.randint(255, size=(4, batch_size, 120))#.cuda() # flow_len, batch_size, packet_len
+ print(data.shape)
+ res = model(data)
+ print(res.shape)
diff --git a/LYZ/model/Bartmodel.py b/LYZ/model/Bartmodel.py
new file mode 100644
index 0000000..c0635ba
--- /dev/null
+++ b/LYZ/model/Bartmodel.py
@@ -0,0 +1,898 @@
+from transformers import BartPretrainedModel, BartConfig
+from transformers.models.bart.modeling_bart import BartLearnedPositionalEmbedding, BartEncoderLayer, BartDecoderLayer, _expand_mask, \
+ _make_causal_mask, shift_tokens_right
+from transformers.modeling_outputs import BaseModelOutput, BaseModelOutputWithPastAndCrossAttentions, Seq2SeqModelOutput
+from torch.nn import TransformerEncoderLayer
+from transformers.utils import logging
+import torch.nn as nn
+import torch.nn.functional as F
+from dataclasses import dataclass
+from torch.nn import CrossEntropyLoss
+from transformers.file_utils import ModelOutput
+import torch
+import random
+from typing import Optional, Tuple
+import math
+import pandas as pd
+import numpy as np
+
+logger = logging.get_logger(__name__)
+
+
+# 引入了话语级Transformer来模拟话语之间的长期上下文依赖关系
+# 定义了可重复使用的 Transformer 模型单元
+class TransformerUnit(nn.Module):
+ def __init__(self, d_model: int, n_heads: int = 8):
+ super(TransformerUnit, self).__init__()
+
+ self.d_model = d_model # 隐藏层维度
+ self.n_heads = n_heads # 注意力头数
+ # self.out_features = out_features
+ # activation by default the GELU
+ self.transformerlayer = TransformerEncoderLayer( # 构建 Transformer 编码层的模块
+ d_model=d_model,
+ nhead=n_heads,
+ activation='gelu' # 基于高斯误差函数的激活函数
+ )
+
+ def forward(self, features):
+ features = self.transformerlayer(features) # (bsz, dim)
+ # dense_features = self.linear(features) # (bsz, cls_num)
+ return features
+
+
+# 利用 BART,一种具有编码器-解码器结构的预训练 Transformer,作为骨干模型,并通过对比和生成损失任务对其进行增强。
+# 定义 BART 模型的编码器
+class BartEncoder(BartPretrainedModel):
+ """
+ Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a
+ :class:`BartEncoderLayer`.
+
+ Args:
+ config: BartConfig
+ embed_tokens (nn.Embedding): output embedding
+ """
+
+ def __init__(self, config: BartConfig, embed_tokens: Optional[nn.Embedding] = None):
+ super().__init__(config)
+
+ self.dropout = config.dropout # dropout 率
+ self.layerdrop = config.encoder_layerdrop
+
+ embed_dim = config.d_model
+ self.padding_idx = config.pad_token_id
+ self.max_source_positions = config.max_position_embeddings
+ self.embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0 # 嵌入尺度
+
+ # 如果提供了 embed_tokens 参数,则直接使用;否则,创建一个新的嵌入层。
+ if embed_tokens is not None:
+ self.embed_tokens = embed_tokens
+ else:
+ self.embed_tokens = nn.Embedding(config.vocab_size, embed_dim, self.padding_idx)
+
+ # 位置嵌入层
+ """
+ 位置嵌入是一种用于引入序列中单词位置信息的技术,
+ 因为Transformer模型并不关注输入序列中单词的顺序。
+ 通过引入位置嵌入,模型能够了解单词在序列中的相对位置。
+ """
+ self.embed_positions = BartLearnedPositionalEmbedding(
+ config.max_position_embeddings,
+ embed_dim,
+ )
+ # 多个BART编码器层
+ self.layers = nn.ModuleList([BartEncoderLayer(config) for _ in range(config.encoder_layers)])
+ self.layernorm_embedding = nn.LayerNorm(embed_dim) # 归一化
+
+ self.init_weights()
+
+ def forward(
+ self,
+ input_ids=None, # 输入序列索引
+ attention_mask=None, # 掩码[0,1]以避免网络关注填充令牌索引
+ head_mask=None, # 掩码[0,1]使注意力模块的选定头部无效
+ inputs_embeds=None,
+ output_attentions=None,
+ output_hidden_states=None, # 是否返回隐藏层状态
+ return_dict=None, # 返回字典/元组
+ ):
+ r""" 加 r 防止字符转义
+ Args:
+ input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
+ Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you
+ provide it.
+
+ Indices can be obtained using :class:`~transformers.BartTokenizer`. See
+ :meth:`transformers.PreTrainedTokenizer.encode` and :meth:`transformers.PreTrainedTokenizer.__call__`
+ for details.
+
+ `What are input IDs? <../glossary.html#input-ids>`__
+ attention_mask (:obj:`torch.Tensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
+ Mask to avoid performing attention on padding token indices. Mask values selected in ``[0, 1]``:
+
+ - 1 for tokens that are **not masked**,
+ - 0 for tokens that are **masked**.
+
+ `What are attention masks? <../glossary.html#attention-mask>`__
+ head_mask (:obj:`torch.Tensor` of shape :obj:`(encoder_layers, encoder_attention_heads)`, `optional`):
+ Mask to nullify selected heads of the attention modules. Mask values selected in ``[0, 1]``:
+
+ - 1 indicates the head is **not masked**,
+ - 0 indicates the head is **masked**.
+
+ inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
+ Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded
+ representation. This is useful if you want more control over how to convert :obj:`input_ids` indices
+ into associated vectors than the model's internal embedding lookup matrix.
+ output_attentions (:obj:`bool`, `optional`):
+ Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under
+ returned tensors for more detail.
+ output_hidden_states (:obj:`bool`, `optional`):
+ Whether or not to return the hidden states of all layers. See ``hidden_states`` under returned tensors
+ for more detail.
+ return_dict (:obj:`bool`, `optional`):
+ Whether or not to return a :class:`~transformers.file_utils.ModelOutput` instead of a plain tuple.
+ """
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
+ output_hidden_states = (
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
+ )
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ # retrieve input_ids and inputs_embeds
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
+ elif input_ids is not None: # 如果使用 input_ids,将其展平成二维张量。
+ input_shape = input_ids.size()
+ input_ids = input_ids.view(-1, input_shape[-1])
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ # 如果没有提供 inputs_embeds,使用模型自带的嵌入层 获得 输入序列的嵌入表示
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale
+
+ # 对输入序列的位置信息进行嵌入得到张量
+ embed_pos = self.embed_positions(input_shape)
+
+ # 将位置嵌入加到输入序列的嵌入表示中,以引入位置信息。这是为了让模型更好地理解输入序列中不同位置的单词。
+ hidden_states = inputs_embeds + embed_pos
+ # 归一化操作有助于缓解训练中的梯度消失问题,提高模型的训练稳定性。
+ hidden_states = self.layernorm_embedding(hidden_states)
+ # dropout 操作
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
+
+ # expand attention_mask
+ # 如果提供了 attention_mask,为了与注意力模块的计算匹配,将其扩展为形状 [batch_size, 1, tgt_seq_len, src_seq_len]。
+ if attention_mask is not None:
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ attention_mask = _expand_mask(attention_mask, inputs_embeds.dtype)
+
+ encoder_states = () if output_hidden_states else None
+ all_attentions = () if output_attentions else None
+
+ # check if head_mask has a correct number of layers specified if desired
+ # 确保该掩码(mask)的数量与编码器层的数量匹配
+ if head_mask is not None: # head_mask 用于指定在注意力操作中哪些头部应该被禁用
+ assert head_mask.size()[0] == (
+ len(self.layers)
+ ), f"The head_mask should be specified for {len(self.layers)} layers, but it is for {head_mask.size()[0]}."
+ # 对编码器的每一层进行迭代
+ for idx, encoder_layer in enumerate(self.layers):
+ if output_hidden_states:
+ encoder_states = encoder_states + (hidden_states,) # 将每一层的隐藏状态添加到 encoder_states 中
+ # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description)
+ # LayerDrop 机制:在训练中随机跳过某些编码器层的方法,以提高模型的鲁棒性。
+ dropout_probability = random.uniform(0, 1)
+ if self.training and (dropout_probability < self.layerdrop): # skip the layer
+ layer_outputs = (None, None)
+ else:
+ if getattr(self.config, "gradient_checkpointing", False) and self.training: # 是否开启梯度检查点
+
+ def create_custom_forward(module): # 内部函数
+ def custom_forward(*inputs):
+ return module(*inputs, output_attentions)
+
+ return custom_forward
+
+ layer_outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(encoder_layer),
+ hidden_states,
+ attention_mask,
+ (head_mask[idx] if head_mask is not None else None),
+ )
+ else:
+ layer_outputs = encoder_layer(
+ hidden_states,
+ attention_mask,
+ layer_head_mask=(head_mask[idx] if head_mask is not None else None),
+ output_attentions=output_attentions,
+ )
+
+ hidden_states = layer_outputs[0]
+
+ if output_attentions:
+ all_attentions = all_attentions + (layer_outputs[1],)
+
+ if output_hidden_states:
+ encoder_states = encoder_states + (hidden_states,)
+
+ if not return_dict: # 如果不使用字典,则返回元组
+ return tuple(v for v in [hidden_states, encoder_states, all_attentions] if v is not None)
+ return BaseModelOutput(
+ last_hidden_state=hidden_states, hidden_states=encoder_states, attentions=all_attentions
+ )
+
+
+# 定义 BART 模型的解码器
+class BartDecoder(BartPretrainedModel):
+ """
+ Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a :class:`BartDecoderLayer`
+
+ Args:
+ config: BartConfig
+ embed_tokens (nn.Embedding): output embedding
+ """
+
+ def __init__(self, config: BartConfig, embed_tokens: Optional[nn.Embedding] = None):
+ super().__init__(config)
+ self.dropout = config.dropout
+ self.layerdrop = config.decoder_layerdrop
+ self.padding_idx = config.pad_token_id
+ self.max_target_positions = config.max_position_embeddings
+ self.embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0 # 嵌入尺度
+
+ # 嵌入层
+ if embed_tokens is not None:
+ self.embed_tokens = embed_tokens
+ else:
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model, self.padding_idx)
+
+ # 位置嵌入层
+ self.embed_positions = BartLearnedPositionalEmbedding(
+ config.max_position_embeddings,
+ config.d_model,
+ )
+ # 多个BART解码器层
+ self.layers = nn.ModuleList([BartDecoderLayer(config) for _ in range(config.decoder_layers)])
+ self.layernorm_embedding = nn.LayerNorm(config.d_model)
+
+ self.init_weights()
+
+ # 返回嵌入层
+ def get_input_embeddings(self):
+ return self.embed_tokens
+
+ # 设置嵌入层
+ def set_input_embeddings(self, value):
+ self.embed_tokens = value
+
+ # 创建解码器的自注意力掩码。包括 创建因果(causal)掩码和扩展输入序列的掩码
+ def _prepare_decoder_attention_mask(self, attention_mask, input_shape, inputs_embeds, past_key_values_length):
+ # create causal mask
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ combined_attention_mask = None
+ if input_shape[-1] > 1:
+ combined_attention_mask = _make_causal_mask(
+ input_shape, inputs_embeds.dtype, past_key_values_length=past_key_values_length
+ ).to(self.device)
+
+ if attention_mask is not None:
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1])
+ combined_attention_mask = (
+ expanded_attn_mask if combined_attention_mask is None else expanded_attn_mask + combined_attention_mask
+ )
+
+ return combined_attention_mask
+
+ def forward(
+ self,
+ input_ids=None,
+ attention_mask=None,
+ encoder_hidden_states=None,
+ encoder_attention_mask=None,
+ head_mask=None,
+ cross_attn_head_mask=None,
+ past_key_values=None,
+ inputs_embeds=None,
+ use_cache=None, # 解码过程可以通过缓存中间结果,避免在每个时间步重新计算。
+ output_attentions=None,
+ output_hidden_states=None,
+ return_dict=None,
+ ):
+ r"""
+ Args:
+ input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
+ Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you
+ provide it.
+
+ Indices can be obtained using :class:`~transformers.BartTokenizer`. See
+ :meth:`transformers.PreTrainedTokenizer.encode` and :meth:`transformers.PreTrainedTokenizer.__call__`
+ for details.
+
+ `What are input IDs? <../glossary.html#input-ids>`__
+ attention_mask (:obj:`torch.Tensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
+ Mask to avoid performing attention on padding token indices. Mask values selected in ``[0, 1]``:
+
+ - 1 for tokens that are **not masked**,
+ - 0 for tokens that are **masked**.
+
+ `What are attention masks? <../glossary.html#attention-mask>`__
+ encoder_hidden_states (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, encoder_sequence_length, hidden_size)`, `optional`):
+ Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention
+ of the decoder.
+ encoder_attention_mask (:obj:`torch.LongTensor` of shape :obj:`(batch_size, encoder_sequence_length)`, `optional`):
+ Mask to avoid performing cross-attention on padding tokens indices of encoder input_ids. Mask values
+ selected in ``[0, 1]``:
+
+ - 1 for tokens that are **not masked**,
+ - 0 for tokens that are **masked**.
+
+ `What are attention masks? <../glossary.html#attention-mask>`__
+ head_mask (:obj:`torch.Tensor` of shape :obj:`(decoder_layers, decoder_attention_heads)`, `optional`):
+ Mask to nullify selected heads of the attention modules. Mask values selected in ``[0, 1]``:
+
+ - 1 indicates the head is **not masked**,
+ - 0 indicates the head is **masked**.
+
+ cross_attn_head_mask (:obj:`torch.Tensor` of shape :obj:`(decoder_layers, decoder_attention_heads)`, `optional`):
+ Mask to nullify selected heads of the cross-attention modules in the decoder to avoid performing
+ cross-attention on hidden heads. Mask values selected in ``[0, 1]``:
+
+ - 1 indicates the head is **not masked**,
+ - 0 indicates the head is **masked**.
+
+ past_key_values (:obj:`tuple(tuple(torch.FloatTensor))`, `optional`, returned when ``use_cache=True`` is passed or when ``config.use_cache=True``):
+ Tuple of :obj:`tuple(torch.FloatTensor)` of length :obj:`config.n_layers`, with each tuple having 2
+ tensors of shape :obj:`(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional
+ tensors of shape :obj:`(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`.
+
+ Contains pre-computed hidden-states (key and values in the self-attention blocks and in the
+ cross-attention blocks) that can be used (see :obj:`past_key_values` input) to speed up sequential
+ decoding.
+
+ If :obj:`past_key_values` are used, the user can optionally input only the last
+ :obj:`decoder_input_ids` (those that don't have their past key value states given to this model) of
+ shape :obj:`(batch_size, 1)` instead of all :obj:`decoder_input_ids`` of shape :obj:`(batch_size,
+ sequence_length)`.
+ inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
+ Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded
+ representation. This is useful if you want more control over how to convert :obj:`input_ids` indices
+ into associated vectors than the model's internal embedding lookup matrix.
+ output_attentions (:obj:`bool`, `optional`):
+ Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under
+ returned tensors for more detail.
+ output_hidden_states (:obj:`bool`, `optional`):
+ Whether or not to return the hidden states of all layers. See ``hidden_states`` under returned tensors
+ for more detail.
+ return_dict (:obj:`bool`, `optional`):
+ Whether or not to return a :class:`~transformers.file_utils.ModelOutput` instead of a plain tuple.
+ """
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
+ output_hidden_states = (
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ # retrieve input_ids and inputs_embeds
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ input_ids = input_ids.view(-1, input_shape[-1])
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds")
+
+ # past_key_values_length
+ past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0
+
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_tokens(input_ids) * self.embed_scale
+
+ attention_mask = self._prepare_decoder_attention_mask(
+ attention_mask, input_shape, inputs_embeds, past_key_values_length
+ )
+
+ # expand encoder attention mask
+ if encoder_hidden_states is not None and encoder_attention_mask is not None:
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ encoder_attention_mask = _expand_mask(encoder_attention_mask, inputs_embeds.dtype, tgt_len=input_shape[-1])
+
+ # embed positions
+ positions = self.embed_positions(input_shape, past_key_values_length)
+
+ hidden_states = inputs_embeds + positions
+ hidden_states = self.layernorm_embedding(hidden_states)
+
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
+
+ # decoder layers
+ all_hidden_states = () if output_hidden_states else None
+ all_self_attns = () if output_attentions else None
+ all_cross_attentions = () if (output_attentions and encoder_hidden_states is not None) else None
+ next_decoder_cache = () if use_cache else None
+
+ # check if head_mask/cross_attn_head_mask has a correct number of layers specified if desired
+ for attn_mask, mask_name in zip([head_mask, cross_attn_head_mask], ["head_mask", "cross_attn_head_mask"]):
+ if attn_mask is not None:
+ assert attn_mask.size()[0] == (
+ len(self.layers)
+ ), f"The `{mask_name}` should be specified for {len(self.layers)} layers, but it is for {head_mask.size()[0]}."
+ for idx, decoder_layer in enumerate(self.layers):
+ # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description)
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+ dropout_probability = random.uniform(0, 1)
+ if self.training and (dropout_probability < self.layerdrop):
+ continue
+
+ past_key_value = past_key_values[idx] if past_key_values is not None else None
+
+ if getattr(self.config, "gradient_checkpointing", False) and self.training: # 是否开启梯度检查点
+
+ if use_cache: # 这在生成任务(如文本生成)中特别有用,因为每次生成一个 token 时,都可以重复使用之前生成的中间结果,而无需重新计算整个序列。
+ logger.warning( # 两个参数不兼容
+ "`use_cache=True` is incompatible with `config.gradient_checkpointing=True`. Setting "
+ "`use_cache=False`..."
+ )
+ use_cache = False
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for past_key_value
+ return module(*inputs, output_attentions, use_cache)
+
+ return custom_forward
+
+ layer_outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(decoder_layer),
+ hidden_states,
+ attention_mask,
+ encoder_hidden_states,
+ encoder_attention_mask,
+ head_mask[idx] if head_mask is not None else None,
+ cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None,
+ None,
+ )
+ else:
+
+ layer_outputs = decoder_layer(
+ hidden_states,
+ attention_mask=attention_mask,
+ encoder_hidden_states=encoder_hidden_states,
+ encoder_attention_mask=encoder_attention_mask,
+ layer_head_mask=(head_mask[idx] if head_mask is not None else None),
+ cross_attn_layer_head_mask=(
+ cross_attn_head_mask[idx] if cross_attn_head_mask is not None else None
+ ),
+ past_key_value=past_key_value,
+ output_attentions=output_attentions,
+ use_cache=use_cache,
+ )
+ hidden_states = layer_outputs[0]
+
+ if use_cache:
+ next_decoder_cache += (layer_outputs[3 if output_attentions else 1],)
+
+ if output_attentions:
+ all_self_attns += (layer_outputs[1],)
+
+ if encoder_hidden_states is not None:
+ all_cross_attentions += (layer_outputs[2],)
+
+ # add hidden states from the last decoder layer
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ next_cache = next_decoder_cache if use_cache else None
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_cross_attentions]
+ if v is not None
+ )
+ return BaseModelOutputWithPastAndCrossAttentions(
+ last_hidden_state=hidden_states,
+ past_key_values=next_cache,
+ hidden_states=all_hidden_states,
+ attentions=all_self_attns,
+ cross_attentions=all_cross_attentions,
+ )
+
+
+# 完整版 Bart 模型
+class BartModel(BartPretrainedModel):
+ def __init__(self, config: BartConfig):
+ super().__init__(config)
+
+ padding_idx, vocab_size = config.pad_token_id, config.vocab_size
+ self.shared = nn.Embedding(vocab_size, config.d_model, padding_idx)
+
+ self.encoder = BartEncoder(config, self.shared)
+ self.decoder = BartDecoder(config, self.shared)
+
+ self.init_weights()
+
+ def get_input_embeddings(self):
+ return self.shared
+
+ def set_input_embeddings(self, value):
+ self.shared = value
+ self.encoder.embed_tokens = self.shared
+ self.decoder.embed_tokens = self.shared
+
+ def get_encoder(self):
+ return self.encoder
+
+ def get_decoder(self):
+ return self.decoder
+
+ def forward(
+ self,
+ input_ids=None,
+ attention_mask=None,
+ decoder_input_ids=None,
+ decoder_attention_mask=None,
+ head_mask=None,
+ decoder_head_mask=None,
+ cross_attn_head_mask=None,
+ encoder_outputs=None,
+ past_key_values=None,
+ inputs_embeds=None,
+ decoder_inputs_embeds=None,
+ use_cache=None,
+ output_attentions=None,
+ output_hidden_states=None,
+ return_dict=None,
+ ):
+
+ # different to other models, Bart automatically creates decoder_input_ids from
+ # input_ids if no decoder_input_ids are provided
+ if decoder_input_ids is None and decoder_inputs_embeds is None:
+ decoder_input_ids = shift_tokens_right(
+ input_ids, self.config.pad_token_id, self.config.decoder_start_token_id
+ )
+
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
+ output_hidden_states = (
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if encoder_outputs is None:
+ encoder_outputs = self.encoder(
+ input_ids=input_ids,
+ attention_mask=attention_mask,
+ head_mask=head_mask,
+ inputs_embeds=inputs_embeds,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+ # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput when return_dict=True
+ elif return_dict and not isinstance(encoder_outputs, BaseModelOutput):
+ encoder_outputs = BaseModelOutput(
+ last_hidden_state=encoder_outputs[0],
+ hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
+ attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
+ )
+
+ # decoder outputs consists of (dec_features, past_key_value, dec_hidden, dec_attn)
+ decoder_outputs = self.decoder(
+ input_ids=decoder_input_ids,
+ attention_mask=decoder_attention_mask,
+ encoder_hidden_states=encoder_outputs[0],
+ encoder_attention_mask=attention_mask,
+ head_mask=decoder_head_mask,
+ cross_attn_head_mask=cross_attn_head_mask,
+ past_key_values=past_key_values,
+ inputs_embeds=decoder_inputs_embeds,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ if not return_dict:
+ return decoder_outputs + encoder_outputs
+
+ return Seq2SeqModelOutput(
+ last_hidden_state=decoder_outputs.last_hidden_state,
+ past_key_values=decoder_outputs.past_key_values,
+ decoder_hidden_states=decoder_outputs.hidden_states,
+ decoder_attentions=decoder_outputs.attentions,
+ cross_attentions=decoder_outputs.cross_attentions,
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
+ encoder_hidden_states=encoder_outputs.hidden_states,
+ encoder_attentions=encoder_outputs.attentions,
+ )
+
+
+def SupConLoss(temperature=0.07, contrast_mode='all', features=None, labels=None, mask=None):
+ """Supervised Contrastive Learning: https://arxiv.org/pdf/2004.11362.pdf."""
+ device = (torch.device('cuda') if features.is_cuda else torch.device('cpu'))
+
+ if len(features.shape) < 3:
+ raise ValueError('`features` needs to be [bsz, n_views, ...],'
+ 'at least 3 dimensions are required')
+ if len(features.shape) > 3:
+ features = features.view(features.shape[0], features.shape[1], -1)
+
+ batch_size = features.shape[0]
+ if labels is not None and mask is not None:
+ raise ValueError('Cannot define both `labels` and `mask`')
+ elif labels is None and mask is None:
+ mask = torch.eye(batch_size, dtype=torch.float32).to(device)
+ elif labels is not None:
+ labels = labels.contiguous().view(-1, 1)
+ if labels.shape[0] != batch_size:
+ raise ValueError('Num of labels does not match num of features')
+ mask = torch.eq(labels, labels.T).float().to(device) # 1 indicates two items belong to same class
+ else:
+ mask = mask.float().to(device)
+
+ contrast_count = features.shape[1] # num of views
+ contrast_feature = torch.cat(torch.unbind(features, dim=1), dim=0) # (bsz * views, dim)
+ if contrast_mode == 'one':
+ anchor_feature = features[:, 0]
+ anchor_count = 1
+ elif contrast_mode == 'all':
+ anchor_feature = contrast_feature # (bsz * views, dim)
+ anchor_count = contrast_count # num of views
+ else:
+ raise ValueError('Unknown mode: {}'.format(contrast_mode))
+
+ # compute logits
+ anchor_dot_contrast = torch.div(
+ torch.matmul(anchor_feature, contrast_feature.T), temperature) # (bsz, bsz)
+ # for numerical stability
+ logits_max, _ = torch.max(anchor_dot_contrast, dim=1, keepdim=True) # (bsz, 1)
+ logits = anchor_dot_contrast - logits_max.detach() # (bsz, bsz) set max_value in logits to zero
+ # logits = anchor_dot_contrast
+
+ # tile mask
+ mask = mask.repeat(anchor_count, contrast_count) # (anchor_cnt * bsz, contrast_cnt * bsz)
+ # mask-out self-contrast cases
+ logits_mask = torch.scatter(torch.ones_like(mask), 1, torch.arange(batch_size * anchor_count).view(-1, 1).to(device),
+ 0) # (anchor_cnt * bsz, contrast_cnt * bsz)
+ mask = mask * logits_mask # 1 indicates two items belong to same class and mask-out itself
+
+ # compute log_prob
+ exp_logits = torch.exp(logits) * logits_mask # (anchor_cnt * bsz, contrast_cnt * bsz)
+ log_prob = logits - torch.log(exp_logits.sum(1, keepdim=True) + 1e-12)
+
+ # compute mean of log-likelihood over positive
+ if 0 in mask.sum(1):
+ raise ValueError('Make sure there are at least two instances with the same class')
+ # temp = mask.sum(1)
+ mean_log_prob_pos = (mask * log_prob).sum(1) / (mask.sum(1) + 1e-12)
+
+ # loss
+ # loss = - (self.temperature / self.base_temperature) * mean_log_prob_pos
+ loss = -mean_log_prob_pos
+ loss = loss.view(anchor_count, batch_size).mean()
+ return loss
+
+
+@dataclass
+class Seq2SeqLMOutput(ModelOutput):
+ loss: Optional[torch.FloatTensor] = None
+ ce_loss: Optional[torch.FloatTensor] = None
+ cl_loss: Optional[torch.FloatTensor] = None
+ gen_loss: Optional[torch.FloatTensor] = None
+ logits: torch.FloatTensor = None
+ cls_logits: torch.FloatTensor = None
+ last_hidden_states: torch.FloatTensor = None
+ past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None
+ decoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None
+ decoder_attentions: Optional[Tuple[torch.FloatTensor]] = None
+ cross_attentions: Optional[Tuple[torch.FloatTensor]] = None
+ encoder_last_hidden_state: Optional[torch.FloatTensor] = None
+ encoder_hidden_states: Optional[Tuple[torch.FloatTensor]] = None
+ encoder_attentions: Optional[Tuple[torch.FloatTensor]] = None
+
+
+"""
+class BartForMultiTask(BartPretrainedModel):
+"""
+
+
+class BartForERC(BartPretrainedModel):
+ base_model_prefix = "model"
+ _keys_to_ignore_on_load_missing = [r"final_logits_bias", r"lm_head\.weight"]
+
+ def __init__(self, config: BartConfig, temperature, alpha, beta, use_trans_layer):
+ super().__init__(config)
+ self.model = BartModel(config)
+ # 注册一个名为 final_logits_bias 的缓冲区,用于生成最终的 logits
+ self.register_buffer("final_logits_bias", torch.zeros((1, self.model.shared.num_embeddings)))
+ # 使用一个线性层作为语言模型头(lm_head),将 BART 的隐藏表示映射到词汇表空间。
+ self.lm_head = nn.Linear(config.d_model, self.model.shared.num_embeddings, bias=False)
+
+ self.init_weights()
+
+ # 引入了一个 Transformer 单元作为辅助任务模块,用于处理上下文表示。
+ self.transformer_unit = TransformerUnit(d_model=config.hidden_size, n_heads=8)
+ # 前馈神经网络(ffn)用于分类任务,包括两个线性层和一个 GELU 激活函数。
+ self.ffn = nn.Sequential(nn.Linear(config.hidden_size, 400),
+ nn.Dropout(0.3),
+ nn.GELU(),
+ nn.Linear(400, config.num_labels))
+
+ self.temperature = temperature # 温度参数,用于控制生成任务的 softmax 温度。
+ self.alpha = alpha # 用于组合分类任务和对比损失的权重参数
+ self.beta = beta # 用于组合分类任务和对比损失的权重参数(具体得看公式)
+ self.num_labels = config.num_labels
+ self.use_trans_layer = use_trans_layer # 是否使用 Transformer 单元进行特征变换
+
+ def get_encoder(self):
+ return self.model.get_encoder()
+
+ def get_decoder(self):
+ return self.model.get_decoder()
+
+ # 提供了改变 token embeddings 大小的方法
+ def resize_token_embeddings(self, new_num_tokens: int) -> nn.Embedding:
+ new_embeddings = super().resize_token_embeddings(new_num_tokens)
+ self._resize_final_logits_bias(new_num_tokens)
+ return new_embeddings
+
+ def _resize_final_logits_bias(self, new_num_tokens: int) -> None:
+ old_num_tokens = self.final_logits_bias.shape[-1]
+ if new_num_tokens <= old_num_tokens:
+ new_bias = self.final_logits_bias[:, :new_num_tokens]
+ else:
+ extra_bias = torch.zeros((1, new_num_tokens - old_num_tokens), device=self.final_logits_bias.device)
+ new_bias = torch.cat([self.final_logits_bias, extra_bias], dim=1)
+ self.register_buffer("final_logits_bias", new_bias)
+
+ # 获取输出 embeddings 的方法
+ def get_output_embeddings(self):
+ return self.lm_head
+
+ def set_output_embeddings(self, new_embeddings):
+ self.lm_head = new_embeddings
+
+ def forward(
+ self,
+ input_ids=None, # 输入序列的 token IDs
+ attention_mask=None, # 输入序列的注意力掩码,指示哪些位置是真实的 token
+ decoder_input_ids=None, # 解码器输入序列的 token IDs(用于生成任务)
+ decoder_attention_mask=None, # 解码器输入序列的注意力掩码
+ head_mask=None,
+ decoder_head_mask=None,
+ cross_attn_head_mask=None,
+ encoder_outputs=None,
+ past_key_values=None,
+ inputs_embeds=None,
+ decoder_inputs_embeds=None,
+ labels=None, # 分类任务的真实标签
+ use_cache=None,
+ output_attentions=None,
+ output_hidden_states=None,
+ return_dict=None,
+ speakers=None,
+ next_input_ids=None, # 是否进行生成任务
+ next_attention_mask=None,
+ ):
+ r"""
+ labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
+ Labels for computing the masked language modeling loss. Indices should either be in ``[0, ...,
+ config.vocab_size]`` or -100 (see ``input_ids`` docstring). Tokens with indices set to ``-100`` are ignored
+ (masked), the loss is only computed for the tokens with labels in ``[0, ..., config.vocab_size]``.
+
+ Returns:
+ """
+ # 上下文掩码,表示哪些位置是真实的 token,通过计算输入序列的注意力掩码的和来得到
+ context_mask = torch.sum(attention_mask, dim=-1).gt(0)
+
+ batch_size, max_seq_len_ex, max_text_seq_len = input_ids.shape
+ seqlens = torch.sum(context_mask, dim=-1)
+
+ # 生成任务
+ if next_input_ids is not None:
+ decoder_input_ids = shift_tokens_right( # shift_tokens_right 函数将 next_input_ids 右移一位,得到解码器的输入序列。
+ next_input_ids[context_mask, :], self.config.pad_token_id, self.config.decoder_start_token_id
+ )
+ # hidden state for generation —— 生成任务
+ # 对于生成任务,使用 BartModel 处理输入序列和生成序列的隐藏表示,然后通过 lm_head 得到 logits
+ outputs_gen = self.model(input_ids=input_ids[context_mask, :],
+ attention_mask=attention_mask[context_mask, :],
+ decoder_input_ids=decoder_input_ids)
+ hidden_states_gen = outputs_gen.last_hidden_state
+ gen_logits = self.lm_head(hidden_states_gen) + self.final_logits_bias
+
+ # hidden state for classification —— 分类任务
+ # 对于分类任务,使用 BartModel 处理输入序列,提取隐藏表示,通过最大池化获得全局特征,然后通过前馈神经网络 ffn 得到分类的 logits。
+ outputs_cls = self.model(input_ids=input_ids[context_mask, :], # 使用上下文掩码提取输入序列的隐藏表示
+ attention_mask=attention_mask[context_mask, :])
+ hidden_states_cls = outputs_cls.last_hidden_state
+
+ mask_for_fill = attention_mask[context_mask, :].unsqueeze(-1).expand(-1, -1, hidden_states_cls.shape[-1]).bool()
+
+ hidden_states_dropout = hidden_states_cls.clone().detach()
+
+ hidden_states = hidden_states_cls.masked_fill(~mask_for_fill, -1e8) # mask position of padding with -1e8
+ hidden_states_dropout = hidden_states_dropout.masked_fill(~mask_for_fill, -1e8)
+ cls_tokens, _ = torch.max(hidden_states, dim=1) # max pooling 最大池化获得全局特征 cls_tokens
+ cls_tokens_dropout, _ = torch.max(hidden_states_dropout, dim=1)
+
+ # 保证每个批次中的样本在序列长度上具有相同的维度
+ we_dim = self.config.hidden_size
+ for ibatch in range(batch_size):
+ # 计算需要填充的零向量 fullzeropad4insert,其形状为 [max_seq_len_ex - seqlens[ibatch], we_dim],
+ # 其中 max_seq_len_ex 是序列的最大长度,seqlens[ibatch] 是当前样本的实际序列长度。
+ fullzeropad4insert = torch.zeros([max_seq_len_ex - seqlens[ibatch], we_dim], device=cls_tokens.device)
+ # 计算插入位置的索引 index4insert,该位置是批次中当前样本序列的末尾
+ index4insert = ibatch * max_seq_len_ex + seqlens[ibatch]
+ # 将零向量插入到 cls_tokens 的相应位置。这将在当前样本的序列末尾添加零向量,以使所有样本的序列长度相等。
+ cls_tokens = torch.cat([cls_tokens[:index4insert], fullzeropad4insert, cls_tokens[index4insert:]], dim=0)
+ # 将零向量插入到 cls_tokens_dropout 的相应位置
+ cls_tokens_dropout = torch.cat([cls_tokens_dropout[:index4insert], fullzeropad4insert, cls_tokens_dropout[index4insert:]], dim=0)
+ # 将调整后的 cls_tokens 和 cls_tokens_dropout 的形状变回 [batch_size, max_seq_len_ex, we_dim]
+ cls_tokens = cls_tokens.view(batch_size, max_seq_len_ex, we_dim)
+ cls_tokens_dropout = cls_tokens_dropout.view(batch_size, max_seq_len_ex, we_dim)
+
+ if self.use_trans_layer:
+ cls_tokens = self.transformer_unit(cls_tokens)
+ cls_tokens_dropout = self.transformer_unit(cls_tokens_dropout)
+
+ logits = self.ffn(cls_tokens) # 前馈神经网络
+ logits_dropout = self.ffn(cls_tokens_dropout)
+
+ loss_fct = CrossEntropyLoss()
+
+ # 生成任务损失
+ if next_input_ids is not None:
+ gen_loss = loss_fct(gen_logits.view(-1, self.config.vocab_size), next_input_ids[context_mask, :].view(-1))
+ else:
+ gen_loss = 0
+ # 分类任务损失
+ if labels is not None:
+ ce_loss = loss_fct(logits[context_mask, :], labels[context_mask]) # 交叉熵损失
+ cl_loss = SupConLoss(temperature=self.temperature, # 对比损失
+ features=torch.stack([logits[context_mask, :], logits_dropout[context_mask, :]], dim=1),
+ labels=labels[context_mask])
+ loss = (1 - self.alpha - self.beta) * ce_loss + self.alpha * cl_loss + self.beta * gen_loss # 整体损失
+ # return loss, ce_loss, cl_loss, gen_loss
+ return Seq2SeqLMOutput(
+ loss=loss,
+ ce_loss=ce_loss,
+ cl_loss=cl_loss,
+ gen_loss=gen_loss
+ )
+ else: # evaluate
+ return Seq2SeqLMOutput(
+ loss=None,
+ logits=None,
+ cls_logits=logits[context_mask, :],
+ last_hidden_states=cls_tokens[context_mask, :],
+ )
+
+
+"""
+# 用于生成(generation)准备输入,通常用于生成文本的场景
+def prepare_inputs_for_generation(
+"""
+
+
+def prepare_decoder_input_ids_from_labels(self, labels: torch.Tensor):
+ return shift_tokens_right(labels, self.config.pad_token_id, self.config.decoder_start_token_id)
+
+
+@staticmethod
+def _reorder_cache(past, beam_idx):
+ reordered_past = ()
+ for layer_past in past:
+ # cached cross_attention states don't have to be reordered -> they are always the same
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past[:2]) + layer_past[2:],
+ )
+ return reordered_past
diff --git a/LYZ/model/__pycache__/Bartmodel.cpython-37.pyc b/LYZ/model/__pycache__/Bartmodel.cpython-37.pyc
new file mode 100644
index 0000000..3023e3a
Binary files /dev/null and b/LYZ/model/__pycache__/Bartmodel.cpython-37.pyc differ
diff --git a/LYZ/model/__pycache__/loggingHandler.cpython-37.pyc b/LYZ/model/__pycache__/loggingHandler.cpython-37.pyc
new file mode 100644
index 0000000..16ad692
Binary files /dev/null and b/LYZ/model/__pycache__/loggingHandler.cpython-37.pyc differ
diff --git a/LYZ/model/date_process.py b/LYZ/model/date_process.py
new file mode 100644
index 0000000..bd8c494
--- /dev/null
+++ b/LYZ/model/date_process.py
@@ -0,0 +1,188 @@
+"""
+数据预处理的
+现在先跑模型
+"""
+
+import os
+import torch
+import logging
+
+from typing import Optional
+
+from dataclasses import dataclass, field
+from loggingHandler import LoggingHandler
+from Bartmodel import BartForERC
+
+from transformers import (AutoTokenizer,
+ HfArgumentParser,
+ TrainingArguments,
+ AutoConfig,
+ set_seed)
+
+import fitlog
+
+logger = logging.getLogger(__name__)
+
+"""
+python main.py \
+--model_name_or_path facebook/bart-large \
+--do_train \
+--task_name $TASK \
+--num_train_epochs $EPOCHS \
+--learning_rate $LEARNING_RATE \
+--output_dir ./save/$TASK \
+--overwrite_output_dir \
+--per_device_train_batch_size $TRAIN_BATCH_SIZE \
+--per_device_eval_batch_size $EVAL_BATCH_SIZE \
+--logging_steps $LOGGING_STEPS \
+--warmup_ratio $WARMUP_RATIO \
+--adam_epsilon 1e-6 \
+--weight_decay 0.01 \
+--seed $SEED \
+--alpha $ALPHA \
+--beta $BETA \
+--temperature $TEMPERATURE \
+--use_trans_layer $DIALOG_TRANSFORMER \
+--train_with_generation $TRAIN_WITH_GENERATION
+
+EPOCHS=4
+TRAIN_BATCH_SIZE=2
+LOGGING_STEPS=500
+WARMUP_RATIO=0.3
+LEARNING_RATE=2e-5
+ALPHA=0.1
+BETA=0.1
+TEMPERATURE=5
+"""
+
+# 差点 参数解析需要其他参数
+# 训练后模型保存地址
+model_output_dir = "./"
+
+rng_seed = -1 # 随机数种子,对话默认 738497
+model_name_or_path = "facebook/bart-large" # C:/Users/A00l/.cache/huggingface/hub/models--facebook--bart-large/snapshots/cb48c1365bd826bd521f650dc2e0940aee54720c" # 模型
+do_train = 1 # 训练模式
+do_eval = 0 # 验证模式
+temperature = 5
+alpha = 0.1
+beta = 0.1
+use_trans_layer = 1
+
+if __name__ == '__main__':
+ # fitlog.commit(__file__)
+ logging.basicConfig(format='%(asctime)s - %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S',
+ level=logging.INFO,
+ handlers=[LoggingHandler()])
+
+ # Set seed before initializing model.
+
+ # 设置日志格式和级别
+ fitlog.set_log_dir('./logs/')
+ # 设置随机种子
+ rnd_seed = fitlog.set_rng_seed() if rng_seed == -1 else fitlog.set_rng_seed(rng_seed)
+ # training_args.seed = rnd_seed
+
+ logger.info("The random seed is %d" % rnd_seed)
+
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
+
+ # speaker_vocab, label_vocab = load_vocab(other_args.task_name) # 加载词汇表
+ num_labels = 6 # 标签数量
+
+ # 初始化 BART 模型的分词器
+ tokenizer = AutoTokenizer.from_pretrained(
+ "facebook/bart-base",
+ cache_dir=None,
+ use_fast=True)
+
+ data = torch.randint(255, size=(10, 14, 100))
+ """
+ train_dataloader, eval_dataloader, test_dataloader = get_dataloaders(tokenizer, other_args.task_name,
+ train_batch_size=training_args.per_device_train_batch_size,
+ eval_batch_size=training_args.per_device_eval_batch_size,
+ device=device,
+ train_with_generation=other_args.train_with_generation,
+ max_seq_length=128) # 可以对应数据包数量
+
+ # 将所有的参数整合到一个字典中
+ param_dict = {}
+ for k, v in vars(training_args).items():
+ param_dict[k] = v
+ for k, v in vars(data_args).items():
+ param_dict[k] = v
+ for k, v in vars(model_args).items():
+ param_dict[k] = v
+ for k, v in vars(other_args).items():
+ param_dict[k] = v
+
+
+ # 使用fitlog库记录超参数
+ fitlog.add_hyper(param_dict)"""
+ fitlog.add_hyper_in_file(__file__)
+
+ try:
+
+ qs = [None]
+ if do_train:
+ config = AutoConfig.from_pretrained(
+ model_name_or_path,
+ num_labels=num_labels,
+ # finetuning_task=task_name,
+ cache_dir=None,
+ revision=None,
+ use_auth_token=None,
+ )
+ config.use_cache = True
+
+ model = BartForERC.from_pretrained( # 情感识别模型
+ model_name_or_path,
+ from_tf=bool(".ckpt" in model_name_or_path),
+ config=config,
+ cache_dir=None,
+ revision=None,
+ use_auth_token=None,
+ temperature=temperature,
+ alpha=alpha,
+ beta=beta,
+ use_trans_layer=use_trans_layer
+ )
+ # print(model)
+ model = model.to(device)
+
+ # train(train_dataloader, eval_dataloader, test_dataloader, model, training_args, other_args)
+
+ fitlog.finish()
+
+ except KeyboardInterrupt:
+ print("Catch keyboard interrupt.")
+
+ # 保存最佳模型
+ if do_train:
+ best_model_path = os.path.join(model_output_dir, "best_model_%d" % rnd_seed)
+ else:
+ best_model_path = model_name_or_path
+
+"""
+ if do_eval or do_predict:
+ config = AutoConfig.from_pretrained(best_model_path)
+
+ model = BartForERC.from_pretrained(
+ best_model_path,
+ from_tf=bool(".ckpt" in model_name_or_path),
+ config=config,
+ temperature=temperature,
+ alpha=alpha,
+ beta=beta,
+ use_trans_layer=use_trans_layer
+ )
+ model = model.to(device)
+
+ if do_eval:
+ results = evaluate(training_args, other_args, eval_dataloader, model, "evaluate")
+ print(results)
+
+ if do_predict:
+ results = evaluate(training_args, other_args, test_dataloader, model, "predict")
+ print(results)
+"""
diff --git a/LYZ/model/loggingHandler.py b/LYZ/model/loggingHandler.py
new file mode 100644
index 0000000..b515cbf
--- /dev/null
+++ b/LYZ/model/loggingHandler.py
@@ -0,0 +1,22 @@
+# For longer texts or text not related to a specific progress bar
+# tqdm offers write() which logs text safely to the console. To be
+# precise, it adds the text above the progress bars, so each line
+# you ever logged using write() will be visible.
+
+import logging
+import tqdm
+
+
+class LoggingHandler(logging.Handler):
+ # default: logging.info
+ def __init__(self, level=logging.NOTSET):
+ super().__init__(level)
+
+ def emit(self, record):
+ # must be implemented in the logginghandler subclass
+ try:
+ msg = self.format(record)
+ tqdm.tqdm.write(msg)
+ self.flush()
+ except (KeyboardInterrupt, SystemExit):
+ self.handleError(record)
diff --git a/LYZ/model/model.py b/LYZ/model/model.py
new file mode 100644
index 0000000..999c118
--- /dev/null
+++ b/LYZ/model/model.py
@@ -0,0 +1,80 @@
+"""
+Bart网络
+
+"""
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from transformers import BartPretrainedModel, BartConfig
+
+
+class SubNet(nn.Module):
+ def __init__(
+ self,
+ block,
+ layers,
+ in_channel=3,
+ zero_init_residual=False,
+ groups=1,
+ width_per_group=64,
+ replace_stride_with_dilation=None,
+ norm_layer=None,
+ ):
+ super(SubNet, self).__init__()
+
+ def _forward_impl(self, x):
+ # See note [TorchScript super()]
+ # with torch.no_grad():
+ x = self.conv1(x)
+ x = self.bn1(x)
+ x = self.relu(x)
+ x = self.maxpool(x)
+
+ x = self.layer1(x)
+ x = self.layer2(x)
+ x = self.layer3(x)
+ x = self.layer4(x)
+
+ x = self.avgpool(x)
+ x = torch.flatten(x, 1)
+ x = self.fc(x)
+
+ return x
+
+ def forward(self, x):
+ return self._forward_impl(x)
+
+
+class Network(nn.Module):
+ def __init__(self, subnet, hidden_dim, feature_dim, class_num):
+ super(Network, self).__init__()
+ self.subnet = subnet
+ self.feature_dim = feature_dim
+ self.cluster_num = class_num
+ self.instance_projector = nn.Sequential(
+ nn.BatchNorm1d(hidden_dim),
+ nn.ReLU(),
+ nn.Linear(hidden_dim, hidden_dim),
+ nn.BatchNorm1d(hidden_dim),
+ nn.ReLU(),
+ nn.Linear(hidden_dim, self.feature_dim),
+ )
+ self.cluster_projector = nn.Sequential(
+ nn.BatchNorm1d(hidden_dim),
+ nn.ReLU(),
+ nn.Linear(hidden_dim, hidden_dim),
+ nn.BatchNorm1d(hidden_dim),
+ nn.ReLU(),
+ nn.Linear(hidden_dim, self.cluster_num),
+ )
+
+ def forward(self, x_i, x_j, return_ci=True):
+ pass
+
+
+ def forward_zc(self, x):
+ h = self.subnet(x)
+ z = F.normalize(self.instance_projector(h), dim=1)
+ c = self.cluster_projector(h)
+ c = F.softmax(c, dim=1)
+ return z, c
diff --git a/LYZ/test.py b/LYZ/test.py
new file mode 100644
index 0000000..438a1e3
--- /dev/null
+++ b/LYZ/test.py
@@ -0,0 +1,222 @@
+# 打印网络测试而已
+import torch
+import torch.nn as nn
+from torch.nn.functional import normalize
+
+
+class OneHotEncodingLayer(nn.Module):
+ def __init__(self, sz=256):
+ super(OneHotEncodingLayer, self).__init__()
+ self.size = sz
+
+ def forward(self, x):
+ return torch.nn.functional.one_hot(x, num_classes=self.size).float()
+
+
+class ByteBlock(nn.Module):
+ def __init__(self, in_channels, nb_filter=(64, 100), filter_length=(3, 3),
+ subsample=(2, 1), pool_length=(2, 2)):
+ super(ByteBlock, self).__init__()
+
+ layers = []
+ for i in range(len(nb_filter)):
+ layers.append(nn.Conv1d(in_channels, nb_filter[i], kernel_size=filter_length[i],
+ padding=0, stride=subsample[i]))
+ layers.append(nn.Tanh())
+ if pool_length[i]:
+ layers.append(nn.MaxPool1d(pool_length[i]))
+ in_channels = nb_filter[i]
+
+ self.block = nn.Sequential(*layers)
+ self.global_pool = nn.AdaptiveMaxPool1d(1)
+ self.fc = nn.Linear(nb_filter[-1], 128)
+
+ def forward(self, x):
+ x = self.block(x)
+ x = self.global_pool(x).squeeze(dim=2)
+ x = torch.nn.functional.relu(self.fc(x))
+ return x
+
+
+
+class FEMnet(nn.Module):
+ """
+ Feature extraction module 定义
+ """
+ def __init__(self, flow_len, packet_len, gru_units):
+ super(FEMnet, self).__init__()
+ self.packet_len = packet_len
+ self.flow_len = flow_len
+ self.batch_size = 10
+ self.gru_hidden_size = gru_units
+ self.rep_dim = gru_units
+
+ self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
+ self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
+ self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
+
+ self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
+ # self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5)
+ # self.output = nn.Softmax(dim=1) # Linear 自带Softmax 分类
+
+ def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
+ embeddings_list = self.embedding(x) # [10, 14, 100, 256]
+ encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
+ for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
+ # print("embeddings 1: ", embeddings.shape)
+ # embeddings = embeddings.permute(0, 2, 1)
+ # print("embeddings 2: ", embeddings.shape)
+ encoder1 = self.block2(embeddings) # [14, 128]
+ # print("encoder 1: ", encoder1.shape)
+ encoder2 = self.block3(embeddings) # [14, 128]
+ # print("encoder 2: ", encoder2.shape)
+ encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
+ # print("encoder : ", encoder.shape)
+ encoder_list[ix] = encoder
+
+ # rnn 网络输入:[seq_len, batch_size, hidden_size]
+ encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
+ biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
+ biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
+ # print("biLSTM: ", biLSTM.shape)
+ attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
+ dense = self.dense_layer(attn_output)
+ # out = self.output(dense)
+ # out = dense[:, -1, :]
+ return dense
+
+ # lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
+ def attention_net(self, lstm_output, final_state):
+ # print("lstm_output: ", lstm_output.shape)
+ # print("final_state: ", final_state.shape)
+ # hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
+ hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
+ # attn_weights : [batch_size, n_step]
+ attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
+ soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
+ # [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
+ # = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
+ context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
+ return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
+
+
+class MyModel(nn.Module):
+ """
+ Feature extraction module定义
+ """
+ def __init__(self, binet, feature_dim, class_n):
+ super(MyModel, self).__init__()
+ self.binet = binet
+ self.feature_dim = feature_dim
+ self.cluster_num = class_n
+ """ 对比聚类 """
+ self.instance_projector = nn.Sequential( # 实例-单例
+ nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
+ nn.ReLU(),
+ nn.Linear(self.binet.rep_dim, self.feature_dim),
+ )
+ self.cluster_projector = nn.Sequential( # 聚类-集群
+ nn.Linear(self.binet.rep_dim, self.binet.rep_dim),
+ nn.ReLU(),
+ nn.Linear(self.binet.rep_dim, self.cluster_num),
+ nn.Softmax(dim=1)
+ )
+
+ # 训练时执行
+ def forward(self, x_i, x_j): # x_i, x_j 来自同一数据的两种不同预处理方式得到的嵌入矩阵
+ h_i = self.resnet(x_i)
+ h_j = self.resnet(x_j)
+
+ z_i = normalize(self.instance_projector(h_i), dim=1)
+ z_j = normalize(self.instance_projector(h_j), dim=1)
+
+ c_i = self.cluster_projector(h_i)
+ c_j = self.cluster_projector(h_j)
+
+ return z_i, z_j, c_i, c_j
+
+ # 测试时执行
+ def forward_cluster(self, x):
+ h = self.resnet(x)
+ c = self.cluster_projector(h) # 聚类分布
+ c = torch.argmax(c, dim=1) # 得到每个样本的聚类标签。
+ return c
+
+
+class MyModel1(nn.Module):
+ """
+ 模型定义
+ """
+ def __init__(self, flow_len, packet_len, gru_units):
+ super(MyModel1, self).__init__()
+ self.packet_len = packet_len
+ self.flow_len = flow_len
+ self.batch_size = 10
+ self.gru_hidden_size = gru_units
+
+ self.embedding = OneHotEncodingLayer(sz=256) # 独热编码
+ self.block2 = ByteBlock(self.packet_len, (128, 256), (5, 5), (1, 1), (2, 2))
+ self.block3 = ByteBlock(self.packet_len, (192, 320), (7, 5), (1, 1), (2, 2))
+
+ self.lstm_layer = nn.GRU(256, self.gru_hidden_size, dropout=0.1, bidirectional=True)
+ self.dense_layer = nn.Linear(self.gru_hidden_size * 2, 5) # # 其实像特征聚类,输出聚类数
+ # self.output = nn.Softmax(dim=1)
+
+ def forward(self, x): # x: [batch_size, flow_len, packet_len] = [10, 14, 100]
+ embeddings_list = self.embedding(x) # [10, 14, 100, 256]
+ encoder_list = torch.zeros((self.batch_size, self.flow_len, 256))
+ for ix, embeddings in enumerate(embeddings_list): # [14, 100, 256]
+ # print("embeddings 1: ", embeddings.shape)
+ # embeddings = embeddings.permute(0, 2, 1)
+ # print("embeddings 2: ", embeddings.shape)
+ encoder1 = self.block2(embeddings) # [14, 128]
+ # print("encoder 1: ", encoder1.shape)
+ encoder2 = self.block3(embeddings) # [14, 128]
+ # print("encoder 2: ", encoder2.shape)
+ encoder = torch.cat([encoder1, encoder2], 1) # [14, 256]
+ # print("encoder : ", encoder.shape)
+ encoder_list[ix] = encoder
+
+ # rnn 网络输入:[seq_len, batch_size, hidden_size]
+ encoder_list = encoder_list.permute(1, 0, 2) # [10, 14, 256] -> [14, 10 ,256]
+ biLSTM, final_hidden_state = self.lstm_layer(encoder_list) # [14, 10, 184], [2, 10, 92]
+ biLSTM = biLSTM.permute(1, 0, 2) # [10, 14, 184]
+ # print("biLSTM: ", biLSTM.shape)
+ attn_output, attention = self.attention_net(biLSTM, final_hidden_state)
+ dense = self.dense_layer(attn_output)
+ # out = self.output(dense)
+ # out = dense[:, -1, :]
+ return dense
+
+ # lstm_output : [batch_size, n_step, self.byte_hidden_size * num_directions(=2)], F matrix
+ def attention_net(self, lstm_output, final_state):
+ # print("lstm_output: ", lstm_output.shape)
+ # print("final_state: ", final_state.shape)
+ # hidden : [batch_size, self.byte_hidden_size * num_directions(=2), 1(=n_layer)]
+ hidden = final_state.view(-1, self.gru_hidden_size * 2, 1) # Tensor维度的重构,-1表示该维度取决于其他维度
+ # attn_weights : [batch_size, n_step]
+ attn_weights = torch.bmm(lstm_output, hidden).squeeze(2) # 加权求和,第三维降维
+ soft_attn_weights = torch.nn.functional.softmax(attn_weights, 1)
+ # [batch_size, self.byte_hidden_size * num_directions(=2), n_step] * [batch_size, n_step, 1]
+ # = [batch_size, self.byte_hidden_size * num_directions(=2), 1]
+ context = torch.bmm(lstm_output.transpose(1, 2), soft_attn_weights.unsqueeze(2)).squeeze(2)
+ return context, soft_attn_weights # context : [batch_size, self.byte_hidden_size * num_directions(=2)]
+
+if __name__ == '__main__':
+ #fe_model = FEMnet(14, 100, 92)
+ #model = MyModel(fe_model, 128, 5)
+ # print(model)
+
+ model = MyModel1(14, 100, 92)
+ data = torch.randint(255, size=(10, 14, 100)) # batch_size, flow_len, packet_len
+ model(data)
+
+"""
+ params = list(model.parameters())
+ print(len(params))
+ print(params[0].size()) # (0): conv1's .weight
+
+
+"""
+
+
diff --git a/LYZ/train.py b/LYZ/train.py
new file mode 100644
index 0000000..725dfb9
--- /dev/null
+++ b/LYZ/train.py
@@ -0,0 +1,89 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import os
+import argparse
+import numpy as np
+
+from torch.utils.tensorboard import SummaryWriter
+from torchvision.utils import make_grid
+from torch.optim import lr_scheduler
+
+from model import *
+from loss import *
+from dataloader import *
+
+
+def get_opt():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-n', '--num-workers', type=int, default=4)
+ parser.add_argument('-e', '--epoch', type=int, default=10)
+ parser.add_argument('-b', '--batch-size', type=int, default=128)
+ parser.add_argument('-t', '--test-batch-size', type=int, default=1)
+ parser.add_argument('-d', '--display-step', type=int, default=600)
+ opt = parser.parse_args()
+ return opt
+
+
+def train(opt):
+ model = PLA_Attention_Model(100, 100, 50).cuda()
+ # model.load_state_dict(torch.load('checkpoint.pt'))
+ model.train()
+
+ train_dataset = NetworkFlowDataset('Thursday-WorkingHours.pcap',
+ 'Thursday-WorkingHours-Morning-WebAttacks.pcap_ISCX.csv')
+ train_data_loader = NetworkFlowDataloader(opt, train_dataset)
+
+ test_dataset = NetworkFlowDataset('Friday-WorkingHours.pcap', 'Friday-WorkingHours-Morning.pcap_ISCX.csv')
+ test_data_loader = NetworkFlowDataloader(opt, test_dataset)
+
+ optim = torch.optim.Adam(model.parameters(), lr=0.001)
+
+ criterion = Loss()
+
+ writer = SummaryWriter()
+
+ for epoch in range(opt.epoch):
+ for i in range(len(train_data_loader.data_loader)):
+ step = epoch * len(train_data_loader.data_loader) + i + 1
+
+ # load data
+ flow, label = train_data_loader.next_batch()
+ flow = flow.cuda()
+ label = label.cuda()
+
+ # train model
+ optim.zero_grad() # 梯度清零,不加则会累加梯度
+ result = model(flow)
+ loss = criterion(result, label)
+ loss.backward()
+ optim.step()
+
+ writer.add_scalar('loss', loss, step)
+
+ writer.close()
+
+ if step % opt.display_step == 0:
+ _, predicted = torch.max(result, 1)
+ total = label.size(0)
+ correct = (predicted == label).sum().item()
+ total_test = 0
+ correct_test = 0
+ for i in range(len(test_data_loader.data_loader)):
+ flow, label = test_data_loader.next_batch()
+ flow = flow.cuda()
+ label = label.cuda()
+ result = model(flow)
+ _, predicted = torch.max(result, 1)
+ total_test += label.size(0)
+ correct_test += (predicted == label).sum().item()
+ print(
+ '[Epoch {}] Loss : {:.2}, train_acc : {:.2}, test_acc : {:.2}'.format(epoch, loss, correct / total,
+ correct_test / total_test))
+
+ torch.save(model.state_dict(), 'checkpoint.pt')
+
+
+if __name__ == '__main__':
+ opt = get_opt()
+ train(opt)