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

原文链接:http://tecdat.cn/?p=9322

前言

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

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

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

准备工作

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

已经分好词的语句词到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)和已知的各种实践似乎在降低某些门槛。

如果您有任何疑问,请在下面发表评论。

大数据部落 -中国专业的第三方数据服务提供商,提供定制化的一站式数据挖掘和统计分析咨询服务

统计分析和数据挖掘咨询服务:y0.cn/teradat(咨询服务请联系官网客服

?QQ:3025393450

?QQ交流群:186388004 

【服务场景】  

科研项目; 公司项目外包;线上线下一对一培训;数据爬虫采集;学术研究;报告撰写;市场调查。

【大数据部落】提供定制化的一站式数据挖掘和统计分析咨询

欢迎关注微信公众号,了解更多数据干货资讯!

欢迎选修我们的R语言数据分析挖掘必知必会课程!

原文地址:https://www.cnblogs.com/tecdat/p/12010293.html

时间: 2024-07-31 09:20:40

CNN+ Auto-Encoder 实现无监督Sentence Embedding ( 基于Tensorflow)的相关文章

将句子表示为向量(上):无监督句子表示学习(sentence embedding)

1. 引言 word emedding技术如word2vec,glove等已经广泛应用于NLP,极大地推动了NLP的发展.既然词可以embedding,句子也应该可以(其实,万物皆可embedding,Embedding is All You Need ^_^).近年来(2014-2018),许多研究者在研究如何进行句子表示学习,从而获得质量较高的句子向量(sentence embedding).事实上,sentence embedding在信息检索,句子匹配,句子分类等任务上均有广泛应用,并且

将句子表示为向量(下):基于监督学习的句子表示学习(sentence embedding)

1. 引言 上一篇介绍了如何用无监督方法来训练sentence embedding,本文将介绍如何利用监督学习训练句子编码器从而获取sentence embedding,包括利用释义数据库PPDB.自然语言推理数据SNLI.以及综合利用监督训练数据和无监督训练数据. 2. 基于释义数据库PPDB 2015发表的论文Towards universal paraphrastic sentence embeddings提出使用PPDB(the Paraphrase Database)来学习通用的sen

Auto Encoder用于异常检测

对基于深度神经网络的Auto Encoder用于异常检测的一些思考 from:https://my.oschina.net/u/1778239/blog/1861724 一.前言 现实中,大部分数据都是无标签的,人和动物多数情况下都是通过无监督学习获取概念,故而无监督学习拥有广阔的业务场景.举几个场景:网络流量是正常流量还是攻击流量.视频中的人的行为是否正常.运维中服务器状态是否异常等等.有监督学习的做法是给样本标出label,那么标label的过程肯定是基于某一些规则(图片除外),既然有了规则

【转载】 无监督特征学习——Unsupervised feature learning and deep learning

无监督特征学习——Unsupervised feature learning and deep learning 分类: Compression Computer Vision Machine Learning 杂感2012-07-31 15:48 36848人阅读 评论(61) 收藏 举报 目录(?)[+] 无监督学习近年来很热,先后应用于computer vision, audio classification和 NLP等问题,通过机器进行无监督学习feature得到的结果,其accurac

itorch无监督聚类

cmd = torch.CmdLine() cmd:text() cmd:text()用来在terminal上显示运行信息 cmd:option('-dir', 'outputs', 'subdirectory to save experiments in') cmd:option用来接受运行时的参数,第一个是参数名称,第二个是默认输入参数,第三个是备注. 1. 处理数据: dofile '1_data.lua' dofile和require的功能差不多,不过require不会重新加载,dofi

转:Deep learning系列(十五)有监督和无监督训练

http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: Andrew NG的深度学习教程: Li feifei的CNN教程: caffe官网的教程: 对比过这几份资料,突然间产生一个困惑:台大和Andrew的教程中用了很大的篇幅介绍了无监督的自编码神经网络,但在Li feifei的教程和caffe的实现中几乎没有涉及.当时一直搞不清这种现象的原因,直到翻阅了深度

【转】有监督训练 &amp; 无监督训练

原文链接:http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: Andrew NG的深度学习教程: Li feifei的CNN教程: caffe官网的教程: 对比过这几份资料,突然间产生一个困惑:台大和Andrew的教程中用了很大的篇幅介绍了无监督的自编码神经网络,但在Li feifei的教程和caffe的实现中几乎没有涉及.当时一直搞不清这种现象的原因,直到

【Machine Translation】无监督神经机器翻译论述

Unsupervised NMT 概述 神经机器翻译系统取得了很好的翻译水平,但非常依赖于平行语料.目前已经有利用大量单语数据训练模型的研究,这其中包括: 仅仅由两份单语语料(不平行)训练出双语词典.这个的核心是学习一个旋转矩阵W,使得两份语料的词向量空间对齐,再进行一些调整更好的对齐两词向量空间,最后进行单词到单词的翻译,即生成了双语词典. 对偶学习的思想.有些研究里也提出迭代后向翻译,但思想是类似的,即通过翻译模型生成假的平行语料,再利用该平行语料训练模型,迭代此过程. 利用第三种语言.翻译

无监督异常检测之卷积AE和卷积VAE

尝试用卷积AE和卷积VAE做无监督检测,思路如下: 1.先用正常样本训练AE或VAE 2.输入测试集给AE或VAE,获得重构的测试集数据. 3.计算重构的数据和原始数据的误差,如果误差大于某一个阈值,则此测试样本为一样. 对于数据集的描述如下: 本数据集一共有10100个样本,每个样本是1行48列的向量,为了让它变成矩阵,自己在末尾补了一个0,将其转变成7*7的矩阵.前8000个是正常样本.后2100个中,前300个是正常样本,之后的1800个中包括6种异常时间序列,每种异常时间序列包括300个