Skip to content

Commit

Permalink
[+] 总结报告
Browse files Browse the repository at this point in the history
  • Loading branch information
404notf0und committed Apr 11, 2020
1 parent e842edf commit f53a0f8
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions 我对安全与NLP的思考和实践.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@

其次是关于预训练前字典的建立。特征化类word2vec的预训练需求直接引发了字典建立的相关问题。在word2vec预训练前,需要考虑预训练数据的产生。基于深度学习的XSS检测文中,是通过建立一个基于黑样本数据的指定大小的字典,不在字典内的数据全部泛化为一个特定词,将泛化后的数据作为预训练的数据。这里我们将此思路扩充,增加使用全量数据建立任意大小的字典。具体到word2vec类中,参数one_class的True or False决定了预训练的数据来源是单类黑样本还是全量黑白样本,参数vocabulary_size的值决定了字典大小,如果为None,就不截断,为全量字典数据。下文的实验部分会测试是单类黑样本预训练word2vec好,还是全量数据预训练更占优势,是字典截断好,还是用全量字典来预训练好。

然后是关于序列的问题,具体地说,是长文本数据特征化需求,引发了序列截断和填充的问题。短文本数据的特征化,可以保留所有原始信息。而在某些安全场景中的长文本数据,特征化比较棘手,保留全部原始信息不太现实,需要对其进行截断,截断的方式主要有字典截断、序列软截断、序列硬截断。字典截断已经在上段说过了,序列软截断是指对不在某个范围内(参数num_words控制范围大小)的数据,直接去除或填充为某值,长文本选择直接去除,缩短整体序列的长度,尽可能保留后续更多的原始信息。如果长本文数据非常非常长,那么就算有字典截断和序列软截断,截断后的序列也可能非常长,超出了模型和算力的承受范围,此时,序列硬截断(参数max_length控制)可以发挥实际作用,直接整整齐齐截断和填充序列,保留指定长度的序列数据。这里需要注意的是,为了兼容后文将说到的“预训练+微调”训练模式中的**预训练矩阵**,序列填充值默认为0
然后是关于序列的问题,具体地说,是长文本数据特征化需求,如下图中的webshell检测等安全场景,引发了序列截断和填充的问题

![image-20200410225942891](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200410225942891.png)

短文本数据的特征化,可以保留所有原始信息。而在某些安全场景中的长文本数据,特征化比较棘手,保留全部原始信息不太现实,需要对其进行截断,截断的方式主要有字典截断、序列软截断、序列硬截断。字典截断已经在上段说过了,序列软截断是指对不在某个范围内(参数num_words控制范围大小)的数据,直接去除或填充为某值,长文本选择直接去除,缩短整体序列的长度,尽可能保留后续更多的原始信息。如果长本文数据非常非常长,那么就算有字典截断和序列软截断,截断后的序列也可能非常长,超出了模型和算力的承受范围,此时,序列硬截断(参数max_length控制)可以发挥实际作用,直接整整齐齐截断和填充序列,保留指定长度的序列数据。这里需要注意的是,为了兼容后文将说到的“预训练+微调”训练模式中的**预训练矩阵**,序列填充值默认为0。

最后,是词向量的问题,具体说,是词嵌入向量问题。词嵌入向量的产生有三种方式:词序列索引+有嵌入层的深度学习模型、word2vec预训练产生词嵌入向量+无嵌入层的深度学习模型、word2vec预训练产生预训练矩阵+初始化参数为预训练矩阵的嵌入层的深度学习模型。这里我把这三种方式简单叫做微调、预训练、预训练+微调,从特征工程角度,这三种方式是产生词嵌入向量的方法,从模型角度,也可以看作是模型训练的三种方法。第一种微调的方式实现起来比较简单,直接使用keras的文本处理类Tokenizer就可以分词,转换为词序列,得到词序列索引,输入到深度学习模型中即可。第二种预训练的方式,调个gensim库中word2vec类预训练,对于不在预训练字典中的数据,其词嵌入向量直接填充为0,第三种预训练+微调的方式,稍微复杂一点,简单来说就是前两种方式的组合,用第二种方式得到预训练矩阵,作为嵌入层的初始化权重矩阵参数,用第一种方式得到词序列索引,作为嵌入层的原始输入。下文的实验部分会测试并对比按这三种方式训练模型的性能,先说结论:预训练+微调>预训练>微调。

## 非预期问题
Expand Down Expand Up @@ -118,7 +120,7 @@ embedding_size:词嵌入向量的维度。

## 测试

使用其中part1A_url.csv和part1B_url.csv数据集,测试轮子鲁棒性的同时,给出系列参数设置及对应的结果,限于篇幅,详细测试报告在
使用其中part1A_url.csv和part1B_url.csv数据集,测试轮子鲁棒性的同时,给出系列参数设置及对应的结果,限于篇幅,详细测试报告在FXY仓库[docs](https://github.com/404notf0und/FXY/blob/master/docs/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B.md)文件夹中。

## 测试结果分析

Expand All @@ -127,4 +129,6 @@ embedding_size:词嵌入向量的维度。

- [x] 预训练的数据不是越多越好,字典也不是越大越好,随着数据量的增大,性能有上限,该截断就截断。
- [x] 训练模式效果对比一般有:预训练+微调>预训练>微调。
- [x] 无论是同源数据还是异源数据,只有其攻击模式类似,模型效果就可以泛化到。
- [x] 无论是同源数据还是异源数据,只有其攻击模式类似,模型效果就可以泛化到。

这篇文章是对我部分工作的一个总结,把零零散散的单点串成线,站在一个更高的视角看待问题。真相在第五层,我以为我看到了第二层,但我可能还在第一层,我们能做的是,唯有不断思考。

0 comments on commit f53a0f8

Please sign in to comment.