Quora Question Pairs 思路记录

    1. 首页 
    2. 小组频道 
    3. Quora Question Pairs
    Quora Question Pairs 思路记录

    Quora Question Pairs 退出小组

    33个成员 2个话题 创建时间:2017-11-30

    Quora Question Pairs比赛思路记录和交流 置顶 精华

    发表于12-06 1409次查看

    此贴用于对学习过程中遇到的问题、学习到的东西做一下小结,群主会根据小结的内容给予相应的建议。

    25回复
    • Quora Question Pairs 思路记录
      2楼旷野的季节  12-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 的样本,我们是不是可以利用一下来优化词向量?


      想问一下,这个架构可以吗?

      如有问题或者建议请老师提出。

       回复
    • Quora Question Pairs 思路记录
      3楼Ryan  12-29

      网络结构不小心被我删掉了,能重新发一下么?

       

      这个是非常常用的网络结构,尤其是需要处理两个事物之间关系的时候。他是一个通用的结构,你可以替换成你想要的任何方法

       回复
    • Quora Question Pairs 思路记录
      4楼Ryan  12-29

      @旷野的季节 在做事情之前做了这么多且细致的工作,大赞一个!

       

      首先不透露更多的可能解决问题的思路了,等你做到一定的深度的时候,再来细说一下这个。个人建议在做一个项目的时候不要参考别人的做法,尤其是刚开始的时候。机器学习是数据为基础的领域,不同的数据具有不同的特点,不存在一种方法能解决所有的问题。参考别人的做法,就丧失了自我分析数据的过程,这也是机器学习过程中最重要的活动,也是体现水平的时候。其实模型在实际的工程项目中的工作量很小。

       

      你的思路可以尝试,当然还有很多问题等待着你去解决。例如,是使用现成的vector还是直接通过训练数据去训练,亦或是两者结合;是使用RNN还是CNN;多层是否必要;训练速度太慢怎么办;效果不如预期,比排行榜上的得分差的太多,原因在哪儿;是否需要引入更多的特征,例如文本类特征;可以做多个模型融合吗 等等

       

      可以多尝试做一下数据分析和深度研究,可以用一些小模型研究看看情况

       回复
    • Quora Question Pairs 思路记录
      5楼旷野的季节  01-01

      先重新把图发一下,下面这个图是 Siamese Nets, 一种通用的架构。

      另外,和垃圾短信类似的做法,是不是也可以先预处理一下、比如先把停用词给去掉。或者按照老师上次回复说的,用一些文本类特征。这么做肯定是可以的,至于怎么利用日后慢慢细想。

      Quora Question Pairs 思路记录

      下面这个图是初步准备使用的架构图。单层的LSTM网络,把两个句子的最后一级的state(t) 拿出来,后面可以是按照图中这么做求欧式距离,也可以是再进入一个MLP神经网络。然后再求欧式距离。如果两个句子意思相同,则欧式距离应该尽量小; 如果两个句子意思不相同,欧式距离应该尽量大。然后采用stochastic 梯度下降法做训练。

       

      Quora Question Pairs 思路记录

       回复
    • Quora Question Pairs 思路记录
      6楼旷野的季节  01-02

      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. 对数据进行更深入的研究。 想想是不是有更好的思路。

       

       收起
      • Quora Question Pairs 思路记录
        Ryan 01-02
        整个思路没啥问题,可以先做base版本的尝试。 关于阈值的部分,项目是以logloss为优化目标,因此从这个角度上来看阈值不重要,重要的是预测的分布要与实际的分布尽可能的相近。
  • Quora Question Pairs 思路记录
    7楼旷野的季节  01-12

    基于RNN的一种实现方式

     

    RNN可以捕捉X序列的信息。比如在下面这个例子里面:

     

    https://r2rt.com/recurrent-neural-networks-in-tensorflow-i.html

     

    X是一个随机产生出来的01序列,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]同时为1y[t]=1 的概率是0.5+0.5-0.25=0.75

    可以把X序列拆分成一个个小的序列,送到RNN模型里面去学习。最终,RNN可以学出来这两个规律。(X[t-3]X[t-8]对于 y[t]的影响)

    虽然这只是一个简单的例子,但是从这个例子可以体会到RNN的作用。

    对于Quora项目,也可以使用类似的思路。用两个相同的RNNor LSTM or GRU,下同)网络,分别处理s1,s2两句话。如下图所示。

    Quora Question Pairs 思路记录

     

    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)||= 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表示两句话意思不同)保持一致。

    Quora Question Pairs 思路记录

     

     

    我期望的结果,是意思相同的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 就是上面提到的thresholdw的含义目前还没有想好,先暂时这么定。即:

    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的数据

     

    程序的架构:

    1. RNN_model.py

    定义模型(计算图), 损失函数

    模型的超参数:

     

    Hyper-Parameters

    Value Space

    Notes:

    Rnn_type

    “rnn” , “lstm”, “gru”

    Encoder里面的记忆单元采用RNN 还是LSTM 还是GRU

    Nonlinear_type

    “sigmoid” or “ReLU”??

    similarity(s1,s2)映射到概率空间的函数

    l2_reg_lambda

    R>=0

    L2正则化的系数

    number_units

    大于等于1的整数

    Encoder里面神经元的数量

    embedding_trainable

    True / False

    词向量是否可以再训练

    batch_size

    大于等于1的整数

    Batch-size

     

     

     

     

    模型的输入输出(tensor)

    Input or Output

    Variable

    Data type and Shape

    Notes

    Input

    Input_s1

    int32,[batch_size, None]

    输入的是词的ID

    Input

    Input_s2

    int32,[batch_size, None]

    输入的是词的ID

    Input

    Input_y

    Int32,[batch_size]

    Label,

    1 for same mearing ,

    0 otherwise

    Input

    Input_seqlen1

    Int32, [batch_size]

    S1数据集中每一句话的长度

    Input

    Input_seqlen2

    Int32,[batch_size]

    S2数据集中每一句话的长度

    Input

    dropout_keep_prob

    Float32, []

    Dropout keep 概率

    Output

    Loss

    Float32,[]

    损失函数,见公式3

     

    1. RNN_train.py

    Train dataDev test data Split

    定义模型的超参数

    定义train_step()函数

    定义dev_step()函数

    定义训练的主循环 ,主循环里面会调用next_batch()函数

     

    1. Data_helper.py

    处理train.csv

    考虑是不是要去掉标点? 可能不去比较好?

    定义next_batch()函数,生成batch数据

     

     

    词向量出于训练速度的考虑,可以先使用50维;今后看情况和手头设备(GPU)的情况考虑是不是增加到300维(当然有没有效果是另外一回事了)

     

    注:word2vec 代码:

    https://github.com/danielfrg/word2vec

     

    目前进展情况:

    写完了RNN_model.py , RNN_train.py

    接下来会写data_helper.py

     

    小组内成员情况:

    成员1, 小曙哥,可能会接下来和我一起完成data_herper.py

    成员2,卑恋,近期有其它事务,可能暂时不能加入此项目进度

     

    RNN_model.py

     

    import tensorflow as tf
    import numpy as np
    from data_helper import build_glove_dic

    class TextRNN(object):
        """
        A RNN model for quora question pair problem
        """
     
        def __init__(self,

          ## architecture hyper-parameters
          rnn_type = "rnn", ## or lstm or gru ?
          nonlinear_type = "sigmoid", ## or relu ? temp use sigmoid.
          l2_reg_lambda=0.0,
          number_units=64,
          embedding_trainable=True   
          ##train-related-parameters
          batch_size=64,   
          
        ## hyper-parameters finish
        ):
            #placeholders for input, output and dropout
            ##input_s1,input_s2 输入ID而不是word_embedding
            self.input_s1 = tf.placeholder(int32,[batch_size, None],name="s1")
            self.input_s2 = tf.placeholder(int32,[batch_size, None],name="s2")
            ## Quora question pair label , 1 for same meaning, 0 otherwise
            self.input_y  = tf.placeholder(int32,[batch_size],name="label")
            
            ## based on tensor-flow rnn model, we should know advance the sequence length of the sentence
            self.input_seqlen1 = tf.placeholder(int32, [batch_size],name="seqlen1")        
            self.input_seqlen2 = tf.placeholder(int32, [batch_size],name="seqlen2")  
            ## prevent overfitting
            self.dropout_keep_prob = tf.placeholder(tf.float32,name="dropout_keep_prob")
            ###placeholder finish
            
            ##hyper-parameters
            self.rnn_type       = rnn_type
            self.nonlinear_type  = nonlinear_type

            self.batch_size     = batch_size
            self.number_units   = number_units
            self.embedding_trainable = embedding_trainable   
            self.l2_reg_lambda  = l2_reg_lambda
            #Keeping track of l2 regularization loss(optional)
            self.l2_loss = tf.constant(0.0)


            
            self.init_weight()
            self.add_encoder()
            self.add_dropout()
            self.add_final_state()
            
            
        def init_weight(self):
            ##Embedding layer
            with tf.device('/cpu:0'), tf.name_scope("embedding"):
                _, self.word_embedding = build_glove_dic()
                self.embedding_size = self.word_embedding.shape[1]
                self.W = tf.get_variable(name='word_embedding', shape = self.word_embedding.shape,dtype=float32,
                initializer=tf.constant_initializer(self.word_embedding), trainable=self.embedding_trainable)

                ## s1,s2 的形状是[batch_size, sequence_length, embedding_size]
                self.s1 = tf.nn.embedding_lookup(self.W, self.input_s1)
                self.s2 = tf.nn.embedding_lookup(self.W, self.input_s2)
                self.x1 = self.s1
                self.x2 = self.s2
                
                
                
        def add_encoder():
            if self.rnn_type=="rnn":
                cell = tf.contrib.rnn.BasicRNNCell(self.number_units)
            elif self.rnn_type=="lstm":
                cell = tf.contrib.rnn.BasicLSTMCell(self.number_units, state_is_tuple=True)
            elif self.rnn_type=="gru": ##needs to check
                cell = tf.nn.rnn_cell.GRUCell(self.num_units, input_size=None, activation=tanh)
            
            init_state = tf.get_variable('init_state', [1,num_units],
                                          initializer = tf.constant_initializer(0.0))
            init_state = tf.tile(init_state, [self.batch_size,1])
            
            rnn_outputs1, final_state1 = tf.nn.dynamic_rnn(cell, self.x1, sequence_length = self.input_seqlen1, initial_state=init_state)
            rnn_outputs2, final_state2 = tf.nn.dynamic_rnn(cell, self.x2, sequence_length = self.input_seqlen2, initial_state=init_state)

           
        def add_dropout():
            #add droptout, as the model otherwise quickly overfits . really ??
            rnn_outputs1 = tf.nn.dropout(rnn_outputs1, self.dropout_keep_prob)
            rnn_outputs2 = tf.nn.dropout(rnn_outputs2, self.dropout_keep_prob)
            
        def add_final_state():
            idx1 = tf.range(self.batch_size)* tf.shape(rnn_outputs1)[1] + (self.input_seqlen1-1)
            idx2 = tf.range(self.batch_size)* tf.shape(rnn_outputs2)[1] + (self.input_seqlen2-1)
            
            last_rnn_output1 = tf.gather(tf.reshape(rnn_outputs1, [-1, num_units]),idx1)
            last_rnn_output2 = tf.gather(tf.reshape(rnn_outputs2, [-1, num_units]),idx2)
            
        def add_loss():
            ## caculte "difference" between encoder output of sentense1 and sentense2
            ## caculate the norm1 distance    
            diff     = last_rnn_output1 - last_rnn_output2          ##shape [batch_size, num_units]
            diff_abs = tf.abs(diff)                                 ##shape [batch_size, num_units]
            diff_abs_sum = reduce_sum(diff_abs, axis=1)             ##shape [batch_size]
            
            ## squeeze the norm1 distance between (0,1)
            diff_exp = tf.exp(-diff_abs_sum) ##shape [batch_size], 
            
            ## automatically learn the "threshold" 
            ##"use this nolinear to map exp(-||x1-x2||) (L1 norm diff) to probability")
            with tf.name_scope("threshold"):
                W = tf.variable([1.0], name="W")
                b = tf.variable([tf.log(0.5)], name="b")
                wx_plus_b = diff_exp * W + b               ## shape [batch_size]
            ##apply sigmoid OR relu ??
            if (self.nonlinear_type == "sigmoid"):
                prob = (1+exp(-1.0 * wx_pls_b)) ## shape[batch_size]
            elif self.nonlinear_type == "relu":
                prob = maximum(0,wx_plus_b) ## ?
                
            ## use logistic regression (softmax) cost
            ## if y=1, prob = prob
            ## if y=0, prob = 1-prob
            losses = y * tf.log(prob) + (1-y) * tf.log(1-prob)     ## shape [batch_size]
            self.loss = tf.reduce_sum(losses)                       ## shape [1,]
                

     

     回复
  • Quora Question Pairs 思路记录
    8楼Lynn  01-12

    1.  想法基本上没有太多的问题,可以先将基本的代码跑通,只要能够确定你的代码能够学习到数据集的信息,就行了,至于正则的部分最开始的时候不用考虑,最重要的是让模型跑起来,这是一个骨架。

    2.  代码部分以后最好加上图片,让我们能够看得清,加上图片的同时最好加上代码链接,以便复制下来看。

    3.  lstm是个不错的结构。是不是可以使用双向lstm和CNN呢,损失函数是不是可以使用其他的呢,参考论文:http://anthology.aclweb.org/P/P16/P16-1036.pdf。

    4.  这个比赛当中有一点比较重要,就是训练集和测试集的正负样本比例。这个会大大影响你的测试结果。

    5.  代码可以参考别人的比较好的代码,第一是学习别人代码,二是培养一个好的代码风格。

    6.  还有一个比较大的方向:现在使用的基于Siamese网络结构,有更好的网路结构吗?(这个需要将现在的结构跑完在去探索)

    7. 可以拜读一下2016年的ACL会议的论文,里面有很多论文提到了语义理解和文本匹配。很多有很大的参考价值。

     回复
  • Quora Question Pairs 思路记录
    9楼旷野的季节  01-12

    好的,谢谢唐老师!

     回复
  • Quora Question Pairs 思路记录
    10楼旷野的季节  01-29

    2018-01-29

    这两周一直在调试代码,但不是很顺利,所以上周没发进展。先说下目前的调试过程,再说下现在遇到的问题吧。

    两周以前写完了RNN_model.py 和 RNN_train.py 前面说过,RNN_model.py创建了RNN模型(定义placeholders, rnn cell, encoder_s1, encoder_s2, 定义losses, loss);

    RNN_train.py  定义超参数; 定义train_step, dev_step , 实现训练过程

    data_helper.py 用于读取原始的数据,创建glove 词向量,seq2id,生成mini-batch等辅助工作。

    大约花了一周时间完成data_helper.py并且让程序跑通了。但是发现了一个重大的问题——loss函数无法收敛。还有一些其它问题,先简单说一下细节问题吧,

    (1) 比如data_helper.py创建mini-batch时,train.csv 最后的数据量不够batch_size 这么多了。导致和placeholder的维度不一致、程序报错退出。但是由于这个小问题存在,RNN模型没法长时间训练,我一开始就想loss函数不能收敛是不是由于训练时间不够长导致的。(其实一开始是先降低了learning-rate ,但是发现不管用)所以目前为了省事儿,先把train.csv 截取了 batch-size 整数大小的一部分(一共65536个sample,batch_size=128)

    (2) 程序跑起来很慢。我把40多万条train.csv 取前面的65536个,这样应该可以吧? 我想着是在65536条example的 "train_small.csv" 上如果确认模型能学到东西了,再换成全部的训练数据。这样跑起来可能还稍微快一点。

    (3) 一开始超参数不太会选。比如batch_size=128,感觉训练起来速度还能接受,如果batch_size太大,内存都不够用了,直接报OOM (out-of-memory?)。然后学习率选的是 1e-3吧,也说不出为什么,就先这么选了。还有模型,就先选的RNN而没有用LSTM,GRU。想先调调基本的模型。

    (4)数据清洗可能做的不太够,比如有的问题就是一个问号,没有内容。这样RNN模型会需要句子长度len,我之前的程序在这种下会认为是0. 导致tensorflow在计算rnn_outputs时报错。也花了一点时间找这个问题。

    然后再说目前最大的问题,losses 不收敛。

    For review purpose, 公式就是下面的:

    similarity(s1,s2) = exp(- L1 norm(encoder(s1) – encoder(s2))).  ————公式(1

    作为相似度度量的指标,这个指标越大,相似度越高。

    比如如果encoder(s1)-encoder(s2)=0, similarity(s1,s2)=1;

    else 如果encoder(s1)-encoder(s2) 很大,similarity(s1,s2)约等于0

    Probability(s1,s2 has the same meaning)=sigmoid(w*similarity(s1,s2)+b)    –公式(2) 其中w,b 我认为是某种“阈值信息”

    losses = - [  y * tf.log(probability) + (1-y) * tf.log(1- probability) ]    --------公式3

    一开始遇到loss 不收敛,肯定先想到的就是learning-rate 太大了。然后learning-rate 调小后,也不起作用。就来看看loss变化有什么规律没有。发现loss 会一点点地变大; 如果把learning-rate 调小后,loss也同样会变大,而且是按照比之前较小的速率大变大(learning-rate变小了)

    然后在想是不是我这个模型本来就是不对的?这个模型根本就没不到东西?我现在要不要换个模型试试?

    但是觉得说不通啊。然后就想是不是因为模型不能长时间训练造成的(前面说过的那些细节问题)

    但是65536个sample, batch_size=128情况下,也能训练512个mini-batch了,也不能一点东西学不到吧(分析是否正确?)

    而且loss 在慢慢变大。这个趋势本身就不对。后来把细节问题解决了,模型能开时间训练了,果然loss 还是变大,趋势没有发生变化。

    所以觉得肯定有别的问题。

    后来还做了下面的尝试:

    self.loss = tf.reduce_sum(self.losses) ## shape [1,]
     
    ## just for test-purpose of the wrapper of this file, NO Actual Ustage
    ##self.val = tf.Variable(initial_value=2.4)

    ##self.loss += self.val

     

    因为我不知道是模型的原因,还是模型上面包的那层训练过程的原因,我就把loss+ 一个variable

    这个发现self.val 会慢慢变小。所以肯定不是训练过程的原因了。如果调整learning-rate 的话—self.val也会跟着变。所以肯定训练过程没问题。

    这样又折腾了好几天。上周六(两天前)发现是loss 函数写反了。:(

    一开始我代码里面写的是

    losses =   y * tf.log(probability) + (1-y) * tf.log(1- probability)少了个负号,因此loss不降反升。

    发现这个问题后,原来以为问题能解决,但是发现loss现在的确不变大了,但是也不变小。

    然后又开始了新一轮尝试,是不 是learning-rate太大了。是不是loss 定义的不对?等等;

    但是目前还没有什么进展。

    现在有什么思路能解决这个问题吗?

    比如把RNN隐藏层的神经元数量变大?

    或者是RNN新一轮的训练没有用上一轮的训练结果?

    或者是mini-batch的数量不合适?(128 )

    还是65536个example 不够(这个可能性小吧)

    或者是RNN模型有什么地方代码有问题?比如获得最后一个stage的rnn_output不对?

    请老师帮忙看看吧。

    代码在:

    https://github.com/chenaaaaa/rnn-based-quora-question-pair

    谢谢!

     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

     回复
  • Quora Question Pairs 思路记录
    11楼旷野的季节  01-30

    2018-1-30 update

    继续昨天的更新一下,

    发现训练时公式(2)里面的w,b 没有朝着一个方向变化(变化了一会又反方向变回来了)

    昨天又做了一下尝试,先简化了一下模型,即把原公式(2) bypss 让公式(2)=公式(1)

    公式(3)不变。简化版本的公式是:

    similarity(s1,s2) = exp(- L1 norm(encoder(s1) – encoder(s2))).  ————公式(1

    作为相似度度量的指标,这个指标越大,相似度越高。最大是1,最小是近似0

     

    Probability(s1,s2 has the same meaning)= sigmoid(w*similarity(s1,s2)+b)  原公式(2)去掉

    Probability(s1,s2 has the same meaning) = similarity(s1,s2)--简化版本公式(2)

    losses = - [  y * tf.log(probability) + (1-y) * tf.log(1- probability+very_small_constant) ]    --------公式3

    (+very_small_constant =1e-16  是因为有些example 的encoder(s1)=encoder(s2),导致probability是1。第二项的log里面会变成0而导致训练出错。)

    最后是对batch 里面所有example的loss求和: loss = tf.reduce_sum(losses)

    发现还是loss 还是上下波动,但是整体上没有向下变化的趋势.

     

    后来还做过尝试,把RNN变成GRU,现象也并没有什么变化啊。。难道RNN模型就不能用吗?

     回复
  • Quora Question Pairs 思路记录
    12楼Lynn  01-31

    你这个代码应该是参考别人的代码写的,有这么几个问题你可以考虑一下(代码的话,有点难看):

    1.  你的给你的训练数据训练了多少个epoches

    2. 6万的数据真不一定够,你可以使用所有的数据,如果不行,再考虑是不是有问题,RNN是没有问题的。

    2.  你用的是对比损失,你现在就先让对比损失跑起来(我这边用对比损失的效果,要比log_loss好)

         有这么几个要点:1. 正负样本比例

                                    2. 你的代码是不是有问题,我在最开始做这个比赛的时候,也出现了你的问题。

                                    3. 如果觉得实在是有问题可以使用tf.losses.log_loss

                                    4. 我出现的问题挺多, 1):数据预处理部分我出现过问题。

                                                                       2):句子的长度你取了多少?我取得是55,也取过60

                                                                       3):神经网络部分的代码对的吗?

     回复
  • Quora Question Pairs 思路记录
    13楼旷野的季节  02-06

    2018-02-06

    1,先说这周获得的结论吧,目前确定GRU从数据集中学到了一些东西,但是问题是,基于目前的GRU方案+损失函数得到的(训练集)准确率比较低,只有57%左右。刚开始训练时的准确率(tp+tn/total)大约是33%,训练了大约2 epoch之后,准确率提升到了43%, 然后我记得经过比较长时间了,大约几十个epoches之后吧,准确率是57%,而且似乎没有再上升的趋势了。另外有时测试还发现,准确率也并不是一直维持在50%多,可能过一会儿又下降到了40% ,过一会儿又上升到50%多。这个。。。为啥

    另外上周的疑问,这周也确认了一下。发现使用4万多个样本训练和使用30多万个样本训练得到的训练集准确率差不多,没发现什么区别。不过现在还是使用了30多万个样本训练。

    2,确认一下我前上次所说的“LOSS函数不下降”的问题。发现那个问题和我当时选择的损失函数关系比较大。

    第一个公式应该是没问题:

    similarity(s1,s2) = exp(- L1 norm(encoder(s1) – encoder(s2))).  ————公式(1

     

    但是下面这个公式:

    Probability(s1,s2 has the same meaning)= sigmoid(w*similarity(s1,s2)+b)--公式(2)  这个从道理上好像就不太通;

     

    在实践中,发现如果用这个公式 的话,(训练集)准确率就一直在33%左右,根本就没有变好的趋势。为了确认是不是训练时间不够长造成的,训练了大约200个 epoches,准确率都没有上升。

     

    后来不用上面的公式了,而是bypass了公式(2)直接令

    Probability(s1,s2 has the same meaning)=  similarity(s1,s2) ,测试结果就是第1条所说。

     

    3,还有一些其它的细节吧

    batch-size 目前取的是8192,是不是太多了啊?老师原来用的batch-size有这么多吗?

    也试过,如果用比较小的batch-size的话,发现准确率跳动地比较厉害了。

     

    4,上周老师评论里面,关于正负样本的比例,唐老师的意思,是每个batch内部正负样本比例都要是50%呢,还是不同的batch之间的正负样本比例比较稳定、别忽高忽低就可以呢?

    或者是其它意思?

     

    “句子的长度你取了多少?我取得是55,也取过60”

    我记得我把所有的train.csv里面的句子,都padding 到了train.csv里面最长的那句话的长度。刚才打印了一下,应该139。所以,55指的是?

     

    结合前面两条说的,看来损失函数对模型的表现影响比较大,我可能打算先改进一下损失函数。尝试上周唐老师所说的对比损失(Contrastive Loss )。

    http://blog.****.net/autocyz/article/details/53149760

     

    或者老师有什么别的建议吗?

     

     回复
  • Quora Question Pairs 思路记录
    14楼Lynn  02-10

    这里面有个比较严重的问题,就是句子长度的问题取句子最长为139,在这个里面90%以上的句子长度都不到60,如果句子的长度取139,那么就是在句子后面拼凑了大量的无用信息,虽然说lstm或gru能够在训练当中学习到较长的时间序列的信息,但是注意,如果时间序列的长度过长LSTM也是很无力的(如果只取LSTM最后一个单元的输出)。

    参考的解决方法:在训练集当中,每个句子的长度是不固定的,在你的代码当中,需要的是固定长度的输入,所以这个时候需要你将所有的句子处理成长度一样,所以这个时候需要人为的指定句子的长度,你在预处理当中应该是有这个参数的,所以将这个参数设置成50,然后再进行处理和训练,你再看看结果。

     收起
    • Quora Question Pairs 思路记录
      我没有使用截断的方法,我统计每句话的精确长度L后,把RNN的每L的output给提取出来了;也就是说,batch里面的不同行抽取的的last state位置是不一样的
Quora Question Pairs 思路记录
15楼Lynn  02-10

batch_size取的是1500,8912是否过大?如果mini_batch取得过大,会是的它的方向探索性不是很强,有没有考虑过这个问题?

当然这只是小问题,大问题在于8912的话,会使得你的代码非常消耗内存,加大了每一轮的计算量,减慢运行速度。

 收起
  • Quora Question Pairs 思路记录
    对,我重新了解了一下stocastic gradient descent 方法,认为您说的很有道理,您的batch-size是1500吧,我现在设的是2048
Quora Question Pairs 思路记录
16楼Lynn  02-10

还有你说的波动的原因是不是和学习率有关系?你的学习率是否过大? 

一般来说,如果你的训练结果波动很大,这个时候你需要考虑减小你的学习率。

 收起
  • Quora Question Pairs 思路记录
    之前的波动应该是架构的原因,我在17楼写了。换了架构后,训练的前期可以看到loss在小幅波动中下降的现象,训练到后期因为就稳定,只剩下类似于随机上下波动的现象了。但是有时训练的太多了,反正效果会变差,即使是训练集效果也会变差? 这正常吗? 我猜测因为mini-batch算的梯度不完全准确,训练时间一长可能跳出局部最小值的概率变大,跑到别处去了
Quora Question Pairs 思路记录
17楼旷野的季节  02-25

谢谢唐老师的回复,过节回复晚了:)

