项目来源:Github
数据集:MR: 一句话的电影评论。分类涉及检测积极/消极的评论(Pang and Lee, 2005)。
关键概念:embedding-layer ; 词向量层
在输入层,每一个单词用一个实数向量表示,这个向量被称为"词向量"(word embedding)。词向量可以形象地理解为将词汇表嵌入到一个固定维度的实数空间里,将单词编号转化为词向量主要有两大作用。
1. 降低输入维度。如果不使用词向量层,而直接将单词以one-hot vector的形式输入CNN,那么输入的维度大小将与词汇表大小相同,假设训练集中的单词个数(vocab_size)是8000,那么对应的one-hot vecotr也是8000,那么输入矩阵的大小将是8000x8000。如果使用词向量层,将设embedding_size=128,那么输入的矩阵则缩小为8000x128;
2.增加语义信息。简单的单词编号是不包含语义信息的,两个单词之间编号相近,并不意味着他们的含义有任何关联,而词向量将洗漱的编号转化为稠密的向量表示,这使得词向量有可能包含更为丰富的信息,在自然语言应用中学习得到的词向量通常会将含义相近的词赋予取值相近的词向量。使得上层的网络可以更容易地抓住相似单词之间的共性。
3.在没有大量监督数据集的情况下,使用从非监督神经语言模型训练得到的词向量进行初始化是用来提升结果的普遍方法。我们使用公用的、下哦那个10亿Google 新闻数据中训练出来的Word2vec词向量。此向量的维度是300并且是采用连续的词袋架构(Mikolov et al., 2013)训练出来的。没有出现在预训练词向量中的单词随机初始化。
Tensorflow实现embedding层:
with tf.variable_scope("Embedding-layer"):
embedding_weight=tf.get_variable("weight",
initializer=tf.random_uniform((vocab_size,embedding_size),minval=-1.0,maxval=1.0))
#根据张量input_x 来将[vocab_size,embedding_size]进行embedding
#input_x的维度是[Batch_size,最长句子的单词数]
wordVector=tf.nn.embedding_lookup(embedding_weight,input_x)
#经过tf.nn.embedding_lookup后 wordVector的维度 [Batch_size,最长句子的单词数,embedding_size]
wordVec_expanded=tf.expand_dims(wordVector,-1)
#原来是二维的现在变成三维的了,在最后一维加入一维
主要步骤:
1)对MR数据,进行预处理,借助python 的re.sub 和正则表达式,将每个句子格式化(去掉特殊符号,分隔标点符号等)
2)随机打乱数据,并且需要自行将数据集划分为测试集和验证集(MNIST等tensorflow自带的已经划分好了)
# 随机打乱数据顺序(x 和 y 必须使用同一个shuffle_indices)
np.random.seed(10)
shuffle_indices = np.random.permutation(np.arange(len(y)))
x_shuffled = x[shuffle_indices]
y_shuffled = y[shuffle_indices]
# 划分训练数据和验证数据集
#选了90%作为测试数据 10%作为验证数据
sample_index = -1 * int(VALIDATION_PERCENTAGE * float(len(y)))
#[:sample_index]从0到倒数第|sample_index|个为测试数据
#[sample_index:]从倒数第|sample_index|到末尾为验证数据
x_train, x_dev = x_shuffled[:sample_index], x_shuffled[sample_index:]
y_train, y_dev = y_shuffled[:sample_index], y_shuffled[sample_index:]
3)设计向前传播网络结构:
embedding-layer —— conv1 卷积层{卷积层使用三个尺寸大小不同的过滤器,通过并联的方式进行卷积,类似Inception-v3} ———最大池化层—— dropout层(只在训练时)———全连接层输出