From f53a0f8cf112dffea69a39c4ff09bd9b16acad7e Mon Sep 17 00:00:00 2001 From: 404notfound <2811832487@qq.com> Date: Sat, 11 Apr 2020 22:02:47 +0800 Subject: [PATCH] =?UTF-8?q?[+]=20=E6=80=BB=E7=BB=93=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...350\200\203\345\222\214\345\256\236\350\267\265.md" | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git "a/\346\210\221\345\257\271\345\256\211\345\205\250\344\270\216NLP\347\232\204\346\200\235\350\200\203\345\222\214\345\256\236\350\267\265.md" "b/\346\210\221\345\257\271\345\256\211\345\205\250\344\270\216NLP\347\232\204\346\200\235\350\200\203\345\222\214\345\256\236\350\267\265.md" index 9c600b0..eb1d3a8 100644 --- "a/\346\210\221\345\257\271\345\256\211\345\205\250\344\270\216NLP\347\232\204\346\200\235\350\200\203\345\222\214\345\256\236\350\267\265.md" +++ "b/\346\210\221\345\257\271\345\256\211\345\205\250\344\270\216NLP\347\232\204\346\200\235\350\200\203\345\222\214\345\256\236\350\267\265.md" @@ -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,第三种预训练+微调的方式,稍微复杂一点,简单来说就是前两种方式的组合,用第二种方式得到预训练矩阵,作为嵌入层的初始化权重矩阵参数,用第一种方式得到词序列索引,作为嵌入层的原始输入。下文的实验部分会测试并对比按这三种方式训练模型的性能,先说结论:预训练+微调>预训练>微调。 ## 非预期问题 @@ -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)文件夹中。 ## 测试结果分析 @@ -127,4 +129,6 @@ embedding_size:词嵌入向量的维度。 - [x] 预训练的数据不是越多越好,字典也不是越大越好,随着数据量的增大,性能有上限,该截断就截断。 - [x] 训练模式效果对比一般有:预训练+微调>预训练>微调。 -- [x] 无论是同源数据还是异源数据,只有其攻击模式类似,模型效果就可以泛化到。 \ No newline at end of file +- [x] 无论是同源数据还是异源数据,只有其攻击模式类似,模型效果就可以泛化到。 + +这篇文章是对我部分工作的一个总结,把零零散散的单点串成线,站在一个更高的视角看待问题。真相在第五层,我以为我看到了第二层,但我可能还在第一层,我们能做的是,唯有不断思考。 \ No newline at end of file