1. 对之前loss不能收敛问题的解决

发现之前很多次说的模型学不到东西,可能是神经网络架构方面的问题

为了完整性,再画一下,之前的架构是下面这个样子:

注:图中的“abs"指的是对两个input相减后取绝对值

Quora Question Pairs 思路记录

                                                                  架构一

后面与唐老师沟通后,参考唐老师的方案,改成了下面的架构:

Quora Question Pairs 思路记录

                                                                                 架构二

后来我思考为什么一开始的架构不行,把上面的两种架构整合成了下面的架构:

Quora Question Pairs 思路记录

                                                                     架构三

注:图中的“abs"指的是对两个input相减后取绝对值

架构三与架构二的区别,是在原始特征之后加了一层 ”对应位置特征相减“ 的操作。

架构三与架构一的主要区别,是去掉了所有abs之后的加和操作。

目前经过尝试,在train && dev set 上架构三比架构二要好一些,当然最终效果如何还要在kaggle网站上提交结果看一下。

 

2. 为什么一开始架构不行的简要想法。

可能是”求和“以后,不同的”特征“的信息丢失了一些?而这个”求和“到底有什么含义吗?受word2vec的影响, 一开始,我认为GRU的输出应该是一句话映射在语义空间的”话的意思“,这样如果两句话s1, s2表达的意思相同,那么这两个映射点位置应该是相近的才对。 于是才会有之前所做的求Manhattan Distance的做法,但是现在看来这种做法可能并不合适?

