使用CNN+ Auto-Encoder 实现无监督Sentence Embedding (代码基于Tensorflow)

前言

这篇文章会利用到上一篇: 基于Spark /Tensorflow使用CNN处理NLP的尝试的数据预处理部分,也就是如何将任意一段长度的话表征为一个2维数组。

本文完整的代码在这: autoencoder-sentence-similarity.py

基本思路是,通过编码解码网络(有点类似微软之前提出的对偶学习),先对句子进行编码,然后进行解码,解码后的语句要和原来的句子尽可能的接近。训练完成后,我们就可以将任意一个句子进行编码为一个向量,这算是Sentence Embedding的一种新的实现。最大的好处是,整个过程无需标注语料,属于无监督类学习。这次我还在编码前引入卷积网络,不过效果有待验证。

准备工作

我们假设大家已经准备了两个数据集,具体可以参考上一篇文章的Spark预处理部分

  1. 已经分好词的语句
  2. 词到vector的字典

然后我们使用如下函数来进行处理:

def next_batch(batch_num, batch_size, word_vec_dict):
    with open(WORD_FILE) as wf:
        line_num = 0
        start_line_num = batch_num * batch_size
        batch_counter = 0
        result = []
        for words in wf:
            result1 = []
            line_num += 1

            if line_num > start_line_num:
                batch_counter += 1
                for word in words.split(" "):
                    if word in word_vec_dict:
                        result1.append(word_vec_dict[word])
                if len(result1) < SEQUENCE_LENGTH:
                    for i in range(SEQUENCE_LENGTH - len(result1)):
                        result1.append(np.zeros(shape=(VOCAB_SIZE, 1)).tolist())
                result.append([str(line_num), result1[0:SEQUENCE_LENGTH]])
                if batch_counter == batch_size:
                    return result

字典的格式是: word + 空格 + 100个逗号分隔的数字
文本内容格式是: 通过空格分隔的已经分好词的句子

因为这次测试数据集有点大,所以没办法一次性载入到内存,只能分批了。缺点是,每一次都需要重新打开文件,为了减少打开文件次数,程序后半部分做了一些优化处理,基本方式为,一次性从文件里取batch_size 条数据,然后让Tensorflow 再分 batch_size / mini_train_batch_size 次进行迭代。每次迭代给的样本量还是比较影响效果的,4000和200比,有20%左右的差异。

构建模型

我尝试了如下两个拓扑,第一个是带卷积的:

Input(段落) -> 卷积 -> 池化 -> 卷积 -> 池化 -> encoder -> encoder -> decoder -> decoder -> lost function (consine夹角)

第二个则是不带卷积:

Input(段落) -> encoder -> encoder -> decoder -> decoder -> lost function (consine夹角)
基本上是两层卷积,两层编解码器。

训练完成后,就获得编码器的所有参数,利用encoder_op 对所有的语句进行编码,从而实现所有语句得到一个唯一的向量(128维)表示。

大概准备了 60多万条语句进行训练,经历了50*60轮迭代后,不带卷积最后loss 大概是从1.1 下降到0.94的样子。如果进行更多迭代,提供更多训练数据,应该可以进一步降低。

带卷积的收敛较快,loss 从0.5 经过3000轮迭代,可以下降到0.1 左右。

因为语料比较隐私,无法提供,但是可以描述下大致的结论,随机找一段话,然后寻找相似的,目前来看,不带卷积的效果非常好,带卷积的因为卷积后信息损失太大,在encoder-decoder阶段感觉无法训练了,最后趋同,因此需要对卷积进行较大调整。关于NLP的卷积,其实我们不一定要保证卷积核的宽度或者高度保持和word embedding的size一样,因为对两个word截取其一般,我认为应该还是有一定的相似度的。

在训练过程中,损失函数我尝试了:

xent =tf.reduce_mean(tf.pow([y_true, y_pred],2), name="xent")

以及

consine = tf.div(tf.reduce_sum(tf.multiply(y_pred, y_true)),
                         tf.multiply(tf.sqrt(tf.reduce_sum(tf.multiply(y_pred, y_pred))),
                                     tf.sqrt(tf.reduce_sum(tf.multiply(y_true, y_true)))))
        xent = tf.reduce_sum(tf.subtract(tf.constant(1.0), consine))

因为采用欧式距离,我们难以确定相似度的阈值,而cosine是一个比较容易衡量的值。所以这里选择了consine作为损失函数。我没有找到Tensorflow的实现,所以完全根据consine公式自己实现了一个。

对于Optimizer,我尝试了

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(xent)
 train_step = tf.train.RMSPropOptimizer(learning_rate).minimize(xent)

目前来看,RMSPropOptimizer效果好很多。

总结

现阶段大量优秀的人才都投入到了深度学习上,所以深度学习也取得了越来越多的进展,用法也越来越多,尤其是对抗学习,加强学习,对偶学习的发展让深度学习可以做的事情越来越多。深度学习在NLP文本分类,特征抽取方面,我觉得还是有潜力可挖的。不过,我觉得深度学习其实是把机器学习的门槛提的更高了,虽然越来越多的工具(比如Tensorflow)和已知的各种实践似乎在降低某些门槛。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容