第一次个人编程作业
基于GRU自编码器的文本查重
Preview
| 这个作业属于哪个课程 |
| ---- | ---- | ---- |
| 这个作业要求在哪里 |
| 这个作业的目标 |
代码文件
PSP表格
| 这个作业属于哪个课程 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟)| |
|---|---|---|---|
| Planning | 计划 | 10 | 5 |
| Estimate | 预估时间 | 500 | 578 |
| Development | 开发 | 5 | 8 |
| Analysis | 分析 | 10 | 10 |
| Design Spec | 生成设计文档 | 5 | 5 |
| Design Review | 设计复审 | 10 | 10 |
| Coding Standard | 代码规范 | 5 | 5 |
| Design | 具体设计 | 20 | 20 |
| Coding | 编程 | 240 | 260 |
| Code Review | 代码复审 | 20 | 20 |
| Test | 测试 | 50 | 100 |
| Reporting | 报告 | 100 | 100 |
| Test Report | 测试报告 | 20 | 20 |
| Size Measurement | 工作量计算 | 5 | 5 |
| Review | 复盘 | 10 | 10 |
| 合计 | 500 | 578 |
计算模块接口的设计与实现过程
本项目共分成三个模块:
- 数据预处理
- 模型定义
- 主模块
数据预处理和模型定义可并发运行,主模块需要等前两个模块运行之后方能执行。
![]()
数据预处理模块
该模块主要用于对输入的文本进行处理,包括对文本进行分词,文本转化等操作。文本的分词主要基于jieba库进行分词,分词可以方便后续对词向量化的操作。文本转化主要讲文本型数据转化成计算机可以处理的数值型数据。
模型定义
本次项目主要基于Pytorch深度学习框架实现。基于Seq2Seq以及自编码器的结构启发,本文首先将文本同时作为输入和输出,构建基于GRU的Seq2Seq模型。模型训练完成之后,保留编码器部分作为文本向量的化的模型。
其中GRU的原理可以参考
人人都能看懂的GRU
Seq2Seq模型原理可以参考
Sequence to Sequence Learning with Neural Networks
主模块
该模块的输入为经过数据预处理之后的文本和定义完成的模型。主模块主要进行
- 模型的训练
- 文本相似度的计算
模型的训练
将处理完成的数据打包成模型可以调用的格式,并输入到模型当中进行训练。输入到模型当中的数据首先经过embedding的操作,embedding之后的数据输入到模型当中进行前向传播,梯度的计算以及权重的更新。训练完成之后,保留模型当中编码器的部分用作文本向量化。部分代码如下图

文本相似度的计算
该部分接受两个文本数据,并返回一个数值数据用于衡量文本的相似度。这里需要对文本进行处理,包括分词,转化等操作并输入到encoder中进行文本向量化操作。相似度的计算采用余弦相似度对两个文本进行计算。余弦相似度的定义如下:

相似度计算代码如下

计算模块接口部分的性能改进。
本项目由于使用了深度学习模型,其执行的效率与执行文件时所使用的机器之间有很大的关系。本次测试使用的机器是M1 MacBook Air。如果测试者使用含有GPU的机器,其速度经过验证可以达到1s左右。本次分析使用的数据收集于MBA,下图是有关的执行时间。

可以看出费时的部分主要在三个部分,
- 相似度的计算(similarity函数)
- 文本转化的过
- 生成文本向量的过程
其中可以进行改进的地方有相似度计算,该相似度的计算可以使用搭载有GPU的机器进行。因为相似度的计算主要涉及到浮点数的点乘运算,而通过CUDA对浮点运算的优化,可以极大缩短相似度计算的时间。而生成文本向量的过程也可以部署到CUDA进行优化。
计算模块部分单元测试展示

可以看出,单元测试的覆盖率并不高。经过检查,发现没有覆盖到的部分实际上是已经被调用到的。

以model.py文件36-42行为例,这几行是Decoder类的初始化时的属性定义,对该类进行实例化时,首先会调用该类的构造方法。
经过手动检查,计算得出单元测试的覆盖率达到96%。
测试用例的结果
本文仅仅展示文本orig.txt和orig_0.8_add.txt测试的结果。通过命令行传入对应的参数,并且设置进行训练(可以选择传入False,时间可以缩短至3s)。经过500轮次训练后,模型输出两个文本之间的相似度。

输出结果

其它文本的结果如下图表所示
| 文本1 | 文本2 | 相似度 |
|---|---|---|
| orig.txt | orig_0.8_add.txt | 0.78 |
| orig.txt | orig_0.8_del.txt | 0.83 |
| orig.txt | orig_0.8_dis_1.txt | 0.83 |
| orig.txt | orig_0.8_dis_10.txt | 0.79 |
| orig.txt | orig_0.8_dis_15.txt | 0.78 |
计算模块部分异常处理说明。
由于训练样本有限,通过给定的文本构造的语料库定会存在不够全面的问题。这就造成了输入新的分词后的文本的词语时,可能因为没有对应的词而报错的问题。本文设置了

若没有该判断条件,则会出现下图报错,