但是为什么word2vec ,可能认为意思相近的词得到的词向量会比较接近呢?

这是因为意思相近的词,在上下文窗口中出现的概率比较高,训练算法自动会把窗口里的词的词向量拉近,把不在窗口里的词的词向量拉远,从而造成了相近的词的词向量较接近。

也许GRU的输出应该理解成”特征“更合适一些。

之前也问过唐老师,”为什么RNN的输出能当成特征直接用呢“ 简要记录一下唐老师的回答,

"siamese网络两个部分算出来的最终的结果,无论里面采用的CNN,LSTM,BLSTM,甚至是全连接网络,这些结果可以看成是高阶特征。在很多论文当中,一般来说就是在这些网络上面下文章,希望能够得到更有表达能力的特征。

只是这些特征不能够用语言解释

在传统机器学习中,很多情况下特征是可以解释的,这个也是神经网络的劣势,可解释性不是很强。

举个例子,word2vec训练出来的128位的向量,这128维的向量都可以看成是这个词汇的特征,只是这个特征不具有很强的解释性。"

所以其实解释了前面我所说的,两个词的意思相近,词向量接近,就是各个特征相近。。。

 

3, 那么现在这个网络能够学习到训练集的信息么?

这个训练集有点特点,是正负样本比较不一样,大约正样本37%,负样本63% 所以单凭正确率无法判断模型是否真的学到了东西。比如说模型把所有的样本都判断成负样本,此时正确率就是63%,看着是大于50%了,像是比胡乱猜要好,但是其实模型什么都没有学到。

回顾一下之前课程学到的东西,

Quora Question Pairs 思路记录

不解释,上实验结果,每一行是一个mini-batch的evaluate结果(每次先在一个mini-batch上evaluate ,然后loss opt,然后换一个batch,重复)

architec is two-feature-substrate

batch_i(th) = 0

epoch_i = 0.0

batch_size = 2048

data_file = train.csv

neural-network type is gru

keep-drop-prob = 0.5

precision = 0.383912235498 recall = 0.549738228321      recall 约= 50%, 此时分类器像是瞎猜 、precision是38%, 因为正样本的数量相对较小,所以precison不高。

precision = 0.310469299555 recall = 0.108448930085  recall变小,分类器把更多的样本都判定成为负例

precision = 0.300000011921 recall = 0.015306122601  recall继续变小

precision = 0.0 recall = 0.0            此时recall =0, 分类器一个正样本都识别不出来了

precision = 0.0 recall = 0.0

precision = nan recall = 0.0  可以看到,precison 变成了正无穷,原因是TP+FP=0, 即分类器把所有的样本都判断成了负例。

precision = nan recall = 0.0  重复好几个mini-batch

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0

precision = nan recall = 0.0  重复好几个mini-batch

precision = 0.20000000298 recall = 0.00272108847275  此时,recall 不再是0了 ,有一些正样本被正确地识别了出来

precision = 0.352941185236 recall = 0.0078125   recall 继续增大

precision = 0.428571432829 recall = 0.00757575780153   recall 继续增大

precision = 0.479999989271 recall = 0.0155844157562  recall 继续增大

precision = 0.555555582047 recall = 0.019430052489

precision = 0.584905683994 recall = 0.0418918915093

precision = 0.660000026226 recall = 0.0424710437655

precision = 0.714285731316 recall = 0.0604838691652

precision = 0.677419364452 recall = 0.0859481617808

precision = 0.726315796375 recall = 0.0875634551048

precision = 0.672727286816 recall = 0.0962288677692

precision = 0.701388895512 recall = 0.136856362224

precision = 0.69938647747 recall = 0.14267835021

precision = 0.707006394863 recall = 0.157446801662

precision = 0.658682644367 recall = 0.14030611515

precision = 0.72327041626 recall = 0.140931367874

precision = 0.617021262646 recall = 0.150845259428

precision = 0.617021262646 recall = 0.163610726595

precision = 0.615384638309 recall = 0.1892247051

precision = 0.645914375782 recall = 0.219576716423

precision = 0.663865566254 recall = 0.210106387734

precision = 0.613445401192 recall = 0.198100402951

precision = 0.684426248074 recall = 0.212198227644

precision = 0.62365591526 recall = 0.216957598925

precision = 0.665517270565 recall = 0.246487870812

precision = 0.649700582027 recall = 0.296448081732

precision = 0.680473387241 recall = 0.303030312061

precision = 0.663580238819 recall = 0.29614326357

precision = 0.680327892303 recall = 0.318007647991

precision = 0.649595677853 recall = 0.319205284119

precision = 0.632947981358 recall = 0.295148253441

precision = 0.630854010582 recall = 0.313698619604

precision = 0.659846544266 recall = 0.332903236151

precision = 0.639423072338 recall = 0.358008086681

precision = 0.66749382019 recall = 0.333746910095

precision = 0.573732733727 recall = 0.331557929516

