-
Quora Question Pairs 退出小组
Quora Question Pairs比赛思路记录和交流 置顶 精华
25回复-
今天是2017年12月24号,平安夜:)18天前进入的这个项目,两周多的时间,还挺快。
之前学过解惑者学院的《垃圾短信识别小试牛刀》课程,有学过词向量,因此对于这个判断两句话意思是不是相同的问题,自然想到的就是把“词”-> 向量 的方法进行推广,扩展成 “句子”-> 向量。但是至于怎么扩展,怎么用向量表达一句话的意思,感觉还没有什么思路。另外就算知道了怎么表达成向量了,还有一个问题是两个向量到底有多“相似”才是意思一样,也不是很好判断的问题。还没有太多思路。
在这两个问题都不是特别清楚的情况下,面临的一个问题,是到底要不要直接去kaggle上找现成的解决方案来利用。但是仔细想了下,想找个方案是很容易的,但是如果只是把方案拿过来实现一下,甚至是有现成的代码拿来RUN一下,似乎学不到太多的东西。于是就想先自己思考一下。
不过既然是自然语言处理的项目,老师也说了是很常见的问题,就想先学学自然语言处理。忘了是怎么找到了斯坦福大学的CS224N( Deep learning in NLP)这门课了,就先看了大约两周的时间。里面开始讲的是word2vec,又跟着看了一遍,有了更多的理解。然后提到了Glove,讲义里说这种向量表示会包含更多的语义信息,估计Quora项目能用的上。就先记下了。至于说这个向量是怎么训练的,暂且没有太管。
然后又看了几天,里面开始提到了神经网络,RNN, CNN, LSTM,有讲到用RNN实现语言模型(什么是语言模型就不说了),这个时候就感觉到可以用RNN做Quora项目。因为想想其实本质是一样的; 都是记录历史信息。当然也可以用LSTM,因为LSTM和RNN没有本质上的区别。LSTM对于长期的序列学习会更好。
此时一开始的疑问之一就解决了。先暂时用RNN(or LSTM)来做。那是不是这样就是最好的表达向量的方式呢? CS224N后面会提到,基于Tree-LSTM(可以说成是 Recursive CNN吗)。 这个方法的动机是说:一句话的意思,由二方面决定,一是句子的组成结构、二是句子中词的含义。224N举的例子是说,语言学领域(包括其它任何领域),递归是一种特别常用的现象。比如" the dog walked into the house"。(随意编的一句话)。the dog 是主语从句?? walked into the house是谓语(从句?),这二者合并成了完整的这句话。the dog 也可以再递归地向下拆分结构。但是这种方法需要parser,来把句子的结构分析出来。看了看这个另外的任务也可以用神经网络去做。 不过这种方法会比较麻烦,暂时先不准备用这种方案。毕竟还是先做个简单的版本出来吧:)
刚开始说的一个疑问(怎么用向量表达话的意思就明白了),然后是另外一个问题——怎么衡量向量的相似度。恰好还是看CS22N,里面提到了下面的这种结构,觉得可以用在此项目上。叫Siamese Nets。
x1,x2就可以是RNN(LSTM)送出来的句子向量。
然后就百度了一下这种网络,恰好又找到了一篇论文,
Siamese Recurrent Architectures for learning sentence similarity.
里面提到了下面的架构:
我感觉这个架构可以直接做为参考使用。
下面把这个思路整理一下:
1. 用Glove表示词向量;
2. 用线性LSTM表示句子
3. 用Siamese Nets 做成判断网络使用
不过还有一些细节可以思考:
词向量需不需要更新(重新学习)?
例如最简单的情况,如果 有一些词如果在Glove里面没有,怎么办? 比如下面的话,注意这个样本的label是1
How do we prepare for UPSC?
How do I prepare for civil service?
可以推测出来,UPSC应该是 civil service 的意思。
所以说,对于样本的label=1 的样本,我们是不是可以利用一下来优化词向量?
想问一下,这个架构可以吗?如有问题或者建议请老师提出。
-
网络结构不小心被我删掉了,能重新发一下么?
这个是非常常用的网络结构,尤其是需要处理两个事物之间关系的时候。他是一个通用的结构,你可以替换成你想要的任何方法
-
@旷野的季节 在做事情之前做了这么多且细致的工作,大赞一个!
首先不透露更多的可能解决问题的思路了,等你做到一定的深度的时候,再来细说一下这个。个人建议在做一个项目的时候不要参考别人的做法,尤其是刚开始的时候。机器学习是数据为基础的领域,不同的数据具有不同的特点,不存在一种方法能解决所有的问题。参考别人的做法,就丧失了自我分析数据的过程,这也是机器学习过程中最重要的活动,也是体现水平的时候。其实模型在实际的工程项目中的工作量很小。
你的思路可以尝试,当然还有很多问题等待着你去解决。例如,是使用现成的vector还是直接通过训练数据去训练,亦或是两者结合;是使用RNN还是CNN;多层是否必要;训练速度太慢怎么办;效果不如预期,比排行榜上的得分差的太多,原因在哪儿;是否需要引入更多的特征,例如文本类特征;可以做多个模型融合吗 等等
可以多尝试做一下数据分析和深度研究,可以用一些小模型研究看看情况
-
先重新把图发一下,下面这个图是 Siamese Nets, 一种通用的架构。
另外,和垃圾短信类似的做法,是不是也可以先预处理一下、比如先把停用词给去掉。或者按照老师上次回复说的,用一些文本类特征。这么做肯定是可以的,至于怎么利用日后慢慢细想。
下面这个图是初步准备使用的架构图。单层的LSTM网络,把两个句子的最后一级的state(t) 拿出来,后面可以是按照图中这么做求欧式距离,也可以是再进入一个MLP神经网络。然后再求欧式距离。如果两个句子意思相同,则欧式距离应该尽量小; 如果两个句子意思不相同,欧式距离应该尽量大。然后采用stochastic 梯度下降法做训练。
-
2017.12.26-2018.1.1 周总结
(1) 目前打算先按照这个架构做。 这周主要学习了一下tensorflow工具。先看了看最基本的、什么是tensor, 什么是node; cost 函数怎么描述,placeholder, optimizer ……
看的是下面这篇文章:感觉写的比较详细
http://jorditorres.org/research-teaching/tensorflow/first-contact-with-tensorflow-book/first-contact-with-tensorflow/
(2)看懂了上面的文章后,仔细阅读了下面这篇文章,该文章通过一个toy project ,即利用RNN解决01二元序列的预测问题。
https://r2rt.com/recurrent-neural-networks-in-tensorflow-i.html
把里面的代码仔细看了看,有下面的收获:
First, RNN抓住的是 X 在“历史上”的信息,通过inner state 内部反馈实现
Second, 这篇文章的tensorflow程序架构、可以分为“数据发生器”“计算图模型”“把数据送进计算图”“ run session”这么几部分,结构还是比较清楚了。 自己写程序时也要注意一下组织程序的问题。有空时可以读一下《小试牛刀》里面推荐的那篇 怎么组织tensorflow程序的文章。
Third, Quora Question问题,不同的话的长度是不相同的。即如果用LSTM的话,输入序列个数(num_steps)是变化的。 调研了一下Dynamic RNN的问题。即通过tensorflow中的Dynamic RNN,可以不用做padding。
Forth,还有一个细节需要思考。 如果用欧式距离做判决的话,这个最终的阈值是怎么确定的。 是否作为参数之一自动学习出来呢? 还是在模型训练的时候,就只是尽量优化出一个结果、即相同意思的句子欧式距离尽可能小,不同意思的话欧式距离尽可能大。最终加一个处理流程,比如统计一下所有的意思相同的话里面,欧式距离最大的值是多少,以此值来作为阈值??这个细节还没有想好应该怎么弄。
下一步工作:
1. 先尽快写出来一个base 版本的程序,用 Train split出来的test集测试一下看看情况
2. 对数据进行更深入的研究。 想想是不是有更好的思路。
-
-
基于RNN的一种实现方式
RNN可以捕捉X序列的信息。比如在下面这个例子里面:
https://r2rt.com/recurrent-neural-networks-in-tensorflow-i.html
X是一个随机产生出来的0,1序列,0/1的概率各是0.5 ;Y序列的产生与X序列有关系。 规则是下面这几条:Y[t]=”1”的基础概率是0.5; 如果X[t-3] = 1, Y[t] =’1’的概率提高50%; 如果X[t-8]=1¸y[t]=’1’的概率降低25%; 如果X[t-3]和X[t-8]同时为1,y[t]=1 的概率是0.5+0.5-0.25=0.75。
可以把X序列拆分成一个个小的序列,送到RNN模型里面去学习。最终,RNN可以学出来这两个规律。(X[t-3]和X[t-8]对于 y[t]的影响)
虽然这只是一个简单的例子,但是从这个例子可以体会到RNN的作用。
对于Quora项目,也可以使用类似的思路。用两个相同的RNN(or LSTM or GRU,下同)网络,分别处理s1,s2两句话。如下图所示。
S1,s2中的每一个单词都先转化成glove向量、 然后送入RNN网络。第一句话是”He is smart” ; 第二句话是”A truly wise man”。在这种encoder架构下,我们认为h3(a)和h4(b)分别代表了两句话的意思。
那么怎么比较h3(a) h4(b)呢? 目前我准备使用的是L1 norm(h3a- h4b)。
比如,
h3(a) = [ 0.123, -0.343, 0.287]
h4(b) = [ -0.38, -0.165, 0.403]
h3(a) - h4(b) = [0.503, -0.178, -0.116]
|| h3(a) - h4(b)||1 = abs(0.503) + abs(-0.178) + abs(-0.116) = 0.797
那么在做预测的时候,这个L1 norm(RNN(s1)- RNN(s2) ) 多近s1,s2算是意思相同,多远算是s1,s2 意思不同呢? 关于这个阈值目前我的想法是当成一个参数来学习出来。如下图所示,横轴是L1 norm(encoder(s1) – encoder(s2)) 其中横轴 0<=x < +INF
纵轴是exp(-横轴), 将横轴压缩成了(0,1) 。exp(-横轴)中加了一个负号的目的,是为了与label中的含义(1表示两句话意思相同,0表示两句话意思不同)保持一致。
我期望的结果,是意思相同的pair(label=1), exp(-L1 norm(encoder(s1) – encoder(s2))) 应该会比较大(图中靠近上面的部分);而意思不同的pair(label=0), exp(-L1 norm(encoder(s1) – encoder(s2)))应该会比较小(图中靠近下面的部分)。而threshold就是区别两者的界限。为了下面描述方便,定义:
similarity(s1,s2) = exp(- L1 norm(encoder(s1) – encoder(s2))). ————公式(1)
作为相似度度量的指标,这个指标越大,相似度越高。
关于上面提到的阈值,目前我准备采用(一维的)Logistic Regression学习出来两个参数: w 和 b。 b 就是上面提到的threshold,w的含义目前还没有想好,先暂时这么定。即:
Probability(s1,s2 has the same meaning)= 1/ (1+exp(- (w*similarity(s1,s2)+b) )) –公式(2)
这个函数把 similarity从度量距离的空间映射到“概率空间”。这样以batch 为单位训练的时候,batch内所有样本出来的概率= 各个样本出现的概率的连乘。然后取其 负对数(-log)作为损失函数,各个样本的损失函数相加作为一个batch的损失函数而成为优化目标。
losses = - [ y * tf.log(probability) + (1-y) * tf.log(1- probability) ] --------公式3
注:y,probability是一个batch的数据
程序的架构:
- RNN_model.py
定义模型(计算图), 损失函数
模型的超参数:
Hyper-Parameters
Value Space
Notes:
Rnn_type
“rnn” , “lstm”, “gru”
Encoder里面的记忆单元采用RNN 还是LSTM 还是GRU
Nonlinear_type
“sigmoid” or “ReLU”??
Quora Question Pairs 思路记录
最新推荐文章于 2024-04-06 09:54:26 发布
本文记录了作者在Quora Question Pairs比赛中的思路和学习过程,从自然语言处理的角度出发,探讨了如何用RNN、LSTM和Siamese Nets构建模型来判断句子相似性。作者首先介绍了从词向量到句子向量的转换思路,然后提出了使用L1 norm计算向量相似度并以Logistic Regression学习阈值的方法。在实践中遇到了训练集loss下降快但测试集loss较高的问题,以及词向量训练和模型过拟合的挑战。
摘要由CSDN通过智能技术生成