revelwivanto/Deeplearning_Malware_Analysis
GitHub: revelwivanto/Deeplearning_Malware_Analysis
基于 Sysmon 事件序列的深度学习恶意软件早期检测系统,支持 LSTM 和 Transformer 模型进行行为序列分类。
Stars: 0 | Forks: 0
# Sysmon 恶意软件检测训练 Notebook 文档
本文档说明了如何运行 Notebook 的说明
实现了 Muhammad Revel Wivanto 的毕业论文
题为 "Early Malware Detection With
Sysmon Event Sequences using LSTM and Transformer"
学号 5025211233
mrevelwivanto@gmail.com
https://youtu.be/TkITESkAd_o
## 目录
A. [Deep Learning Notebook Implementation](#deep-learning-notebook-implementation)
1. [Overview and How to Run](#overview-and-how-to-run)
2. [Configuration](#configuration)
3. [Imports and Utilities](#imports-and-utilities)
4. [Data Loading](#data-loading)
5. [Vocabulary and Tokenization](#vocabulary-and-tokenization)
6. [Helper Functions](#helper-functions)
7. [Shared Components](#shared-components)
8. [Model Architectures](#model-architectures)
9. [Training Function](#training-function)
10. [Experiment Execution](#experiment-execution)
11. [Testing and Evaluation](#testing-and-evaluation)
B. [Pre-processing](#pre-processing)
C. [Data Analysis](#data-analysis)
# Deep Learning Notebook 实现
## 概述与运行方法
该 Notebook 实现了一个早期恶意软件检测系统,用于分析 Sysmon 事件日志。其核心思想是将 process trees(相关系统事件序列)表示为已分词的文本序列,然后训练 deep learning 模型来分类某个 process tree 是否与恶意活动相关。
该 Pipeline 支持两种模型架构:
- **LSTM (Long Short-Term Memory)**:双向循环神经网络,按顺序处理序列。
- **Transformer**:基于 attention 的架构,并行处理序列。
该 Notebook 还支持两种类型的实验:
- **Event-based**:根据事件数量限制输入。
- **Time-based**:根据输入前的时间限制输入。
### 如何运行:
- **取消注释一个 EXPERIMENTS 以运行**
- **Training**:
将 `LOAD_IF_EXISTS` 设置为 False(如果文件存在将覆盖 & 将创建文件)
或者
将 `LOAD_IF_EXISTS` 设置为 True(将创建文件) **将训练具有最长进程限制的模型** - **Testing**: 将 `LOAD_IF_EXISTS` 设置为 True **将测试具有设定进程限制的模型** - **Run ALL** ## 配置 ### 文件路径 Notebook 定义了几个用于输入数据、模型存储和输出的路径: - `DATASET_PATH`:预处理后的 CSV 数据集路径 - `MODEL_SAVE_DIR`:模型所在目录 - `VOCAB_SAVE_PATH`:用于保存/加载词汇表映射的路径 - `FALSE_PREDS_OUTPUT`:错误预测事件的路径 ### 数据集约束 - `MAX_TRAIN_EVENTS`:用于基于事件实验的训练的最大事件数 (673) - `MAX_TRAIN_TIME`:用于基于时间实验的训练的最大时间窗口 (20113 个时间单位) ### 测试限制 Notebook 在各种限制下测试模型性能以进行早期恶意软件检测: - `EVENT_LIMITS_TO_TEST`:事件数量限制列表,从 1 到 673 个事件 - `TIME_LIMITS_TO_TEST`:时间阈值列表,从 1 到 20113 秒时间单位 ### 可复现性 - `SEED`:设置为 42 以确保所有随机操作的可复现性(仍为非确定性) - `LOAD_IF_EXISTS`:布尔标志,如果已存在保存的模型则跳过训练 ### 实验配置 `EXPERIMENTS` 列表定义了要运行的模型类型组合。每个条目指定: - `model`:"LSTM" 或 "Transformer" - `type`:"event" 或 "time" ### 共享配置 `SHARED_CONFIG` 字典包含所有模型的超参数: | Parameter | Value | 描述 | | ----------------------------- | ----- | ---------------------------------------------------------------------------- | | `vocab_size` | 15000 | 词汇表中唯一 token 的最大数量 | | `max_chunk_length` | 10000 | 每个序列块的最大 token 长度 | | `max_chunks` | 1 | 每个 process tree 的最大块数 | | `batch_size` | 8 | 每次梯度更新的序列数量 | | `num_epochs` | 50 | 最大训练 epoch 数量 | | `learning_rate` | 1e-3 | AdamW optimizer 的学习率 | | `weight_decay` | 1e-4 | L2 正则化强度 | | `early_stopping_patience` | 10 | 如果 F1-Score 没有提升,等待停止的 epoch 数量 | | `early_stopping_min_delta` | 0.001 | 重置 patience 所需的最小 F1 提升 | | `focal_alpha` | 0.25 | Focal Loss 的 Alpha 参数 | | `focal_gamma` | 2.0 | Focal Loss 的 Gamma 参数 | | `embedding_dim` | 32 | token embedding 的维度 | | `hnm_start_epoch` | 5 | 开始 Hard Negative Mining 的 epoch | | `hnm_interval` | 5 | Hard Negative Mining 轮次之间的 epoch 间隔 | | `hnm_threshold` | 0.15 | 触发挖掘的精确率-召回率差异阈值 | | `hnm_max_dataset_size` | 12000 | 增强后的最大数据集大小 | | `hnm_max_additions_per_round` | 1000 | 每轮 HNM 增加的最大样本数 | ### LSTM 配置 | Parameter | Value | 描述 | | ----------------- | ----- | -------------------------------------------- | | `hidden_dim` | 64 | LSTM hidden state 维度 | | `dense_layer_dim` | 32 | 输出前的全连接层维度 | | `n_layers` | 2 | LSTM 层堆叠数量 | | `bidirectional` | True | 从两个方向处理序列 | | `dropout` | 0.5 | 用于正则化的 dropout 率 | ### Transformer 配置 | Parameter | Value | 描述 | | ------------ | ----- | -------------------------------- | | `num_heads` | 2 | attention heads 数量 | | `num_layers` | 1 | transformer encoder 层数 | | `ff_dim` | 128 | feed-forward network 维度 | | `dropout` | 0.4 | 用于正则化的 dropout 率 | ## 导入与实用工具 Notebook 导入以下主要库: - **pandas/numpy**:数据操作和数值计算。 - **torch**:PyTorch 深度学习框架。 - **sklearn**:训练/测试集划分和评估指标。 - **transformers**:BERT 配置工具(用作 transformer 架构参考)。 - **wandb**:用于实验跟踪的 Weights and Biases。 - **collections.Counter**:用于构建词汇表的 token 频率计数。 ### 确定性行为 Notebook 强制执行确定性行为(在 HNM 中不完整)以确保可复现性: 1. 设置环境变量 `CUBLAS_WORKSPACE_CONFIG`。 2. 在 PyTorch 中启用确定性算法。 3. 为 Python、NumPy 和 PyTorch(CPU 和 CUDA)设置种子。 4. 禁用 cuDNN benchmark 模式并启用确定性模式。 ### 工具函数 **seed_worker(worker_id)**:确保 DataLoader worker 使用确定性种子。 **clear_memory()**:通过调用垃圾回收和清空 CUDA 缓存来释放 GPU 和 CPU 内存。 ## 数据加载 ### 数据集格式 数据集从 CSV 文件加载,预期包含以下列: - `text`:事件 process tree 的分词表示,作为空格分隔的字符串。 - `event_times`:每个事件的时间戳列表(存储为 Python 列表的字符串表示)。 - `label`:二分类标签(0 = benign,1 = malicious)。 ### 时间转换 `convert_times()` 函数解析 `event_times` 列: 1. 如果值是字符串,函数尝试使用 `ast.literal_eval` 解析它。 2. 如果清理失败,函数返回空列表。 3. 如果成功,函数将所有值转换为 float。 ### 训练/验证/测试集划分 数据使用分层抽样进行划分以保持类别比例: 1. 第一次划分:70% 训练,30% 临时(验证 + 测试)。 2. 第二次划分:这 30% 被平均分为 15% 验证和 15% 测试。 结果为: - 训练:4.232 个样本 - 验证:907 个样本 - 测试:907 个样本 ## 词汇表与 Tokenization ### 构建词汇表 `build_vocab()` 函数创建 word-to-index 映射: 1. 将所有训练文本连接成一个字符串。 2. 按空格分割并使用 `Counter` 计算词频。 3. 按频率降序排列单词。 4. 创建词汇表字典,将单词映射到从 2 开始的索引。 5. 保留索引 0 用于 ``(填充 token),索引 1 用于 ``(未知 token)。
6. 如果尚不存在,则添加 `[SEP]`(分隔符 token)。
7. 将词汇表保存到 JSON 文件。
词汇表限制为 `vocab_size`(15.000 个 token)以管理内存和模型复杂度。
### Tokenization
`tokenize()` 函数将文本序列转换为整数序列:
1. 按 [SEP] 分割每个文本。
2. 在词汇表中查找每个单词。
3. 未知单词映射到索引 1 (``)。
结果是列表的列表,其中每个内部列表包含整数 token ID。
## 辅助函数
### 序列切片
**slice_by_event_count(df, tokens, event_limit, sep_id)**:
- 根据事件数量限制序列。
- 计算 `[SEP]` token(标记事件边界)。
- 在指定事件数量后截断序列。
**slice_by_time_window(df, tokens, time_limit, sep_id)**:
- 根据之前的时间限制序列。
- 计算在该时间窗口内发生了多少事件。
- 通过 `[SEP]` 截断序列,仅包含这些事件。
### Chunking
**这种 chunking 策略将序列分成更小的块,其大小因长序列而异。**
**(仅为实验进行,以加快运行时间)** **smart_chunk_tokens(tokens, sep_id, min_chunk, max_chunk)**: - 从长序列创建大小可变的块。 - 对于短序列(小于或等于 max_chunk),按原样在单个块中返回序列。 - 对于长序列,当块达到最小大小时在分隔符 token 处切割。 - 当当前块达到最大大小时强制创建新块。 ### Padding **pad_chunked_processes(chunked_data, max_chunks, chunk_len)**: - 创建形状为 (num_samples, max_chunks, chunk_len) 的 3D NumPy 数组。 - 用零初始化。 - 为每个样本和块填充实际 token 值。 - 使用 int16 数据类型以减少内存使用。 ## 共享组件 ### Focal Loss `FocalLoss` 类实现 focal loss 以处理类别不平衡: **公式**:FL(p*t) = -alpha * (1 - p*t)^gamma * log(p_t) 其中: - `alpha` (0.25):类别权重的平衡因子。 - `gamma` (2.0):聚焦参数,减少简单样本的权重。 Focal loss 减少了容易分类样本的贡献,迫使模型关注困难样本(通常是少数类)。 ### Multiple Instance Learning 数据集 `MILDataset` 类为 PyTorch 包装特征和标签: - 将 NumPy 数组转换为 PyTorch tensor。 - 特征存储为 int16,并在访问时转换为 long tensor。 - 标签存储为 float32 以兼容 binary cross-entropy。 ### 自定义 Collate Function `collate_fn()` 函数处理具有可变长度的序列批处理: 1. 计算实际序列长度(非填充 token)。 2. 删除现有填充并重新填充到当前批次中的最大长度(而非全局最大值)。 3. 返回填充序列、标签及其长度。 这种动态填充通过不将短批次填充到全局最大长度来提高效率。 ## 模型架构 ### SysmonLSTM 用于序列分类的双向 LSTM 网络。 **架构**: 1. **Embedding Layer**:将 token ID 映射到维度为 `embedding_dim` (32) 的稠密向量。填充 token(ID 0)映射到零向量。 2. **LSTM Layer**:双向 LSTM,具有: - 2 个堆叠层 - hidden 维度 64 - 层间 50% dropout - 使用 packed sequences 忽略填充 token 3. **Fully Connected Layer**:将最终 hidden state(双向为 128 维)映射到 32 维,具有 ReLU 激活。 4. **Output Layer**:映射到单个 logit 用于二分类。 **Forward Pass**: 1. Embedding 输入 token。 2. 使用实际长度打包序列(从计算中排除填充)。 . 通过 LSTM 处理。 4. 拼接前向和后向最终 hidden states。 5. 通过全连接层。 6. 返回 logit(sigmoid 前的分数)。 ### SysmonTransformer 用于序列分类的 Transformer encoder。 **架构**: 1. **Embedding Layer**:将 token ID 映射到维度为 `embedding_dim` (32) 的稠密向量。 2. **Positional Encoding**:可学习的位置 embeddings 添加到 token embeddings。 3. **Transformer Encoder**:标准 transformer encoder,具有: - 2 个 attention heads - 1 个 encoder 层 - feed-forward 维度 128 - 40% dropout 4. **Output Layer**:将池化后的表示映射到单个 logit。 **Forward Pass**: 1. Embedding 输入 token 并添加位置编码。 2. 创建填充掩码,其中值 True 表示填充 token。 3. 通过 transformer encoder 处理(attention 忽略填充)。 4. 在非填充位置应用平均池化。 5. 对池化后的表示应用 dropout。 6. 返回 logit(sigmoid 前的分数)。 ## 训练函数 `train_model()` 函数实现了完整的训练循环。 ### 初始化 - 使用 alpha 和 gamma 配置创建 Focal Loss 标准。 - 使用带有学习率衰减 (weight_decay) 的 AdamW optimizer。 - 初始化最佳 F1 分数和 patience 计数器。 ### Hard Negative Mining (HNM) 从 epoch 5 开始,之后每 5 个 epoch: 1. **检查数据集大小**:如果数据集已达到最大大小(12.000 个样本)则跳过。 2. **确定挖掘目标**: - 如果 recall 明显超过 precision:挖掘 false positives (FP)。 - 如果 precision 明显超过 recall:挖掘 false negatives (FN)。 3. **挖掘过程**: - 在整个训练集上运行推理。 - 根据挖掘目标识别错误分类的样本。 - 将困难样本(每轮最多 1.000 个)添加到训练数据集。 - 使用增强后的数据集重新创建 DataLoader。 ### 训练循环 对于每个 epoch: 1. **训练阶段**: - 将模型设置为训练模式。 - 遍历批次。 - 通过模型进行 forward pass。 - 计算 focal loss。 - 反向传播梯度。 - 应用梯度裁剪(最大范数 = 1.0)。 - 更新权重。 2. **验证阶段**: - 将模型设置为评估模式。 - 禁用梯度计算。 - 收集预测、目标和概率分数。 - 计算指标:precision、recall、F1 score、AUC 和混淆矩阵。 3. **日志记录**: - 将所有指标记录到 Weights and Biases。 4. **模型检查点**: - 如果 F1 超过最小增量则保存模型并重置 patience。 - 否则,增加 patience 计数器。 5. **Early Stopping**: - 如果 patience 达到配置限制(10 个 epoch)则停止训练。 6. **内存管理**: - 每 5 个 epoch 清理内存。 ### 最后步骤 - 加载最佳模型检查点。 - 返回模型和最佳 F1 分数。 ## 实验执行 主实验循环处理每个配置的实验: ### 准备 1. 确定实验类型(基于事件或时间)。 2. 选择适当的切片函数。 3. 使用最大限制切片训练和验证数据。 4. 过滤空序列。 ### 类别平衡 1. 识别多数和少数类的索引。 2. 对少数类进行过采样以匹配多数类大小。 3. 打乱 已平衡的索引。 ### 数据准备 1. 对所有序列应用智能 chunking。 2. 填充 chunking 后的数据以具有统一的形状。 3. 创建 PyTorch 数据集和数据加载器。 ### 模型初始化 基于模型类型: - LSTM:使用特定 LSTM 配置创建 SysmonLSTM。 - Transformer:使用特定 transformer 配置创建 SysmonTransformer。 ### 训练或加载 - 如果 `LOAD_IF_EXISTS` 为 True 且存在已保存的模型,则加载该模型。 - 否则,初始化 Weights and Biases 跟踪并训练模型。 ### 多限制测试 训练后,在多个观察限制 上评估模型: 对于配置范围内的每个限制: 1. 将测试数据切片到指定限制。 2. 过滤空序列。 3. 对测试数据进行 chunking 和 padding。 4. 运行推理并收集预测。 5. 计算测试指标。 6. 将结果记录到 Weights and Biases。 7. 清理内存。 ## 测试与评估 ### 计算的指标 - **Precision**:TP / (TP + FP) - 阳性预测的准确性。 - **Recall**:TP / (TP + FN) - 实际阳性的覆盖率。 - **F1 Score**:precision 和 recall 的调和平均值。 - **AUC**:ROC 曲线下面积。 - **Confusion Matrix**:True positives、true negatives、false positives、false negatives。 ### 早期检测分析 通过在多个事件/时间限制下测试,Notebook 允许分析: 1. **检测速度**:多快能检测到恶意软件? 2. **准确性与速度的权衡**:观察次数减少时准确性如何下降? 3. **所需最小信息**:可靠检测所需的最小事件/时间数量是多少? ### 输出 最终输出包括: - 每个实验在训练期间达到的最佳 F1 分数。 - 在每个观察限制下记录到 Weights and Biases 的测试指标。 ## 总结 该 Notebook 提供了完整的 Pipeline 用于: 1. 加载和预处理 Sysmon 事件日志数据。 2. 构建词汇表并对序列进行 tokenization。 3. 训练 LSTM 和 Transformer 模型,具有: - 用于处理类别不平衡的 Focal loss。 - 用于动态数据集增强的 Hard negative mining。 - 用于正则化的 Early stopping。 4. 在各种观察限制下评估早期检测能力。 5. 使用 Weights and Biases 跟踪所有实验。 模块化设计允许轻松实验各种模型架构、超参数和评估策略。
或者
将 `LOAD_IF_EXISTS` 设置为 True(将创建文件) **将训练具有最长进程限制的模型** - **Testing**: 将 `LOAD_IF_EXISTS` 设置为 True **将测试具有设定进程限制的模型** - **Run ALL** ## 配置 ### 文件路径 Notebook 定义了几个用于输入数据、模型存储和输出的路径: - `DATASET_PATH`:预处理后的 CSV 数据集路径 - `MODEL_SAVE_DIR`:模型所在目录 - `VOCAB_SAVE_PATH`:用于保存/加载词汇表映射的路径 - `FALSE_PREDS_OUTPUT`:错误预测事件的路径 ### 数据集约束 - `MAX_TRAIN_EVENTS`:用于基于事件实验的训练的最大事件数 (673) - `MAX_TRAIN_TIME`:用于基于时间实验的训练的最大时间窗口 (20113 个时间单位) ### 测试限制 Notebook 在各种限制下测试模型性能以进行早期恶意软件检测: - `EVENT_LIMITS_TO_TEST`:事件数量限制列表,从 1 到 673 个事件 - `TIME_LIMITS_TO_TEST`:时间阈值列表,从 1 到 20113 秒时间单位 ### 可复现性 - `SEED`:设置为 42 以确保所有随机操作的可复现性(仍为非确定性) - `LOAD_IF_EXISTS`:布尔标志,如果已存在保存的模型则跳过训练 ### 实验配置 `EXPERIMENTS` 列表定义了要运行的模型类型组合。每个条目指定: - `model`:"LSTM" 或 "Transformer" - `type`:"event" 或 "time" ### 共享配置 `SHARED_CONFIG` 字典包含所有模型的超参数: | Parameter | Value | 描述 | | ----------------------------- | ----- | ---------------------------------------------------------------------------- | | `vocab_size` | 15000 | 词汇表中唯一 token 的最大数量 | | `max_chunk_length` | 10000 | 每个序列块的最大 token 长度 | | `max_chunks` | 1 | 每个 process tree 的最大块数 | | `batch_size` | 8 | 每次梯度更新的序列数量 | | `num_epochs` | 50 | 最大训练 epoch 数量 | | `learning_rate` | 1e-3 | AdamW optimizer 的学习率 | | `weight_decay` | 1e-4 | L2 正则化强度 | | `early_stopping_patience` | 10 | 如果 F1-Score 没有提升,等待停止的 epoch 数量 | | `early_stopping_min_delta` | 0.001 | 重置 patience 所需的最小 F1 提升 | | `focal_alpha` | 0.25 | Focal Loss 的 Alpha 参数 | | `focal_gamma` | 2.0 | Focal Loss 的 Gamma 参数 | | `embedding_dim` | 32 | token embedding 的维度 | | `hnm_start_epoch` | 5 | 开始 Hard Negative Mining 的 epoch | | `hnm_interval` | 5 | Hard Negative Mining 轮次之间的 epoch 间隔 | | `hnm_threshold` | 0.15 | 触发挖掘的精确率-召回率差异阈值 | | `hnm_max_dataset_size` | 12000 | 增强后的最大数据集大小 | | `hnm_max_additions_per_round` | 1000 | 每轮 HNM 增加的最大样本数 | ### LSTM 配置 | Parameter | Value | 描述 | | ----------------- | ----- | -------------------------------------------- | | `hidden_dim` | 64 | LSTM hidden state 维度 | | `dense_layer_dim` | 32 | 输出前的全连接层维度 | | `n_layers` | 2 | LSTM 层堆叠数量 | | `bidirectional` | True | 从两个方向处理序列 | | `dropout` | 0.5 | 用于正则化的 dropout 率 | ### Transformer 配置 | Parameter | Value | 描述 | | ------------ | ----- | -------------------------------- | | `num_heads` | 2 | attention heads 数量 | | `num_layers` | 1 | transformer encoder 层数 | | `ff_dim` | 128 | feed-forward network 维度 | | `dropout` | 0.4 | 用于正则化的 dropout 率 | ## 导入与实用工具 Notebook 导入以下主要库: - **pandas/numpy**:数据操作和数值计算。 - **torch**:PyTorch 深度学习框架。 - **sklearn**:训练/测试集划分和评估指标。 - **transformers**:BERT 配置工具(用作 transformer 架构参考)。 - **wandb**:用于实验跟踪的 Weights and Biases。 - **collections.Counter**:用于构建词汇表的 token 频率计数。 ### 确定性行为 Notebook 强制执行确定性行为(在 HNM 中不完整)以确保可复现性: 1. 设置环境变量 `CUBLAS_WORKSPACE_CONFIG`。 2. 在 PyTorch 中启用确定性算法。 3. 为 Python、NumPy 和 PyTorch(CPU 和 CUDA)设置种子。 4. 禁用 cuDNN benchmark 模式并启用确定性模式。 ### 工具函数 **seed_worker(worker_id)**:确保 DataLoader worker 使用确定性种子。 **clear_memory()**:通过调用垃圾回收和清空 CUDA 缓存来释放 GPU 和 CPU 内存。 ## 数据加载 ### 数据集格式 数据集从 CSV 文件加载,预期包含以下列: - `text`:事件 process tree 的分词表示,作为空格分隔的字符串。 - `event_times`:每个事件的时间戳列表(存储为 Python 列表的字符串表示)。 - `label`:二分类标签(0 = benign,1 = malicious)。 ### 时间转换 `convert_times()` 函数解析 `event_times` 列: 1. 如果值是字符串,函数尝试使用 `ast.literal_eval` 解析它。 2. 如果清理失败,函数返回空列表。 3. 如果成功,函数将所有值转换为 float。 ### 训练/验证/测试集划分 数据使用分层抽样进行划分以保持类别比例: 1. 第一次划分:70% 训练,30% 临时(验证 + 测试)。 2. 第二次划分:这 30% 被平均分为 15% 验证和 15% 测试。 结果为: - 训练:4.232 个样本 - 验证:907 个样本 - 测试:907 个样本 ## 词汇表与 Tokenization ### 构建词汇表 `build_vocab()` 函数创建 word-to-index 映射: 1. 将所有训练文本连接成一个字符串。 2. 按空格分割并使用 `Counter` 计算词频。 3. 按频率降序排列单词。 4. 创建词汇表字典,将单词映射到从 2 开始的索引。 5. 保留索引 0 用于 `
**(仅为实验进行,以加快运行时间)** **smart_chunk_tokens(tokens, sep_id, min_chunk, max_chunk)**: - 从长序列创建大小可变的块。 - 对于短序列(小于或等于 max_chunk),按原样在单个块中返回序列。 - 对于长序列,当块达到最小大小时在分隔符 token 处切割。 - 当当前块达到最大大小时强制创建新块。 ### Padding **pad_chunked_processes(chunked_data, max_chunks, chunk_len)**: - 创建形状为 (num_samples, max_chunks, chunk_len) 的 3D NumPy 数组。 - 用零初始化。 - 为每个样本和块填充实际 token 值。 - 使用 int16 数据类型以减少内存使用。 ## 共享组件 ### Focal Loss `FocalLoss` 类实现 focal loss 以处理类别不平衡: **公式**:FL(p*t) = -alpha * (1 - p*t)^gamma * log(p_t) 其中: - `alpha` (0.25):类别权重的平衡因子。 - `gamma` (2.0):聚焦参数,减少简单样本的权重。 Focal loss 减少了容易分类样本的贡献,迫使模型关注困难样本(通常是少数类)。 ### Multiple Instance Learning 数据集 `MILDataset` 类为 PyTorch 包装特征和标签: - 将 NumPy 数组转换为 PyTorch tensor。 - 特征存储为 int16,并在访问时转换为 long tensor。 - 标签存储为 float32 以兼容 binary cross-entropy。 ### 自定义 Collate Function `collate_fn()` 函数处理具有可变长度的序列批处理: 1. 计算实际序列长度(非填充 token)。 2. 删除现有填充并重新填充到当前批次中的最大长度(而非全局最大值)。 3. 返回填充序列、标签及其长度。 这种动态填充通过不将短批次填充到全局最大长度来提高效率。 ## 模型架构 ### SysmonLSTM 用于序列分类的双向 LSTM 网络。 **架构**: 1. **Embedding Layer**:将 token ID 映射到维度为 `embedding_dim` (32) 的稠密向量。填充 token(ID 0)映射到零向量。 2. **LSTM Layer**:双向 LSTM,具有: - 2 个堆叠层 - hidden 维度 64 - 层间 50% dropout - 使用 packed sequences 忽略填充 token 3. **Fully Connected Layer**:将最终 hidden state(双向为 128 维)映射到 32 维,具有 ReLU 激活。 4. **Output Layer**:映射到单个 logit 用于二分类。 **Forward Pass**: 1. Embedding 输入 token。 2. 使用实际长度打包序列(从计算中排除填充)。 . 通过 LSTM 处理。 4. 拼接前向和后向最终 hidden states。 5. 通过全连接层。 6. 返回 logit(sigmoid 前的分数)。 ### SysmonTransformer 用于序列分类的 Transformer encoder。 **架构**: 1. **Embedding Layer**:将 token ID 映射到维度为 `embedding_dim` (32) 的稠密向量。 2. **Positional Encoding**:可学习的位置 embeddings 添加到 token embeddings。 3. **Transformer Encoder**:标准 transformer encoder,具有: - 2 个 attention heads - 1 个 encoder 层 - feed-forward 维度 128 - 40% dropout 4. **Output Layer**:将池化后的表示映射到单个 logit。 **Forward Pass**: 1. Embedding 输入 token 并添加位置编码。 2. 创建填充掩码,其中值 True 表示填充 token。 3. 通过 transformer encoder 处理(attention 忽略填充)。 4. 在非填充位置应用平均池化。 5. 对池化后的表示应用 dropout。 6. 返回 logit(sigmoid 前的分数)。 ## 训练函数 `train_model()` 函数实现了完整的训练循环。 ### 初始化 - 使用 alpha 和 gamma 配置创建 Focal Loss 标准。 - 使用带有学习率衰减 (weight_decay) 的 AdamW optimizer。 - 初始化最佳 F1 分数和 patience 计数器。 ### Hard Negative Mining (HNM) 从 epoch 5 开始,之后每 5 个 epoch: 1. **检查数据集大小**:如果数据集已达到最大大小(12.000 个样本)则跳过。 2. **确定挖掘目标**: - 如果 recall 明显超过 precision:挖掘 false positives (FP)。 - 如果 precision 明显超过 recall:挖掘 false negatives (FN)。 3. **挖掘过程**: - 在整个训练集上运行推理。 - 根据挖掘目标识别错误分类的样本。 - 将困难样本(每轮最多 1.000 个)添加到训练数据集。 - 使用增强后的数据集重新创建 DataLoader。 ### 训练循环 对于每个 epoch: 1. **训练阶段**: - 将模型设置为训练模式。 - 遍历批次。 - 通过模型进行 forward pass。 - 计算 focal loss。 - 反向传播梯度。 - 应用梯度裁剪(最大范数 = 1.0)。 - 更新权重。 2. **验证阶段**: - 将模型设置为评估模式。 - 禁用梯度计算。 - 收集预测、目标和概率分数。 - 计算指标:precision、recall、F1 score、AUC 和混淆矩阵。 3. **日志记录**: - 将所有指标记录到 Weights and Biases。 4. **模型检查点**: - 如果 F1 超过最小增量则保存模型并重置 patience。 - 否则,增加 patience 计数器。 5. **Early Stopping**: - 如果 patience 达到配置限制(10 个 epoch)则停止训练。 6. **内存管理**: - 每 5 个 epoch 清理内存。 ### 最后步骤 - 加载最佳模型检查点。 - 返回模型和最佳 F1 分数。 ## 实验执行 主实验循环处理每个配置的实验: ### 准备 1. 确定实验类型(基于事件或时间)。 2. 选择适当的切片函数。 3. 使用最大限制切片训练和验证数据。 4. 过滤空序列。 ### 类别平衡 1. 识别多数和少数类的索引。 2. 对少数类进行过采样以匹配多数类大小。 3. 打乱 已平衡的索引。 ### 数据准备 1. 对所有序列应用智能 chunking。 2. 填充 chunking 后的数据以具有统一的形状。 3. 创建 PyTorch 数据集和数据加载器。 ### 模型初始化 基于模型类型: - LSTM:使用特定 LSTM 配置创建 SysmonLSTM。 - Transformer:使用特定 transformer 配置创建 SysmonTransformer。 ### 训练或加载 - 如果 `LOAD_IF_EXISTS` 为 True 且存在已保存的模型,则加载该模型。 - 否则,初始化 Weights and Biases 跟踪并训练模型。 ### 多限制测试 训练后,在多个观察限制 上评估模型: 对于配置范围内的每个限制: 1. 将测试数据切片到指定限制。 2. 过滤空序列。 3. 对测试数据进行 chunking 和 padding。 4. 运行推理并收集预测。 5. 计算测试指标。 6. 将结果记录到 Weights and Biases。 7. 清理内存。 ## 测试与评估 ### 计算的指标 - **Precision**:TP / (TP + FP) - 阳性预测的准确性。 - **Recall**:TP / (TP + FN) - 实际阳性的覆盖率。 - **F1 Score**:precision 和 recall 的调和平均值。 - **AUC**:ROC 曲线下面积。 - **Confusion Matrix**:True positives、true negatives、false positives、false negatives。 ### 早期检测分析 通过在多个事件/时间限制下测试,Notebook 允许分析: 1. **检测速度**:多快能检测到恶意软件? 2. **准确性与速度的权衡**:观察次数减少时准确性如何下降? 3. **所需最小信息**:可靠检测所需的最小事件/时间数量是多少? ### 输出 最终输出包括: - 每个实验在训练期间达到的最佳 F1 分数。 - 在每个观察限制下记录到 Weights and Biases 的测试指标。 ## 总结 该 Notebook 提供了完整的 Pipeline 用于: 1. 加载和预处理 Sysmon 事件日志数据。 2. 构建词汇表并对序列进行 tokenization。 3. 训练 LSTM 和 Transformer 模型,具有: - 用于处理类别不平衡的 Focal loss。 - 用于动态数据集增强的 Hard negative mining。 - 用于正则化的 Early stopping。 4. 在各种观察限制下评估早期检测能力。 5. 使用 Weights and Biases 跟踪所有实验。 模块化设计允许轻松实验各种模型架构、超参数和评估策略。
标签:AMSI绕过, Apex, LSTM, Python, Sysmon, Sysmon日志, TA毕业设计, Transformer, 事件序列分析, 凭据扫描, 双向LSTM, 威胁检测, 安全教育, 无后门, 早期预警, 机器学习, 注意力机制, 深度学习, 端点安全, 自定义DNS解析器, 补丁管理, 进程树, 逆向工具