precision = 0.640495896339 recall = 0.403645843267

precision = 0.656521737576 recall = 0.391699105501   recall 继续增大

LOG比较多,省略了

最终训练了大约56个epoch(RUN了2天多吧)

precision = 0.703311264515 recall = 0.708000004292

precision = 0.691078543663 recall = 0.691999971867

precision = 0.714480876923 recall = 0.665394425392

precision = 0.671562075615 recall = 0.682496607304

precision = 0.701492547989 recall = 0.66882276535

precision = 0.707571804523 recall = 0.702983140945

precision = 0.678861796856 recall = 0.67702704668

precision = 0.697333335876 recall = 0.693633973598

precision = 0.689961910248 recall = 0.711664497852

precision = 0.686351716518 recall = 0.674838721752

 

在训练集中recall 大约70%, precision 也大约70%, accuracy 这次跑没有打印,可能在75%左右吧。

再说验证集。
一共有409600个sample(把原始train.csv复制扩大了几K个样本)

train-set : 307200

dev-set : 105600

average accuracy = 0.7539746

average precision = 0.67941993

average recall = 0.60883856

有点差啊?

注:神经网络里面防止过拟合比较常用的是dropout,放假期间尝试过dropout_keep_rate=1,发现train和dev 二者的accuracy 差距明显变大(当时还没有评估precision && recall)。加了dropout后,至少在accuracy上两者的差值明显变小了,但是train set 的准确率也没有不加dropout 时高了,所以最终似乎也没有发现dev set 的准确性变高。也许是我现在的程序还比较粗糙,dropout这个事件后续再尝试。目前dropout_keep_rate = 0.5。

4, 经过上面的分析,可以认为模型已经学到东西了:)?

先在kaggle上提交一下吧,看看结果怎么样,能排在什么水平

我的下一步的改进思路,基本按照机器学习的正常流程来说:

1) 数据清洗

      老外用quora很多都是在手机上吧?键盘那么小,拼错单词的情况可能会有吧?(不知道会不会单词检查)。那么对于不在glove字典中出现的单词,也许是由于拼字错误造成的,也许是一些专业性比较强的词、或者是自行创造的某些生活词汇。如果能在glove字典中找到非常相似的词,则认为是拼写错误,那么就用glove字典中出现的词来替代问题中的词。

2)词向量是不是可以重新训练? 也就是说,只是把glove的词向量当成是初始的词向量,而非固定的词向量。

3)特征工程

        这个是目前一直没有考虑的问题。是不是可以考虑用下面的这些特征

       1) 两句话的最长公共子序列的长度 如果LCS 比较大,是不是意思一样的概率就会比较大?

       2) 两句话的长度差值。 如果一句话很长,另外一句话非常短,是不是意思相同的概率会比较低?

       3)主题模型?

 

4) 换不同的模型试试

现在用的是GRU,如果换成LSTM, BLSTM呢?

5) 换损失函数试试 比如之前提到的对比损失

6) 是不是可以在simense网络后,加一个随机森林试试? 自己瞎想的:

意思是分两轮,第一论用softmax训练出来一个simense网络,等训练了足够轮之后,认为simense网络里面的参数都稳定了,此时特征都得到了,然后simense 网络就不动了;然后把softmax去掉,替换成random forest,开始第二轮单独训练random forest ,最终用ramdom forest的输出当成最终的预测值。

7) 数据随机扩展。

如果s1, s2意思相同的话,那么 s2, s1 的意思也是相同的。因此可以把一个y=1 的样本(s1, s2, y )送进模型的时候,随机决定是送进(s1, s2, y ) 还是  (s2, s1, y)。  

目前的想法大概就是这些,如有问题欢迎指正!

 

 

 

  

 回复
Quora Question Pairs 思路记录
18楼旷野的季节  03-13

经过与唐老师的沟通,目前思路如下:

1) 参考文档:

http://web.stanford.edu/class/cs224n/reports/2759336.pdf

“ 你之前将抽取出来的两个高阶向量直接连续起来,它增加了两个信息,一个是r1-r2,一个是r1.*r2,

将这四个向量连接起来,这个应该相对于目前的网络结构得到一个挺好的优化。”

我模拟了一下这个实验,accuracy 大概能到83%左右,recall应该也比这个要高一些。可能预处理做的比这个文档上做的更多一些。

然后还有一个,参考一下下面的这些文档。

这3个博客是一个系列,最后一个链接涉及到了很多自然语言理解的问题

1.https://explosion.ai/blog/quora-deep-text-pair-classification#example-neural-network

2.https://explosion.ai/blog/supervised-similarity-siamese-cnn

3.https://explosion.ai/blog/

 

2) “词向量改成可以训练的,这个非常重要”

这个一定要能训练,因为不能的数据集有不同的词语分布,也导致(不同的数据集的)向量分布是不一样的。可以训练的话会导致这个词向量是最符合我们这个数据集要求
 

3,还有一点是keep_dropout_prob ,我现在是0。5,可以把这个参数先取消,暂时先不做弃权,应该先把不做弃权的效果提上去。若训练集的效果已经提高上去,而训练集的(准确率或loss)和测试集(准确或loss)的准确率区别比较大了,再来做弃权。相当于我现在一上来就做正则,此时我并不知道现在不知道模型处于什么状态,能达到什么效果,是不是已经过拟合。只有当模型已经出现过拟合了,再来做正则。

 

4,就我目前的效果来说,先不用考虑CELL是什么。目前还不用考虑是GRU,LSTM,双向LSTM,比如我就用LSTM,先把效果提上去,提到和别人一样,比如别人是83%,我是79%,此时可以再换CELL。对于单个模型来说,GRU,LSTM,的差别没有大到那种程度。

5,数据清洗——可以先不考虑。当处理个大概以后,再说。先把(结果)提上去。   怎么提呢,比如网络架构。要确定网络架构一定是对的,比如(什么东西,training or dev ?)能到80%?

6, 特征工程,LCSor 长度差值,or 主题模型可以先不考虑(因为对于短句子来说,主题是比较难做的)很少有人做LDA。。先不用考虑这个

7,但是当训练结果到达一定程度后,考虑LCS or 长度差值,可以再数据清洗,拼写错误,语法错误,等。就目前来说,先把上面提到的这些做好,网络结构稍微变一下就好。

8,损失函数——“前面提到的对比损失暂时不用改。先把网络改一下,网络结构改好了后,先看看效果。就目前来说,不同损失函数的差别没有那么大”

9, 分类器直接用全连接网络就可以了,先不用把神经网络提取出来的模型送到Random Forest, 这种分类器。"好多硕士的垃圾论文都是这么干的”

10, kaggle上写给的不是准确率,是以logloss ,以logloss 为判断结果,

11,拿测试集调参是没有问题的

12,跑50轮没有必要,跑的太多,跑的太多会产生非常严重的过拟合,有时要在代码中加入画图的功能,tensorboard,准确率、召回率、loss 都能打印出来,动态变化的。可以看测试集,什么时候收敛都可以看出来,可以看什么时候拟合效果是最好的。如果tensorboard费劲,也可以看loss。 训练集的准确率和loss 到最后不会产生大的波动,但是测试集的准确率可能不好有太大变化,但是loss会有一个特别大的提升(To be checked)。

12,提交给Kaggle上的是概率。是softmax/sigmoid上的概率。提交0-1结果是有问题的。

13,用了一下交叉验证,但是用交叉验证或不用,差别没有那么大,一开始进不需要使用。

14,“用测试集上调参用什么指标?” 用logloss 就可以。

 

 

 
 回复
Quora Question Pairs 思路记录
19楼旷野的季节  03-16

1,这周的工作,学习了tensorboard的使用:

为了和词向量Trainalbe的结果做下对比,因此本篇的结果,是词向量不可训练。下一篇再上词向量可训练的。另外此时keep_dropout_prob=1 。目前是为了看一下模型现在处于的状态。

把超参数说明一下:

RUN_MODEL=two-feature-substrate   高阶特征的组合方式是abs(r1-r2)

BATCH_SIZE=2048                                       一个batch包含的样本个数
DROPOUT_KEEP_PROB=1.0                   不做弃权
EMBEDDING_TRAINABLE=False             词向量不可训练
L2_REG_LAMBDA=0.0                                 不做正则
NUMBER_UNITS=50                                    RNN的cell个数
TRAIN_SAMPLE_PERCENTAGE=0.75     train/total 比例
TRAIN_SIZE=307200                                    训练集的样本个数

下面的图片是训练集,而文字描述是测试集:

Quora Question Pairs 思路记录

Train loss:    0.36 :  DEV loss:  0.5330878 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Quora Question Pairs 思路记录

而测试集的情况是:

Train accuracy : 83% Dev accuracy :  75.68 %

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Quora Question Pairs 思路记录

而测试集的情况是:

Train precison: 77%  Dev precision: 68.22 %

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Quora Question Pairs 思路记录

而测试集的情况是:

Train recall : 77% Test recall:  61.5%

这四个指标的Train && Dev 之间的差距都比较大,因此,我认为现在模型处于严重的过拟合状态。应该考虑加正则或者drop手段来防止过拟合。

 

 

 回复
Quora Question Pairs 思路记录
20楼旷野的季节  03-17

与前一篇的区别,是词向量是可以训练的。正如唐老师所说,词向量一定要是可以训练的,效果有了很大的变化:

还是先看训练集,结果好的不得了. 超参数是这些:

RUN_MODEL=two-feature-substrate-trainable                        -- 模型的高阶特征处理方式: abs(r1-r2)
BATCH_SIZE=2048                                                                              
DROPOUT_KEEP_PROB=1.0                                                           --不做弃权
EMBEDDING_TRAINABLE=True                                                      --词向量可训练
L2_REG_LAMBDA=0.0                                                                        --损失函数(cross-entropy)不做正则
NUMBER_UNITS=50                                                                           --一个RNN模型内部的hidden-state 个数
RNN_TYPE=gru                                                                                    --cell 类型:GRU
TRAIN_SAMPLE_PERCENTAGE=0.75                                            --train/total 比例

训练集loss 能下降到0.1以下:

还有个现象,loss会在每轮(一轮包含150个mini-batch)开始的地方突然有个很大的下降,但是在每轮中间的地方loss 会有缓慢的提升,然后在下一轮开始的地方再突然下降一下子。图中突然下降了几次,就代表训练了几轮。

不只是loss,下面的accuracy, recall, precison 都有这个现象。why?

Quora Question Pairs 思路记录

 

训练集accuracy 提升到97% 左右。还是在每epoch开头的地方突然上升。所以出现下面这样的波动形式。Quora Question Pairs 思路记录

 

训练集recall 最后能提到97% 左右。

Quora Question Pairs 思路记录

训练集precision 能在95%左右。

Quora Question Pairs 思路记录

 

综上,改成词向量可以训练之后,神经网络在训练集上的表现有了巨大的提升。

但是在测试集上的表现就不那么好了。

@ 后面的数字是min-batch 个数, 1 epoch = 150 mini-batches

 

加粗的几行是我认为loss 最好的几次迭代,大约是1个epoch的位置

