CNN在智能问答中的应用

智能问答在智能客服领域应用的非常广泛, 微软/Google/Facebook等巨头公司也花了大量精力在聊天机器人上. 聊天机器人的技术方案现在有两种, 一种是检索模型, 另一种是生成模型. **生成模型**的核心思想是Sequence to Sequence模型, 是一个非常活跃的研究领域, 可以作为闲扯调戏的对象, 放在实际产品中解决问题还不太成熟. **检索模型**中的主流技术方案大概也分为两种, 一种基于搜索, 一种基于机器学习. 基于检索的模型其实在慢慢的被淘汰, 准确率已经低于机器学习方案, 并且差距有越来越大的趋势.
智能问答在机器学习来说, 核心就是文本分类, 文本分类有多种模型, 比如贝叶斯模型, CNN, RNN等. 实际应用效果来看, 深度学习方案要优于其他机器学习方案. 本文将深入探讨下CNN在中文智能问答中的解决方案.
===== 基本流程 =====
– 训练过程
– 收集数据
– 建立模型
– 调节参数
– 验证效果
– 获得模型
– 应用过程
– 将训练过程中获得的模型应用到线上应用
主要分为两部分, 一部分训练过程, 得到个中文文本分类模型; 第二部分将分类模型应用到线上即可. 第二部分相对偏工程, 比较核心的内容是在模型的建立和参数的调节中, 下面给出一个CNN中文文本分类模型, 主要参考文献是1. Convolutional Neural Networks for Sentence Classification和2. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift.
===== 技术细节 =====
**1. 文本向量化**
CNN是面向图像处理领域的一个比较成功的模型, 近年来在NLP领域也开始崭露头角. 这里的文本向量化方法主线路和论文中所述类似, 主要流程是:
– 预处理, 将全角转半角, 大写转小写, 去除特殊字符, 将文本按字切分等
– 从训练集中获取中文+常见英文做成一个索引字典, 并添加一个padding字符索引
– 设置句子向量的最大长度, 倒序遍历训练集的每个句子, 对于每个碰到的字都去检索索引字典并添加到句子向量中, 如果超过长度则丢弃剩余字, 如果短于设置的长度就添加padding字符索引
– 根据句子类别获取所有的y向量
到这, 我们有了x/y向量, 但是这个x向量还不能直接作为CNN的输入, 还要做一次word embedding. Word embedding有两种方法:
– 随机初始化, 让CNN自己在训练中获取每个字的向量
– 无监督学习获得
论文中实现了这两种方法, 并且做了结合(multichannel)还进行了对比, 总体来说单纯的无监督学习获得向量并且在训练中动态调整(non-static)的效果比较好. 后续会进行相应的试验, 检验是否适合用于中文文本分类.

**2. 模型结构**
这里拿论文中的图1进行讲解:

图示中有两个channel, 各个channel的处理是一样的, 拿一个channel来看, 每一行代表一个字向量, 行数就是设置的最大句子长度. 为了同时捕获句子中单字/双字/三字/四字特征, 这里的FILTER_SIZES分别设置成为1,2,3,4(通过Cross Validation获得), 这些长度的filter就像滑动窗口一样依次扫过整个句子, 每一个filter_size的filter(filter个数为128)都会得到一个向量, 通过一层batch normalization, 再送给relu激活函数进行处理, 最终在CNN层进行一次max pooling, 将每个句子每个filter获得的最大值输出. 这些最大值有128*4个, 进入softmax模型进行分类, 即是这里实现的整个模型结构. 和论文中不同的是这里多实现了一个batch normalization和多分类softmax.

**3. Batch normalization**
Batch normalization是Google大牛在2015年的论文中提出的, 基本思想是对隐层的输出层进行一次正则化, 可能你会觉得很简单, 但是在CNN的应用上尤为成功. 算法如下图所示:

对于DNN来说, batch normalization就是在mini-batch的隐层单元的输出上对每个维度进行一次正则化, 并且进行相应的scale和shift. 而对于CNN来说, 比较好的方法是对同一个batch的所有相同channel进行一次正则化, 这样可以保证CNN模型本身的特性.
训练过程如上可以解决, 预测过程我们希望样本的分类结果仅仅是由自己决定, 跟其他样本无关, 那么就需要整体样本的均值和方差(之前的参数估计都是有偏估计). 可以由以下算法得到:

**4. Cross Validation**
Cross Validation是一种模型参数自动化获取的一种方案, 在之前的文章中有详细讲解, 这里不做赘述.

**5. 参数组合**
为了调节参数达到最优状态, 在进行cross validation进行参数选择之后, 最终确定下来的参数如下:

BATCH_NORM=True
BATCH_SIZE=256
DROPOUT_KEEP_PROB=0.5
EMBEDDING_DIM=256
EVALUATE_EVERY=100
FILTER_SIZES=1,2,3,4
HEIGHT_STRIDE=1
L2_REG_LAMBDA=0.0
NUM_FILTERS=128
NUM_THREADS=8

===== 结束语 =====
可以说, 这是从我学习机器学习以来一个比较大并且比较成功的应用, 从论文到实现碰到过很多问题, 但好在解决之后看到不断上升的准确率让人很有成就感. 数据比较敏感, 这里不过多阐述, 后续会根据最新研究进展继续优化模型:-)

— 2016/07/24 12:23