Quora Question Pairs 思路记录
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”??
把similarity(s1,s2)映射到概率空间的函数
l2_reg_lambda
R1 >=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
- RNN_train.py
Train data和Dev test data Split;
定义模型的超参数
定义train_step()函数
定义dev_step()函数
定义训练的主循环 ,主循环里面会调用next_batch()函数
- 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_dicclass 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_typeself.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,]
-
1. 想法基本上没有太多的问题,可以先将基本的代码跑通,只要能够确定你的代码能够学习到数据集的信息,就行了,至于正则的部分最开始的时候不用考虑,最重要的是让模型跑起来,这是一个骨架。
2. 代码部分以后最好加上图片,让我们能够看得清,加上图片的同时最好加上代码链接,以便复制下来看。
3. lstm是个不错的结构。是不是可以使用双向lstm和CNN呢,损失函数是不是可以使用其他的呢,参考论文:http://anthology.aclweb.org/P/P16/P16-1036.pdf。
4. 这个比赛当中有一点比较重要,就是训练集和测试集的正负样本比例。这个会大大影响你的测试结果。
5. 代码可以参考别人的比较好的代码,第一是学习别人代码,二是培养一个好的代码风格。
6. 还有一个比较大的方向:现在使用的基于Siamese网络结构,有更好的网路结构吗?(这个需要将现在的结构跑完在去探索)
7. 可以拜读一下2016年的ACL会议的论文,里面有很多论文提到了语义理解和文本匹配。很多有很大的参考价值。
-
好的,谢谢唐老师!
-
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
谢谢!
-
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模型就不能用吗?
-
你这个代码应该是参考别人的代码写的,有这么几个问题你可以考虑一下(代码的话,有点难看):
1. 你的给你的训练数据训练了多少个epoches
2. 6万的数据真不一定够,你可以使用所有的数据,如果不行,再考虑是不是有问题,RNN是没有问题的。
2. 你用的是对比损失,你现在就先让对比损失跑起来(我这边用对比损失的效果,要比log_loss好)
有这么几个要点:1. 正负样本比例
2. 你的代码是不是有问题,我在最开始做这个比赛的时候,也出现了你的问题。
3. 如果觉得实在是有问题可以使用tf.losses.log_loss
4. 我出现的问题挺多, 1):数据预处理部分我出现过问题。
2):句子的长度你取了多少?我取得是55,也取过60
3):神经网络部分的代码对的吗?
-
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
或者老师有什么别的建议吗?
-
这里面有个比较严重的问题,就是句子长度的问题取句子最长为139,在这个里面90%以上的句子长度都不到60,如果句子的长度取139,那么就是在句子后面拼凑了大量的无用信息,虽然说lstm或gru能够在训练当中学习到较长的时间序列的信息,但是注意,如果时间序列的长度过长LSTM也是很无力的(如果只取LSTM最后一个单元的输出)。
参考的解决方法:在训练集当中,每个句子的长度是不固定的,在你的代码当中,需要的是固定长度的输入,所以这个时候需要你将所有的句子处理成长度一样,所以这个时候需要人为的指定句子的长度,你在预处理当中应该是有这个参数的,所以将这个参数设置成50,然后再进行处理和训练,你再看看结果。
batch_size取的是1500,8912是否过大?如果mini_batch取得过大,会是的它的方向探索性不是很强,有没有考虑过这个问题?
当然这只是小问题,大问题在于8912的话,会使得你的代码非常消耗内存,加大了每一轮的计算量,减慢运行速度。
还有你说的波动的原因是不是和学习率有关系?你的学习率是否过大?
一般来说,如果你的训练结果波动很大,这个时候你需要考虑减小你的学习率。
谢谢唐老师的回复,过节回复晚了:)
1. 对之前loss不能收敛问题的解决
发现之前很多次说的模型学不到东西,可能是神经网络架构方面的问题
为了完整性,再画一下,之前的架构是下面这个样子:
注:图中的“abs"指的是对两个input相减后取绝对值
架构一
后面与唐老师沟通后,参考唐老师的方案,改成了下面的架构:
架构二
后来我思考为什么一开始的架构不行,把上面的两种架构整合成了下面的架构:
架构三
注:图中的“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%了,像是比胡乱猜要好,但是其实模型什么都没有学到。
回顾一下之前课程学到的东西,
不解释,上实验结果,每一行是一个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)。
目前的想法大概就是这些,如有问题欢迎指正!
经过与唐老师的沟通,目前思路如下:
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 就可以。
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 训练集的样本个数
下面的图片是训练集,而文字描述是测试集:
Train loss: 0.36 : DEV loss: 0.5330878
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
而测试集的情况是:
Train accuracy : 83% Dev accuracy : 75.68 %
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
而测试集的情况是:
Train precison: 77% Dev precision: 68.22 %
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
而测试集的情况是:
Train recall : 77% Test recall: 61.5%
这四个指标的Train && Dev 之间的差距都比较大,因此,我认为现在模型处于严重的过拟合状态。应该考虑加正则或者drop手段来防止过拟合。
与前一篇的区别,是词向量是可以训练的。正如唐老师所说,词向量一定要是可以训练的,效果有了很大的变化:
还是先看训练集,结果好的不得了. 超参数是这些:
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?
训练集accuracy 提升到97% 左右。还是在每epoch开头的地方突然上升。所以出现下面这样的波动形式。
训练集recall 最后能提到97% 左右。
训练集precision 能在95%左右。
综上,改成词向量可以训练之后,神经网络在训练集上的表现有了巨大的提升。
但是在测试集上的表现就不那么好了。
@ 后面的数字是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 区别也比较大。可见目前模型处于严重的过拟合。
接下来先要解决一下模型的过拟合问题。
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的词向量,因为程序跑起来,慢,才做罢 ~~
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
上一篇的图片没有发成功,重新发一次这篇总结:
参考了唐老师给出的参考资料
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_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曲线长下面这个样子:
第一轮时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
1. 由上面TensorFlow输出的损失图可以看出在每个epoch里面,损失函数是上升的,这个其实已经能够说明在训练的过程当中产生了过拟合的情况,实际上是一个严重的过拟合,所以要解决这种情况:下面是建议:
1. 加上正则,这是一般做法,但是比较难控制的是正则化系数,需要调整参数。
2. 弃权,这是神经网络的做法。
3. earlying stopping 这是你在上面已经提到了。
4. 采用模型集成的想法,比如在这里,你是用的是LSTM,是不是可以使用CNN,或者BLSTM或者是GRU。甚至每一个都可以做一做,然后进行stacking,取平均值什么的,也就是类似于Random forest,这种想法能够降低模型的方差,获取比较好的预测结果。
5. 进行手动特征工程,这个在很多材料上面都有。
6. 数据源有些标签是有问题的,需要修改,但是这一块我还没有发现比较好的方法解决。
2. 词向量的问题:词向量的维度在我看来有点小,我取得是128,仅仅作为参考。
3. 还有损失的问题:测试机的分布和训练集的分布是不一样的,你可以考虑重新考虑一下分布(亚采样?重采样?)。
4. RNN size可以取大一点。
5. 因为训练数据集比较大,所以在分割验证机的时候没有必要那么大(验证集取一万就行了,用来查看效果)
6. 还有就是参数调整的问题,可以使用交叉验证(警告:这个非常消耗时间,而且你的电脑那么慢)
7. 建议:最好用TensorBoard将测试集的loss也画出来,这样知道early stopping应该在哪里stop
关于词向量的问题,一般来说有3种做法,提前训练好向量和随机生成词向量,还有初始化为one-hot。
在我们的这个问题里面最好使用时时训练好的向量,并且可以训练。
根据唐老师的提议,把 test集上的loss 也画出来了。过拟合太严重了!
橘黄色的是train 上的; 蓝色的是test集上的。蓝色最低点大约是0.45。随后很快就一路高涨。
加正则试试?
下面是accuracy: 可以看到,测试集的准确率(大约0.8)远远小于train上的。
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