DEV loss: 0.6659 ; accuracy: 0.6341 ; recall: 0.0088 ; precison: 0.3312 ; [email protected] 0
DEV loss: 0.6705 ; accuracy: 0.6372 ; recall: 0.0000 ; precison: nan ; [email protected] 10
DEV loss: 0.6531 ; accuracy: 0.6360 ; recall: 0.0174 ; precison: 0.4557 ; [email protected] 20
DEV loss: 0.5838 ; accuracy: 0.7217 ; recall: 0.4242 ; precison: 0.6891 ; [email protected] 50
DEV loss: 0.5438 ; accuracy: 0.7354 ; recall: 0.4776 ; precison: 0.6976 ; [email protected] 60
DEV loss: 0.5235 ; accuracy: 0.7445 ; recall: 0.4851 ; precison: 0.7191 ; [email protected] 70
DEV loss: 0.5229 ; accuracy: 0.7465 ; recall: 0.4742 ; precison: 0.7326 ; [email protected] 80
DEV loss: 0.5157 ; accuracy: 0.7517 ; recall: 0.5194 ; precison: 0.7180 ; [email protected] 90
DEV loss: 0.5093 ; accuracy: 0.7561 ; recall: 0.5289 ; precison: 0.7240 ; [email protected] 100
DEV loss: 0.5049 ; accuracy: 0.7633 ; recall: 0.5578 ; precison: 0.7258 ; [email protected] 110
DEV loss: 0.4961 ; accuracy: 0.7668 ; recall: 0.5774 ; precison: 0.7235 ; [email protected] 120
DEV loss: 0.5035 ; accuracy: 0.7675 ; recall: 0.5558 ; precison: 0.7382 ; [email protected] 130
DEV loss: 0.5041 ; accuracy: 0.7700 ; recall: 0.5509 ; precison: 0.7483 ; [email protected] 140
DEV loss: 0.4950 ; accuracy: 0.7728 ; recall: 0.5776 ; precison: 0.7389 ; [email protected] 150

DEV loss: 0.5051 ; accuracy: 0.7743 ; recall: 0.6171 ; precison: 0.7203 ; [email protected] 160
DEV loss: 0.5158 ; accuracy: 0.7724 ; recall: 0.6085 ; precison: 0.7203 ; [email protected] 170
DEV loss: 0.5139 ; accuracy: 0.7694 ; recall: 0.6014 ; precison: 0.7170 ; [email protected] 180
DEV loss: 0.5311 ; accuracy: 0.7699 ; recall: 0.5740 ; precison: 0.7335 ; [email protected] 190
DEV loss: 0.5285 ; accuracy: 0.7698 ; recall: 0.5702 ; precison: 0.7354 ; [email protected] 200
DEV loss: 0.5063 ; accuracy: 0.7774 ; recall: 0.6331 ; precison: 0.7193 ; [email protected] 210
DEV loss: 0.5225 ; accuracy: 0.7733 ; recall: 0.6100 ; precison: 0.7218 ; [email protected] 220
DEV loss: 0.5283 ; accuracy: 0.7746 ; recall: 0.5955 ; precison: 0.7328 ; [email protected] 230
DEV loss: 0.5235 ; accuracy: 0.7766 ; recall: 0.5916 ; precison: 0.7401 ; [email protected] 240
DEV loss: 0.5041 ; accuracy: 0.7798 ; recall: 0.6475 ; precison: 0.7177 ; [email protected] 250
DEV loss: 0.5089 ; accuracy: 0.7818 ; recall: 0.6295 ; precison: 0.7311 ; [email protected] 260

DEV loss: 0.5253 ; accuracy: 0.7764 ; recall: 0.5726 ; precison: 0.7514 ; [email protected] 270
DEV loss: 0.5222 ; accuracy: 0.7777 ; recall: 0.5740 ; precison: 0.7540 ; [email protected] 280
DEV loss: 0.5385 ; accuracy: 0.7776 ; recall: 0.5600 ; precison: 0.7634 ; [email protected] 290
DEV loss: 0.5249 ; accuracy: 0.7796 ; recall: 0.5941 ; precison: 0.7461 ; [email protected] 300
DEV loss: 0.5537 ; accuracy: 0.7815 ; recall: 0.6159 ; precison: 0.7381 ; [email protected] 310
DEV loss: 0.5536 ; accuracy: 0.7813 ; recall: 0.6280 ; precison: 0.7309 ; [email protected] 320
DEV loss: 0.5699 ; accuracy: 0.7792 ; recall: 0.6148 ; precison: 0.7331 ; [email protected] 330

DEV loss: 0.5710 ; accuracy: 0.7779 ; recall: 0.6352 ; precison: 0.7192 ; [email protected] 340
DEV loss: 0.5712 ; accuracy: 0.7768 ; recall: 0.6316 ; precison: 0.7188 ; [email protected] 350
DEV loss: 0.5867 ; accuracy: 0.7749 ; recall: 0.6006 ; precison: 0.7306 ; [email protected] 360
DEV loss: 0.5844 ; accuracy: 0.7773 ; recall: 0.6140 ; precison: 0.7290 ; [email protected] 370
DEV loss: 0.5889 ; accuracy: 0.7761 ; recall: 0.6173 ; precison: 0.7244 ; [email protected] 380
DEV loss: 0.5766 ; accuracy: 0.7761 ; recall: 0.6131 ; precison: 0.7266 ; [email protected] 390
DEV loss: 0.6048 ; accuracy: 0.7731 ; recall: 0.5612 ; precison: 0.7499 ; [email protected] 400
DEV loss: 0.5857 ; accuracy: 0.7776 ; recall: 0.5921 ; precison: 0.7424 ; [email protected] 410
DEV loss: 0.5886 ; accuracy: 0.7756 ; recall: 0.5774 ; precison: 0.7464 ; [email protected] 420
DEV loss: 0.5653 ; accuracy: 0.7805 ; recall: 0.6122 ; precison: 0.7380 ; [email protected] 430
 DEV loss: 0.5659 ; accuracy: 0.7827 ; recall: 0.6333 ; precison: 0.7314 ; [email protected] 440
