This project proposes a deep reinforcement learning framework grounded in sequential decision-making, leveraging DQN and D3QN models for training and inference on one-dimensional time-series data.
Experiments on a simulated pipeline leak dataset show that the framework achieves strong classification performance in low-data scenarios and is readily extendable to other anomaly detection applications.
本项目提出了一种基于序贯决策的深度强化学习框架,并在此框架上使用DQN模型、D3QN模型于一维时序数据上完成训练、推理。
经过本人在学校提供的模拟实验中获取的管道泄漏数据集上进行的实验,
可以证明该框架在小样本条件下有较强的分类性能,并可推广应用于其他异常检测任务。
- 深度强化学习通用框架如图所示:
- 下图是本项目实验时使用的DQN的网络模型:
- 下图是本项目实验时使用的D3QN的网络结构,在DQN基础上对最后的价值流进行了解耦:
- 本项目的分类诊断流程所下图所示:
具体的实验细节可以读项目结构和代码。
- 首先需要配置一个虚拟环境(推荐在虚拟环境里部署项目),python版本为3.9。
- 接下来,需要把本项目的代码zip下载下来,解压到你指定的工作文件夹中。
- 使用终端Terminal或者命令提示符,进入提取创好的虚拟环境中,如果你使用的是anaconda,则对应的命令是:
- cd 你的工作文件夹的绝对路径(如果有特殊符号需要使用引号把路径括起来)
- conda activate 你的虚拟环境名字
- 最后输入命令:pip install requirements.txt
- 等待虚拟环境安装好依赖库即可使用本项目的模型进行训练、测试。
- 在开始具体的使用介绍之前,我先对一些说法做定义。DQN模型和D3QN模型在代码结构上存在平行关系,都是由五个文件构成,依次是:网络结构、环境、经验池、训练代码、测试代码。
- 首先需要修改的是env.py文件(环境),环境中可以修改默认的窗口大小(状态长度)、滑动步长、数据集文件类型。但是最为重要的是代码顶部的LABEL_MAP,需要根据你的数据集的标签类型调整此字典。再这之后需要修改step中的奖励函数,这里基于你刚刚调整好的映射关系修改就行。
- 训练代码(train)中需要基于你刚刚调整的env中定义的分类动作数量修改ACTION_DIM。另外,可以通过模型初始化的第一部分中对env的初始化传入参数调整以修改你的数据集的读取路径。
- 测试代码(test)中同样需要修改ACTION_DIM。DATA_ROOT用于调整测试使用的数据集路径、MODEL_PATH可以调整要读取的模型文件的路径。
- 本项目未把所有路径都集合在代码文件的一个区域,但是主要集中在初始化(包括日志准备区域)和存在输出的地方。具体的可以自己查看代码、和本README的介绍内容。
- 状态设计:本项目设计的状态是一维时序浮点型数据,由时间窗口WINDOW_SIZE、提取步长step_size这两个参数控制生成。时间窗口由默认和传入两种形式,传入时需要找到PipelineEnv初始化的代码行进行修改。这两个参数都可以在env.py环境文件中找到,修改默认值。
- 动作设计:本项目的动作就是分类,因此在数据集适配就已经完成了设计。如果还是需要修改,比如把分类动作变成报警动作,并且停止检测,需要在env.py完成数据集适配,其中step方法需要大改,此时动作会影响此局游戏下一回合的状态。之后修改训练代码和测试代码中的ACTION_DIM。
- 奖励设计:本项目采用差异化奖励设计,只需要调整env.py的step方法即可修改对应的奖励函数。
- 如果你对本项目使用的DQN、D3QN网络结构对最优价值函数的拟合效果不满意,可以改变网络结构(dqn.py、Dueling_dqn.py)的代码更替或优化网络取得自己想要的效果,但是替换时请根据项目结构保持不同代码文件间的对应关系。
├─ dqn.py ------------- # Defines the DQN network structure
├─ env.py ------------- # RL environment for pipeline data
├─ replay_buffer.py -- # Experience replay buffer
├─ DQN_train.py ----- # Training script for DQN
├─ test_dqn.py ------- # Testing script for DQN
-
本文件定义了DQN模型中使用到的网络结构。
-
强化学习中的环境(Environment):
-
LABEL_MAP定义数据标签和数值编码的映射关系。
-
本项目实验时使用的环境PipelineEnv:
- 初始化时可以输入时间窗口以控制状态的长度。在本模型的框架中,状态是时序数据中连续的一段离散点值。
- 类别中的初始化部分,可以自定义时间窗口滑动的步长,如果需要更改则需要在此处调整step_size的数值。
- 本环境仅对xlsx文件进行了数据读取的兼容,如果需要使用其他格式,请修改_load_files。
- step方法完成对奖励函数的定义,本项目在实验时采用了差异化的奖励函数以权衡预测错误的不同代价。可以自适应调整此部分,以实现自己想要的训练效果。
-
-
- 初始化时可以输入所希望的经验池容量,超过容量时自动删除最老的经验。
- 从push的输入可以窥见一条经验具体是什么,done定义了“游戏”是否结束,当done为0时,说明游戏未结束。
- sample用来采样,可以输入需要的经验数量,即批大小(batch_size),len方法可以输出此时经验池有多少经验。
-
-
evaluate_policy方法使用测试集对每回合训练完的模型进行一个评估,从而绘制评估曲线。
- 需要输入环境、模型和device,device用于适配cpu或者gpu,通过修改输入的环境可以更改测试的数据集。
- 输出是数据集上的平均return,表示平均一个样本(一局游戏)获得的总rewards,本项目命名为eval reward。
-
超参数的设置:
- WINDOW_SIZE ----------- 时间窗口,样本上读取的状态长度
- ACTION_DIM ------------- 动作空间维度,在此实验中是3,因为只有三个动作,用标量0、1、2表示。
- LR ------------------------- 学习率
- GAMMA ------------------ 折扣因子,用以权衡后续选择的影响
- BATCH_SIZE -------------- 单回合抽取经验的数量
- MEMORY_SIZE ----------- 经验池容量、
- EPISODES ---------------- 运行一次本代码,经历的回合数
- EPSILON_START ---------- 初始探索率
- EPSILON_END ------------ 最低探索率,保证Agent有更加包容、开放的视角
- EPSILON_DECAY --------- 探索率衰减因子,可以使得训练后期趋于“贪婪”,使训练更加稳定
- TARGET_UPDATE_FREQ -- 更新目标网络的频率,单位是回合数
-
具体的训练流程:
- 初始化部分主要由三部分组成:模型初始化(在env的初始化更改使用的数据集路径)、试加载上次训练结果(model_path和代码底部保存模型相互呼应)、准备训练日志。
- 训练阶段优先与环境交互形成经验放入经验池,经验池达到一回合训练所需经验数量则开始训练。一局游戏之后计算eval reward,并写训练日志。
- 训练结束后将训练的模型保存至当前文件夹下的dqn_models文件夹内,如果没有则会自动创建;训练日志最终保存在当前文件下的d3qn_train_log.csv。
-
-
- 初始化时设置了需要的超参数(要与训练时一致)、测试时使用的路径,之后进行模型加载和环境初始化。
- 具体的测试过程比较简单,懂了怎么训练的,看看代码就懂了是如何测试的。
- 测试结束后先输出一段文字报告,之后会保存三个结果文件到初始化定义的结果文件夹中。
- dqn_test_predictions.csv保存了数据集每个样本的预测结果,并且附上真实结果进行对比。
- dqn_classification_report.csv保存的是预测结果的总体报告。
- confusion_matrix_DQN.png如其名保存的是测试结果混淆矩阵。
├─ Dueling_dqn.py ---------------- # Defines the Dueling DQN network structure
├─ env.py -------------------------- # RL environment for pipeline data
├─ priortized_replay_buffer.py ---- # Priortized experience replay buffer
├─ D3QN_train.py ----------------- # Training script for D3QN
├─ test_d3qn.py ------------------- # Testing script for D3QN
-
本文件定义了D3QN模型中使用到的Dueling DQN结构。
-
强化学习中的环境(Environment),与DQN使用相同的环境。
-
-
初始化在原先的经验回放池上新添了alpha参数,用以控制优先采样偏置,偏置强度越高,则越趋向于采样模型认为更值得学习的经验来学习。
-
由于引入了优先级机制,此时的push变得很不一样:
- 首先为了让经验池的拓展性更高,buffer不再使用预先定义的库,而是采用列表的方式定义。后续可以定义经验池的溢出处理方式等。
- 经验中加入label,用于训练时记录TD-error。
- 新放入的优先级基于当前经验池中的最大优先级赋予其优先级,使Agent趋向于学习新鲜事物。
- 本实验经验池的溢出处理方式是覆盖最旧的经验,通过pos属性实现。
-
sample用来采样,这里引入了beta参数,可以控制重要性采样修正的强度,以纠正非均匀采样带来的分布偏差。
-
update_priorities用于动态更改经验池的优先级。
-
-
-
evaluate_policy方法使用测试集对每回合训练完的模型进行一个评估,从而绘制评估曲线,与DQN的一模一样,可以考虑放进一个库里。
-
第一部分超参数与DQN是一样的,第二部分超参数涉及到PER机制,前面也有所提及:
- ALPHA --------------- 优先采样偏置强度
- BETA_START --------- 重要性采样修正的强度
- BETA_INC ------------ 重要性采样修正强度的增长因子,使训练后期偏向于均衡学习
-
具体的训练流程:
- 初始化部分主要由三部分组成:模型初始化(在env的初始化更改使用的数据集路径)、试加载上次训练结果(model_path和代码底部保存模型相互呼应)、准备训练日志。 此外,还有td_error日志的准备工作。
- 相比DQN,一回合结束后需要记录td-error、更新优先级;此处记录的td-errror为训练使用经验的td-error对应类别的平均值,以衡量训练过程中遇到的经验的学习价值。一局游戏后在更新探索率的同时也更新重要性采样修正强度,之后写训练日志。
- 训练结束后将训练的模型保存至当前文件夹下的d3qn_models文件夹内,如果没有则会自动创建,同时保存下列两个文件在当前文件夹下:
- d3qn_train_log.csv,这与DQN类似。
- td_error_log.csv,记录训练过程的td_error。
-
-
-
初始化时设置了需要的超参数(要与训练时一致)、测试时使用的路径,之后进行模型加载和环境初始化。
-
测试报告相比DQN多了置信度confidence_list,除此之外几乎一模一样。
-
测试结束后先输出一段文字报告,之后会保存三个结果文件到初始化定义的结果文件夹中。
- d3qn_test_predictions.csv保存了数据集每个样本的预测结果,并且附上真实结果进行对比。
- d3qn_classification_report.csv保存的是预测结果的总体报告。
- confusion_matrix_D3QN.png如其名保存的是测试结果混淆矩阵。
-
- 本人实验使用的管道泄漏声波数据集是分布平均的。
- td-error在D3QN的训练过程的相关代码拓展性不强,需要根据自己的数据集进行相应的修改,主要是跟类别相关。
- D3QN优化了state的张量表达,所以在一些地方会和DQN有所不同。本项目里DQN只能接受一维数据的输入,若要调整可以参考D3QN的代码。
- 本项目暂未拓展更多的可视化结果,只有混淆矩阵是图的形式,其他的结果要么是模型文件、要么是文字数据。