DEV loss: 0.6109 ; accuracy: 0.7763 ; recall: 0.5629 ; precison: 0.7579 ; [email protected] 450
DEV loss: 0.6445 ; accuracy: 0.7774 ; recall: 0.6011 ; precison: 0.7366 ; [email protected] 460
DEV loss: 0.6201 ; accuracy: 0.7810 ; recall: 0.6366 ; precison: 0.7257 ; [email protected] 470
DEV loss: 0.6452 ; accuracy: 0.7789 ; recall: 0.6210 ; precison: 0.7291 ; [email protected] 480
DEV loss: 0.6480 ; accuracy: 0.7775 ; recall: 0.6272 ; precison: 0.7227 ; [email protected] 490
DEV loss: 0.6481 ; accuracy: 0.7769 ; recall: 0.6292 ; precison: 0.7201 ; [email protected] 500
DEV loss: 0.6588 ; accuracy: 0.7776 ; recall: 0.6170 ; precison: 0.7282 ; [email protected] 510
DEV loss: 0.6349 ; accuracy: 0.7803 ; recall: 0.6447 ; precison: 0.7200 ; [email protected] 520
DEV loss: 0.6468 ; accuracy: 0.7786 ; recall: 0.6313 ; precison: 0.7228 ; [email protected] 530
DEV loss: 0.6670 ; accuracy: 0.7768 ; recall: 0.6149 ; precison: 0.7274 ; [email protected] 540
DEV loss: 0.6969 ; accuracy: 0.7715 ; recall: 0.5670 ; precison: 0.7420 ; [email protected] 550
DEV loss: 0.6397 ; accuracy: 0.7818 ; recall: 0.6284 ; precison: 0.7320 ; [email protected] 560
DEV loss: 0.6683 ; accuracy: 0.7772 ; recall: 0.6120 ; precison: 0.7298 ; [email protected] 570
DEV loss: 0.6534 ; accuracy: 0.7753 ; recall: 0.5944 ; precison: 0.7353 ; [email protected] 580
DEV loss: 0.6742 ; accuracy: 0.7757 ; recall: 0.5806 ; precison: 0.7445 ; [email protected] 590
DEV loss: 0.6560 ; accuracy: 0.7773 ; recall: 0.5958 ; precison: 0.7393 ; [email protected] 600
DEV loss: 0.7081 ; accuracy: 0.7763 ; recall: 0.5930 ; precison: 0.7386 ; [email protected] 610
DEV loss: 0.6917 ; accuracy: 0.7772 ; recall: 0.6255 ; precison: 0.7229 ; [email protected] 620
DEV loss: 0.7018 ; accuracy: 0.7785 ; recall: 0.6231 ; precison: 0.7271 ; [email protected] 630
DEV loss: 0.7143 ; accuracy: 0.7763 ; recall: 0.6365 ; precison: 0.7154 ; [email protected] 640
DEV loss: 0.7307 ; accuracy: 0.7764 ; recall: 0.6059 ; precison: 0.7315 ; [email protected] 650
DEV loss: 0.7487 ; accuracy: 0.7763 ; recall: 0.5971 ; precison: 0.7363 ; [email protected] 660
DEV loss: 0.7326 ; accuracy: 0.7756 ; recall: 0.6419 ; precison: 0.7111 ; [email protected] 670
DEV loss: 0.7562 ; accuracy: 0.7755 ; recall: 0.5941 ; precison: 0.7361 ; [email protected] 680
DEV loss: 0.7530 ; accuracy: 0.7746 ; recall: 0.5833 ; precison: 0.7399 ; [email protected] 690
DEV loss: 0.7605 ; accuracy: 0.7730 ; recall: 0.5841 ; precison: 0.7354 ; [email protected] 700
DEV loss: 0.7301 ; accuracy: 0.7743 ; recall: 0.6192 ; precison: 0.7194 ; [email protected] 710
DEV loss: 0.7036 ; accuracy: 0.7807 ; recall: 0.6542 ; precison: 0.7164 ; [email protected] 720
DEV loss: 0.7296 ; accuracy: 0.7731 ; recall: 0.6245 ; precison: 0.7142 ; [email protected] 730
DEV loss: 0.7083 ; accuracy: 0.7776 ; recall: 0.6297 ; precison: 0.7218 ; [email protected] 740
DEV loss: 0.7306 ; accuracy: 0.7750 ; recall: 0.6092 ; precison: 0.7265 ; [email protected] 750
DEV loss: 0.7493 ; accuracy: 0.7791 ; recall: 0.6185 ; precison: 0.7311 ; [email protected] 760
DEV loss: 0.7832 ; accuracy: 0.7747 ; recall: 0.6100 ; precison: 0.7252 ; [email protected] 770
DEV loss: 0.7836 ; accuracy: 0.7777 ; recall: 0.6179 ; precison: 0.7281 ; [email protected] 780
DEV loss: 0.8177 ; accuracy: 0.7737 ; recall: 0.6059 ; precison: 0.7249 ; [email protected] 790
DEV loss: 0.7961 ; accuracy: 0.7770 ; recall: 0.6333 ; precison: 0.7185 ; [email protected] 800
DEV loss: 0.8156 ; accuracy: 0.7740 ; recall: 0.6264 ; precison: 0.7150 ; [email protected] 810
DEV loss: 0.8091 ; accuracy: 0.7749 ; recall: 0.6227 ; precison: 0.7190 ; [email protected] 820
DEV loss: 0.8161 ; accuracy: 0.7732 ; recall: 0.6260 ; precison: 0.7133 ; [email protected] 830
DEV loss: 0.7899 ; accuracy: 0.7778 ; recall: 0.6267 ; precison: 0.7235 ; [email protected] 840
DEV loss: 0.8163 ; accuracy: 0.7748 ; recall: 0.6033 ; precison: 0.7288 ; [email protected] 850
DEV loss: 0.8356 ; accuracy: 0.7717 ; recall: 0.5829 ; precison: 0.7329 ; [email protected] 860
DEV loss: 0.8385 ; accuracy: 0.7724 ; recall: 0.5911 ; precison: 0.7298 ; [email protected] 870
DEV loss: 0.7942 ; accuracy: 0.7769 ; recall: 0.6284 ; precison: 0.7206 ; [email protected] 880
DEV loss: 0.7872 ; accuracy: 0.7755 ; recall: 0.6318 ; precison: 0.7157 ; [email protected] 890
DEV loss: 0.8127 ; accuracy: 0.7751 ; recall: 0.6028 ; precison: 0.7300 ; [email protected] 900
DEV loss: 0.8680 ; accuracy: 0.7722 ; recall: 0.5751 ; precison: 0.7387 ; [email protected] 910
DEV loss: 0.8479 ; accuracy: 0.7749 ; recall: 0.6110 ; precison: 0.7250 ; [email protected] 920
DEV loss: 0.8654 ; accuracy: 0.7768 ; recall: 0.6170 ; precison: 0.7262 ; [email protected] 930
DEV loss: 0.8799 ; accuracy: 0.7737 ; recall: 0.6088 ; precison: 0.7233 ; [email protected] 940
DEV loss: 0.8527 ; accuracy: 0.7752 ; recall: 0.6235 ; precison: 0.7194 ; [email protected] 950
DEV loss: 0.8872 ; accuracy: 0.7745 ; recall: 0.6102 ; precison: 0.7244 ; [email protected] 960
DEV loss: 0.8974 ; accuracy: 0.7709 ; recall: 0.6066 ; precison: 0.7178 ; [email protected] 970
DEV loss: 0.8966 ; accuracy: 0.7715 ; recall: 0.6148 ; precison: 0.7152 ; [email protected] 980
DEV loss: 0.9059 ; accuracy: 0.7710 ; recall: 0.6144 ; precison: 0.7141 ; [email protected] 990
DEV loss: 0.8862 ; accuracy: 0.7730 ; recall: 0.6271 ; precison: 0.7124 ; [email protected] 1000
DEV loss: 0.8957 ; accuracy: 0.7738 ; recall: 0.6306 ; precison: 0.7124 ; [email protected] 1010
DEV loss: 0.8694 ; accuracy: 0.7731 ; recall: 0.6358 ; precison: 0.7086 ; [email protected] 1020
DEV loss: 0.8972 ; accuracy: 0.7709 ; recall: 0.5963 ; precison: 0.7234 ; [email protected] 1030
DEV loss: 0.8937 ; accuracy: 0.7729 ; recall: 0.5862 ; precison: 0.7341 ; [email protected] 1040
DEV loss: 0.8588 ; accuracy: 0.7716 ; recall: 0.6160 ; precison: 0.7148 ; [email protected] 1050
DEV loss: 0.9108 ; accuracy: 0.7722 ; recall: 0.6133 ; precison: 0.7175 ; [email protected] 1060
DEV loss: 0.9231 ; accuracy: 0.7712 ; recall: 0.6160 ; precison: 0.7140 ; [email protected] 1070
DEV loss: 0.9258 ; accuracy: 0.7721 ; recall: 0.6234 ; precison: 0.7123 ; [email protected] 1080
DEV loss: 0.9140 ; accuracy: 0.7718 ; recall: 0.6518 ; precison: 0.6988 ; [email protected] 1090
DEV loss: 0.9197 ; accuracy: 0.7745 ; recall: 0.6333 ; precison: 0.7129 ; [email protected] 1100
DEV loss: 0.9350 ; accuracy: 0.7713 ; recall: 0.6194 ; precison: 0.7125 ; [email protected] 1110
DEV loss: 0.9336 ; accuracy: 0.7753 ; recall: 0.6355 ; precison: 0.7137 ; [email protected] 1120
DEV loss: 0.9476 ; accuracy: 0.7710 ; recall: 0.6301 ; precison: 0.7068 ; [email protected] 1130
DEV loss: 0.9473 ; accuracy: 0.7719 ; recall: 0.6193 ; precison: 0.7139 ; [email protected] 1140
DEV loss: 1.0057 ; accuracy: 0.7704 ; recall: 0.5846 ; precison: 0.7286 ; [email protected] 1150
DEV loss: 0.9972 ; accuracy: 0.7719 ; recall: 0.5840 ; precison: 0.7328 ; [email protected] 1160
DEV loss: 0.9716 ; accuracy: 0.7715 ; recall: 0.6060 ; precison: 0.7198 ; [email protected] 1170
DEV loss: 0.9594 ; accuracy: 0.7731 ; recall: 0.6132 ; precison: 0.7199 ; [email protected] 1180
DEV loss: 0.9689 ; accuracy: 0.7730 ; recall: 0.5972 ; precison: 0.7278 ; [email protected] 1190
DEV loss: 0.9508 ; accuracy: 0.7709 ; recall: 0.6027 ; precison: 0.7200 ; [email protected] 1200
DEV loss: 0.9960 ; accuracy: 0.7695 ; recall: 0.5949 ; precison: 0.7206 ; [email protected] 1210
DEV loss: 0.9898 ; accuracy: 0.7696 ; recall: 0.6113 ; precison: 0.7126 ; [email protected] 1220
DEV loss: 1.0158 ; accuracy: 0.7668 ; recall: 0.5986 ; precison: 0.7126 ; [email protected] 1230
DEV loss: 0.9878 ; accuracy: 0.7729 ; recall: 0.6259 ; precison: 0.7129 ; [email protected] 1240
DEV loss: 1.0076 ; accuracy: 0.7689 ; recall: 0.6303 ; precison: 0.7019 ; [email protected] 1250
DEV loss: 1.0095 ; accuracy: 0.7706 ; recall: 0.6357 ; precison: 0.7032 ; [email protected] 1260
DEV loss: 1.0291 ; accuracy: 0.7692 ; recall: 0.6103 ; precison: 0.7121 ; [email protected] 1270
DEV loss: 1.0177 ; accuracy: 0.7688 ; recall: 0.6104 ; precison: 0.7112 ; [email protected] 1280
DEV loss: 1.0118 ; accuracy: 0.7724 ; recall: 0.6133 ; precison: 0.7181 ; [email protected] 1290
DEV loss: 1.0196 ; accuracy: 0.7729 ; recall: 0.6320 ; precison: 0.7100 ; [email protected] 1300
DEV loss: 1.0118 ; accuracy: 0.7725 ; recall: 0.6272 ; precison: 0.7114 ; [email protected] 1310
DEV loss: 1.0268 ; accuracy: 0.7683 ; recall: 0.6026 ; precison: 0.7140 ; [email protected] 1320
DEV loss: 1.0056 ; accuracy: 0.7719 ; recall: 0.6126 ; precison: 0.7171 ; [email protected] 1330
DEV loss: 0.9959 ; accuracy: 0.7699 ; recall: 0.6298 ; precison: 0.7044 ; [email protected] 1340
DEV loss: 0.9999 ; accuracy: 0.7693 ; recall: 0.6238 ; precison: 0.7058 ; [email protected] 1350
DEV loss: 1.0659 ; accuracy: 0.7672 ; recall: 0.5919 ; precison: 0.7169 ; [email protected] 1360
DEV loss: 1.0352 ; accuracy: 0.7720 ; recall: 0.6186 ; precison: 0.7144 ; [email protected] 1370
DEV loss: 1.0618 ; accuracy: 0.7720 ; recall: 0.6082 ; precison: 0.7196 ; [email protected] 1380
DEV loss: 1.0594 ; accuracy: 0.7723 ; recall: 0.6082 ; precison: 0.7203 ; [email protected] 1390
DEV loss: 1.0625 ; accuracy: 0.7713 ; recall: 0.6135 ; precison: 0.7154 ; [email protected] 1400
DEV loss: 1.0484 ; accuracy: 0.7711 ; recall: 0.6214 ; precison: 0.7111 ; [email protected] 1410
DEV loss: 1.0742 ; accuracy: 0.7684 ; recall: 0.6077 ; precison: 0.7116 ; [email protected] 1420
DEV loss: 1.0538 ; accuracy: 0.7710 ; recall: 0.6298 ; precison: 0.7068 ; [email protected] 1430
DEV loss: 1.0473 ; accuracy: 0.7710 ; recall: 0.6262 ; precison: 0.7086 ; [email protected] 1440
DEV loss: 1.0861 ; accuracy: 0.7683 ; recall: 0.5924 ; precison: 0.7193 ; [email protected] 1450
DEV loss: 1.0943 ; accuracy: 0.7680 ; recall: 0.5950 ; precison: 0.7170 ; [email protected] 1460
DEV loss: 1.0661 ; accuracy: 0.7693 ; recall: 0.6275 ; precison: 0.7041 ; [email protected] 1470
DEV loss: 1.0624 ; accuracy: 0.7662 ; recall: 0.6073 ; precison: 0.7067 ; [email protected] 1480
DEV loss: 1.0819 ; accuracy: 0.7691 ; recall: 0.5919 ; precison: 0.7212 ; [email protected] 1490
DEV loss: 1.0587 ; accuracy: 0.7688 ; recall: 0.6016 ; precison: 0.7156 ; [email protected] 1500
DEV loss: 1.1026 ; accuracy: 0.7681 ; recall: 0.5976 ; precison: 0.7158 ; [email protected] 1510
DEV loss: 1.0929 ; accuracy: 0.7708 ; recall: 0.6197 ; precison: 0.7112 ; [email protected] 1520
DEV loss: 1.1367 ; accuracy: 0.7682 ; recall: 0.5863 ; precison: 0.7222 ; [email protected] 1530
DEV loss: 1.1140 ; accuracy: 0.7690 ; recall: 0.5962 ; precison: 0.7188 ; [email protected] 1540
DEV loss: 1.1122 ; accuracy: 0.7695 ; recall: 0.6075 ; precison: 0.7142 ; [email protected] 1550
DEV loss: 1.1027 ; accuracy: 0.7701 ; recall: 0.6246 ; precison: 0.7073 ; [email protected] 1560
DEV loss: 1.0887 ; accuracy: 0.7696 ; recall: 0.6323 ; precison: 0.7027 ; [email protected] 1570
DEV loss: 1.1285 ; accuracy: 0.7686 ; recall: 0.6307 ; precison: 0.7013 ; [email protected] 1580

DEV loss: 1.1198 ; accuracy: 0.7696 ; recall: 0.6143 ; precison: 0.7113 ; [email protected] 1590
DEV loss: 1.1425 ; accuracy: 0.7676 ; recall: 0.6001 ; precison: 0.7136 ; [email protected] 1600
DEV loss: 1.1145 ; accuracy: 0.7680 ; recall: 0.6187 ; precison: 0.7055 ; [email protected] 1610
DEV loss: 1.1620 ; accuracy: 0.7661 ; recall: 0.6014 ; precison: 0.7093 ; [email protected] 1620
DEV loss: 1.1395 ; accuracy: 0.7671 ; recall: 0.6028 ; precison: 0.7110 ; [email protected] 1630
DEV loss: 1.1194 ; accuracy: 0.7689 ; recall: 0.6141 ; precison: 0.7095 ; [email protected] 1640
DEV loss: 1.1028 ; accuracy: 0.7699 ; recall: 0.6187 ; precison: 0.7097 ; [email protected] 1650
DEV loss: 1.1536 ; accuracy: 0.7654 ; recall: 0.5890 ; precison: 0.7140 ; [email protected] 1660
DEV loss: 1.1395 ; accuracy: 0.7683 ; recall: 0.6080 ; precison: 0.7113 ; [email protected] 1670
DEV loss: 1.1600 ; accuracy: 0.7703 ; recall: 0.6085 ; precison: 0.7157 ; [email protected] 1680
DEV loss: 1.1918 ; accuracy: 0.7658 ; recall: 0.5858 ; precison: 0.7169 ; [email protected] 1690
DEV loss: 1.2008 ; accuracy: 0.7662 ; recall: 0.5822 ; precison: 0.7197 ; [email protected] 1700
DEV loss: 1.1987 ; accuracy: 0.7692 ; recall: 0.6003 ; precison: 0.7173 ; [email protected] 1710
DEV loss: 1.2023 ; accuracy: 0.7701 ; recall: 0.6110 ; precison: 0.7138 ; [email protected] 1720
DEV loss: 1.2142 ; accuracy: 0.7701 ; recall: 0.5901 ; precison: 0.7249 ; [email protected] 1730
DEV loss: 1.1778 ; accuracy: 0.7699 ; recall: 0.6045 ; precison: 0.7168 ; [email protected] 1740

能得到的信息有这么几个:

1, 训练的轮数太多的话,accuracy ,recall, preciosn 也许变化不太大,但是loss  会先下降随后一路上升

即使是test表现最好的第一轮未,

train loss = 0.34 dev loss = 0.49

,train && test 区别也比较大。可见目前模型处于严重的过拟合。

接下来先要解决一下模型的过拟合问题。

 

 回复
Quora Question Pairs 思路记录
21楼旷野的季节  24天前

Parameters:

参考了唐老师给出的参考资料

http://web.stanford.edu/class/cs224n/reports/2759336.pdf

神经网络的架构使用的是:

和这个架构唯一的区别,是把r1-r2 替换成了abs(r1-r2),

我一开始没有用四个向量拼接的方式,只是使用了abs(r1-r2);而如果仅仅用r1-r2,神经网络基本无法收敛。因此参考这篇文章时,我把四个向量里面的r1-r2 替换成了abs(r1-r2)。

目前的疑问有下面这些:

问题一: 如果词向量是可以训练的,该怎么训练呢?有下面这两种方式,哪种是正确的?

方式一: 用glove向量当成词向量的初始值,然后只是在训练时顺便把词向量做成"Trainable",如下面的代码:

            self.W = tf.get_variable(name='word_embedding', shape = self.word_emm
bedding.shape,dtype=tf.float32,
            initializer=tf.constant_initializer(self.word_embedding), trainable==
self.embedding_trainable)    使用glove向量当成W的初始值, 同时W的是可以根据loss做调整的,使用的是神经网络最后一层的tf.nn.softmax_cross_entropy_with_logits做损失函数

方式二: 使用word2vec程序,把traing.txt当成语料库,用CBOW or Skip-Gram模型来学习词向量。

然后学习到词向量之后,再拿过来送进现有模型,同时做成不可训练的(or 可训练的?如方式一?)

 

应该是使用哪种方式呢?方式一or 方式二  or 都不是?

目前我的程序使用的是方式一

 

问题二:

训练集的loss曲线,

第一轮时loss 下降很快;

第二轮时loss 基本持平;

从第二轮到第三轮切换时,loss有一个大幅度的下降;

为什么从第三轮开始,在每轮内部的loss会有小幅的小升?而从第三轮进入第四轮时,loss 才会有一个比较大下降?

Note: 每一轮进入下一轮时,所有的训练数据会全部随机shuffle。每个mini-batch会按照顺序依次切取一小块送给模型进行训练。

优化算法使用的是Adam算法。

 

问题三:

我目前使用50维的词向量,是不是太小?对结果影响大吗?

 

因为我看论文里面说:

使用了200d的词向量,本来想使用300d的词向量,因为程序跑起来,慢,才做罢 ~~

Table 1:
Model performance comparison
In all of these models, we used a word embedding pre-trained using the GloVe algorithm
using 27 billion Twitter tweets. The vectors chosen were 200d, as these were the largest
dimensionality vectors available with this dataset. Using 300d vectors with Wikipedia data
was also explored, but training time was prohibitively slow, and Twitter vectors appeared to
outperform 200d Wikipedia vectors on this datase


RUN_MODEL=two-feature-substrate-trainable-swap
ALLOW_SOFT_PLACEMENT=True
BATCH_SIZE=2048                                                        一个mini-batch包含的样本数

DROPOUT_KEEP_PROB=0.5                                    四个向量拼接之后,进入全连接层之前,做了弃权,0.5
EMBEDDING_TRAINABLE=True                                  使用神经网络最后的损失来训练词向量,OK?

L2_REG_LAMBDA=0.0                                                    损失函数没有做L2

NUMBER_UNITS=50                                                       每一个RNN内部的"memory"包含的神经元的大小
RNN_TYPE=gru
TRAIN_SAMPLE_PERCENTAGE=0.75                        使用75%的数据做训练,其余的25%做测试, OK?
TRAIN_SIZE=307200                                                       训练集的包含的样本大小

 

下面是在25%的测试集(共107200个样本)的测试情况

DEV loss: 0.6602 ; accuracy: 0.6372 ; recall: 0.0000 ; precison: nan ; [email protected] 0
DEV loss: 0.6296 ; accuracy: 0.6408 ; recall: 0.0142 ; precison: 0.7647 ; [email protected] 4

...
DEV loss: 0.4783 ; accuracy: 0.7680 ; recall: 0.5416 ; precison: 0.7487 ; [email protected] 84
DEV loss: 0.4790 ; accuracy: 0.7671 ; recall: 0.5396 ; precison: 0.7477 ; [email protected] 88
DEV loss: 0.4753 ; accuracy: 0.7700 ; recall: 0.5496 ; precison: 0.7489 ; [email protected] 92
DEV loss: 0.4774 ; accuracy: 0.7701 ; recall: 0.5457 ; precison: 0.7520 ; [email protected] 96
DEV loss: 0.4735 ; accuracy: 0.7727 ; recall: 0.5623 ; precison: 0.7480 ; [email protected] 100
...
DEV loss: 0.4601 ; accuracy: 0.7824 ; recall: 0.6044 ; precison: 0.7470 ; [email protected] 136
DEV loss: 0.4839 ; accuracy: 0.7711 ; recall: 0.5027 ; precison: 0.7895 ; [email protected] 140
DEV loss: 0.4692 ; accuracy: 0.7783 ; recall: 0.5572 ; precison: 0.7678 ; [email protected] 144
DEV loss: 0.4668 ; accuracy: 0.7796 ; recall: 0.5829 ; precison: 0.7534 ; [email protected] 148
read next epoch!, epoch =  1
DEV loss: 0.4857 ; accuracy: 0.7768 ; recall: 0.5419 ; precison: 0.7747 ; [email protected] 152
DEV loss: 0.4657 ; accuracy: 0.7875 ; recall: 0.6334 ; precison: 0.7427 ; [email protected] 156
DEV loss: 0.4649 ; accuracy: 0.7870 ; recall: 0.6116 ; precison: 0.7543 ; [email protected] 160
...
DEV loss: 0.4892 ; accuracy: 0.7839 ; recall: 0.5779 ; precison: 0.7687 ; [email protected] 208
DEV loss: 0.4711 ; accuracy: 0.7875 ; recall: 0.6249 ; precison: 0.7475 ; [email protected] 212
DEV loss: 0.4765 ; accuracy: 0.7859 ; recall: 0.6004 ; precison: 0.7588 ; [email protected] 216
DEV loss: 0.4726 ; accuracy: 0.7883 ; recall: 0.6231 ; precison: 0.7505 ; [email protected] 220
DEV loss: 0.4805 ; accuracy: 0.7854 ; recall: 0.5926 ; precison: 0.7626 ; [email protected] 224
DEV loss: 0.4614 ; accuracy: 0.7902 ; recall: 0.6439 ; precison: 0.7433 ; [email protected] 228
...
DEV loss: 0.4588 ; accuracy: 0.7935 ; recall: 0.6361 ; precison: 0.7555 ; [email protected] 284
DEV loss: 0.4734 ; accuracy: 0.7918 ; recall: 0.5950 ; precison: 0.7783 ; [email protected] 288
DEV loss: 0.4579 ; accuracy: 0.7959 ; recall: 0.6472 ; precison: 0.7547 ; [email protected] 292
DEV loss: 0.4723 ; accuracy: 0.7901 ; recall: 0.5766 ; precison: 0.7874 ; [email protected] 296

read next epoch!, epoch =  2
DEV loss: 0.4484 ; accuracy: 0.7975 ; recall: 0.6784 ; precison: 0.7412 ; [email protected] 300 --> after 2 epoch

算正常的一个结果么?

最好的情况我目测在这里

再往后就开始过拟合了。如下面是15轮之后的结果:

loss会上升的很厉害;所以Early Stop很重要啊~~

DEV loss: 0.8380 ; accuracy: 0.8047 ; recall: 0.6548 ; precison: 0.7718 ; [email protected] 2428  --> 16.18 epoch
DEV loss: 0.8379 ; accuracy: 0.8036 ; recall: 0.6684 ; precison: 0.7609 ; [email protected] 2432
DEV loss: 0.8187 ; accuracy: 0.8029 ; recall: 0.6808 ; precison: 0.7522 ; [email protected] 2436
DEV loss: 0.8403 ; accuracy: 0.8038 ; recall: 0.6404 ; precison: 0.7792 ; [email protected] 2440
DEV loss: 0.8190 ; accuracy: 0.8047 ; recall: 0.6836 ; precison: 0.7547 ; [email protected] 2444
DEV loss: 0.8504 ; accuracy: 0.8035 ; recall: 0.6501 ; precison: 0.7720 ; [email protected] 2448
DEV loss: 0.8257 ; accuracy: 0.8025 ; recall: 0.6702 ; precison: 0.7572 ; [email protected] 2452 --> 16.34 epoch

 回复
Quora Question Pairs 思路记录
22楼旷野的季节  24天前

上一篇的图片没有发成功,重新发一次这篇总结:


参考了唐老师给出的参考资料
http://web.stanford.edu/class/cs224n/reports/2759336.pdf
神经网络的架构是:

Quora Question Pairs 思路记录

 


和这个架构唯一的区别,是把r1-r2 替换成了abs(r1-r2),
我一开始没有用四个向量拼接的方式,只是使用了abs(r1-r2);而如果仅仅用r1-r2,神经网络基本无法收敛。因此参考这篇文章时,我把四个向量里面的r1-r2 替换成了abs(r1-r2)。
目前的疑问有下面这些:

 

问题一: 如果词向量是可以训练的,该怎么训练呢?有下面这两种方式,哪种是正确的?

      方式一: 用glove向量当成词向量的初始值,然后只是在训练时顺便把词向量做成"Trainable",如下面的代码:
                    self.W = tf.get_variable(name='word_embedding', shape = self.word_emmbedding.shape,dtype=tf.float32,
                    initializer=tf.constant_initializer(self.word_embedding),

                     trainable==True)

    使用glove向量当成W的初始值, 同时W的是可以根据loss做调整的,使用的是神经网络最后一层的tf.nn.softmax_cross_entropy_with_logits做损失函数


       方式二: 使用word2vec程序,把traing.txt当成语料库,用CBOW or Skip-Gram模型来学习词向量。
       然后学习到词向量之后,再拿过来送进现有模型,同时做成不可训练的(or 可训练的?如方式一?)

应该是使用哪种方式呢?方式一or 方式二  or 都不是?
目前我的程序使用的是方式一

问题二:
目前我的训练集的loss曲线长下面这个样子:

 

Quora Question Pairs 思路记录
第一轮时loss 下降很快;
第二轮时loss 基本持平;
从第二轮到第三轮切换时,loss有一个大幅度的下降;
为什么从第三轮开始,在每轮内部的loss会有小幅的小升?而从第三轮进入第四轮时,loss 才会有一个比较大下降?
Note: 每一轮进入下一轮时,所有的训练数据会全部随机shuffle。每个mini-batch会按照顺序依次切取一小块送给模型进行训练。
优化算法使用的是Adam算法。

问题三:
我目前使用50维的词向量,是不是太小?对结果影响大吗?

因为我看论文里面说:
使用了200d的词向量,本来想使用300d的词向量,因为程序跑起来,慢,才做罢 ~~

问题四:
测试集上loss最低到0.44, 离0.23还有一段差距啊?怎么办?
0.23的损失函数是根据我目前的架构实现的吗?是不是还有什么其它的技巧呢?

 

附:程序的超参数如下:

RUN_MODEL=two-feature-substrate-trainable-swap
ALLOW_SOFT_PLACEMENT=True
BATCH_SIZE=2048                                                        一个mini-batch包含的样本数是2048

DROPOUT_KEEP_PROB=0.5                                    四个向量拼接之后,进入全连接层之前,做了弃权,0.5
EMBEDDING_TRAINABLE=True                                  使用神经网络最后的损失来训练词向量,OK?

L2_REG_LAMBDA=0.0                                                    损失函数没有做L2
NUMBER_UNITS=50                                                       每一个RNN内部的"memory"包含的神经元的大小是50
RNN_TYPE=gru
TRAIN_SAMPLE_PERCENTAGE=0.75                        使用75%的数据做训练,其余的25%做测试, 比例OK?
TRAIN_SIZE=307200                                                       训练集的包含的样本大小

下面是在25%的测试集(共107200个样本)的测试情况
DEV loss: 0.6602 ; accuracy: 0.6372 ; recall: 0.0000 ; precison: nan ; [email protected] 0
DEV loss: 0.6296 ; accuracy: 0.6408 ; recall: 0.0142 ; precison: 0.7647 ; [email protected] 4
DEV loss: 0.5885 ; accuracy: 0.6993 ; recall: 0.4305 ; precison: 0.6242 ; [email protected] 8
DEV loss: 0.5899 ; accuracy: 0.7101 ; recall: 0.4230 ; precison: 0.6557 ; [email protected] 12
DEV loss: 0.5807 ; accuracy: 0.7132 ; recall: 0.3489 ; precison: 0.7141 ; [email protected] 16
DEV loss: 0.5485 ; accuracy: 0.7296 ; recall: 0.4527 ; precison: 0.6951 ; [email protected] 20
DEV loss: 0.5287 ; accuracy: 0.7381 ; recall: 0.4870 ; precison: 0.6994 ; [email protected] 24
DEV loss: 0.5195 ; accuracy: 0.7440 ; recall: 0.5616 ; precison: 0.6771 ; [email protected] 28
DEV loss: 0.5250 ; accuracy: 0.7416 ; recall: 0.4626 ; precison: 0.7253 ; [email protected] 32
DEV loss: 0.5511 ; accuracy: 0.7302 ; recall: 0.3781 ; precison: 0.7558 ; [email protected] 36
DEV loss: 0.5113 ; accuracy: 0.7515 ; recall: 0.5925 ; precison: 0.6806 ; [email protected] 40
DEV loss: 0.5283 ; accuracy: 0.7356 ; recall: 0.3861 ; precison: 0.7697 ; [email protected] 44
。。。。。。
DEV loss: 0.4605 ; accuracy: 0.7883 ; recall: 0.6857 ; precison: 0.7179 ; [email protected] 168
DEV loss: 0.4723 ; accuracy: 0.7854 ; recall: 0.5999 ; precison: 0.7578 ; [email protected] 172
DEV loss: 0.4781 ; accuracy: 0.7838 ; recall: 0.5803 ; precison: 0.7667 ; [email protected] 176
DEV loss: 0.4648 ; accuracy: 0.7889 ; recall: 0.6491 ; precison: 0.7372 ; [email protected] 180
DEV loss: 0.4884 ; accuracy: 0.7823 ; recall: 0.5601 ; precison: 0.7773 ; [email protected] 184
DEV loss: 0.4577 ; accuracy: 0.7902 ; recall: 0.6831 ; precison: 0.7229 ; [email protected] 188
DEV loss: 0.4721 ; accuracy: 0.7862 ; recall: 0.5919 ; precison: 0.7650 ; [email protected] 192
。。。。。。
DEV loss: 0.4588 ; accuracy: 0.7935 ; recall: 0.6361 ; precison: 0.7555 ; [email protected] 284
DEV loss: 0.4734 ; accuracy: 0.7918 ; recall: 0.5950 ; precison: 0.7783 ; [email protected] 288
DEV loss: 0.4579 ; accuracy: 0.7959 ; recall: 0.6472 ; precison: 0.7547 ; [email protected] 292
DEV loss: 0.4723 ; accuracy: 0.7901 ; recall: 0.5766 ; precison: 0.7874 ; [email protected] 296

read next epoch!, epoch =  2
DEV loss: 0.4484 ; accuracy: 0.7975 ; recall: 0.6784 ; precison: 0.7412 ; [email protected] 300 --> after 2 epoch
算正常的一个结果么?
最好的情况我目测在这里
再往后就开始过拟合了。如下面是15轮之后的结果:
loss会上升的很厉害;所以Early Stop很重要啊~~
DEV loss: 0.8380 ; accuracy: 0.8047 ; recall: 0.6548 ; precison: 0.7718 ; [email protected] 2428  --> 16.18 epoch
DEV loss: 0.8379 ; accuracy: 0.8036 ; recall: 0.6684 ; precison: 0.7609 ; [email protected] 2432
DEV loss: 0.8187 ; accuracy: 0.8029 ; recall: 0.6808 ; precison: 0.7522 ; [email protected] 2436
DEV loss: 0.8403 ; accuracy: 0.8038 ; recall: 0.6404 ; precison: 0.7792 ; [email protected] 2440
DEV loss: 0.8190 ; accuracy: 0.8047 ; recall: 0.6836 ; precison: 0.7547 ; [email protected] 2444
DEV loss: 0.8504 ; accuracy: 0.8035 ; recall: 0.6501 ; precison: 0.7720 ; [email protected] 2448
DEV loss: 0.8257 ; accuracy: 0.8025 ; recall: 0.6702 ; precison: 0.7572 ; [email protected] 2452 --> 16.34 epoch
 

 回复
Quora Question Pairs 思路记录
23楼Lynn  12天前

1.   由上面TensorFlow输出的损失图可以看出在每个epoch里面,损失函数是上升的,这个其实已经能够说明在训练的过程当中产生了过拟合的情况,实际上是一个严重的过拟合,所以要解决这种情况:下面是建议:

     1. 加上正则,这是一般做法,但是比较难控制的是正则化系数,需要调整参数。

     2. 弃权,这是神经网络的做法。

     3. earlying stopping 这是你在上面已经提到了。

     4. 采用模型集成的想法,比如在这里,你是用的是LSTM,是不是可以使用CNN,或者BLSTM或者是GRU。甚至每一个都可以做一做,然后进行stacking,取平均值什么的,也就是类似于Random forest,这种想法能够降低模型的方差,获取比较好的预测结果。

     5. 进行手动特征工程,这个在很多材料上面都有。

     6. 数据源有些标签是有问题的,需要修改,但是这一块我还没有发现比较好的方法解决。

      

 回复
Quora Question Pairs 思路记录
24楼Lynn  12天前

2. 词向量的问题:词向量的维度在我看来有点小,我取得是128,仅仅作为参考。

3. 还有损失的问题:测试机的分布和训练集的分布是不一样的,你可以考虑重新考虑一下分布(亚采样?重采样?)。

4. RNN size可以取大一点。

5. 因为训练数据集比较大,所以在分割验证机的时候没有必要那么大(验证集取一万就行了,用来查看效果)

6. 还有就是参数调整的问题,可以使用交叉验证(警告:这个非常消耗时间,而且你的电脑那么慢)

7. 建议:最好用TensorBoard将测试集的loss也画出来,这样知道early stopping应该在哪里stop

 回复
Quora Question Pairs 思路记录
25楼Lynn  12天前

关于词向量的问题,一般来说有3种做法,提前训练好向量和随机生成词向量,还有初始化为one-hot。

 

在我们的这个问题里面最好使用时时训练好的向量,并且可以训练。

 回复
Quora Question Pairs 思路记录
26楼旷野的季节  16小时前

根据唐老师的提议,把 test集上的loss 也画出来了。过拟合太严重了!

橘黄色的是train 上的; 蓝色的是test集上的。蓝色最低点大约是0.45。随后很快就一路高涨。

加正则试试?

 

Quora Question Pairs 思路记录

下面是accuracy: 可以看到,测试集的准确率(大约0.8)远远小于train上的。

Quora Question Pairs 思路记录

recall && precision类似,就不上图了。

附:

Parameters:

DROPOUT_KEEP_PROB=0.5
EMBEDDING_TRAINABLE=True
L2_REG_LAMBDA=0.0

NUMBER_UNITS=100
RNN_TYPE=gru
SENTENCE_CUT_LENGTH=60
TRAIN_BATCH_SIZE=2500
TRAIN_SAMPLE_PERCENTAGE=0.96
TRAIN_SIZE=388115

 回复
话题作者
Quora Question Pairs 思路记录
解惑者学院首席讲师

新加组员

  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录 
  • Quora Question Pairs 思路记录