深度学习利器:TensorFlow与NLP模型

前言

\\

自然语言处理(简称NLP),是研究计算机处理人类语言的一门技术,NLP技术让计算机可以基于一组技术和理论,分析、理解人类的沟通内容。传统的自然语言处理方法涉及到了很多语言学本身的知识,而深度学习,是表征学习(representation learning)的一种方法,在机器翻译、自动问答、文本分类、情感分析、信息抽取、序列标注、语法解析等领域都有广泛的应用。

\\

2013年末谷歌发布的word2vec工具,将一个词表示为词向量,将文字数字化,有效地应用于文本分析。2016年谷歌开源自动生成文本摘要模型及相关TensorFlow代码。2016/2017年,谷歌发布/升级语言处理框架SyntaxNet,识别率提高25%,为40种语言带来文本分割和词态分析功能。2017年谷歌官方开源tf-seq2seq,一种通用编码器/解码器框架,实现自动翻译。本文主要结合TensorFlow平台,讲解TensorFlow词向量生成模型(Vector Representations of Words);使用RNN、LSTM模型进行语言预测;以及TensorFlow自动翻译模型。

\\

Word2Vec数学原理简介

\\

我们将自然语言交给机器学习来处理,但机器无法直接理解人类语言。那么首先要做的事情就是要将语言数学化,Hinton于1986年提出Distributed Representation方法,通过训练将语言中的每一个词映射成一个固定长度的向量。所有这些向量构成词向量空间,每个向量可视为空间中的一个点,这样就可以根据词之间的距离来判断它们之间的相似性,并且可以把其应用扩展到句子、文档及中文分词。

\\

Word2Vec中用到两个模型,CBOW模型(Continuous Bag-of-Words model)和Skip-gram模型(Continuous Skip-gram Model)。模型示例如下,是三层结构的神经网络模型,包括输入层,投影层和输出层。

\\

(点击放大图像)

\\

053e82398fff2a791da1f6de07aa282e.png

\\

691963b8dfe3ed835fa483ba47842539.jpg

\\

(点击放大图像)

\\

7c8ca58c9de5111153128f6b0a4c6274.png

\\

其中score(wt, h),表示在的上下文环境下,预测结果是的概率得分。上述目标函数,可以转换为极大化似然函数,如下所示:

\\

(点击放大图像)

\\

85475af825c90b5687f9d56f04017784.png

\\

求解上述概率模型的计算成本是非常高昂的,需要在神经网络的每一次训练过程中,计算每个词在他的上下文环境中出现的概率得分,如下所示:

\\

(点击放大图像)

\\

6367f29dc112253c4a05d7ae15a93ecc.png

\\

然而在使用word2vec方法进行特性学习的时候,并不需要计算全概率模型。在CBOW模型和skip-gram模型中,使用了逻辑回归(logistic regression)二分类方法进行的预测。如下图CBOW模型所示,为了提高模型的训练速度和改善词向量的质量,通常采用随机负采样(Negative Sampling)的方法,噪音样本w1,w2,w3,wk…为选中的负采样。

\\

(点击放大图像)

\\

8268ad187f749ecbb730ae48fcc6b38f.png

\\

TensorFlow近义词模型

\\

本章讲解使用TensorFlow word2vec模型寻找近义词,输入数据是一大段英文文章,输出是相应词的近义词。比如,通过学习文章可以得到和five意思相近的词有: four, three, seven, eight, six, two, zero, nine。通过对大段英文文章的训练,当神经网络训练到10万次迭代,网络Loss值减小到4.6左右的时候,学习得到的相关近似词,如下图所示:

\\

(点击放大图像)

\\

b35656a3970a4c3ea174b85838d8011d.png

\\

下面为TensorFlow word2vec API 使用说明:

\\

构建词向量变量,vocabulary_size为字典大小,embedding_size为词向量大小

\\
\embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
\\

定义负采样中逻辑回归的权重和偏置

\\
\nce_weights = tf.Variable(tf.truncated_normal\([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size))) \nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
\\

定义训练数据的接入

\\
\train_inputs = tf.placeholder(tf.int32, shape=[batch_size]) \train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
\\

定义根据训练数据输入,并寻找对应的词向量

\\
\embed = tf.nn.embedding_lookup(embeddings, train_inputs)
\\

基于负采样方法计算Loss值

\\
\loss = tf.reduce_mean( tf.nn.nce_loss\(weights=nce_weights, biases=nce_biases, labels=train_labels,\inputs=embed, num_sampled=num_sampled, num_classes=vocabulary_size))
\\

定义使用随机梯度下降法执行优化操作,最小化loss值

\\
\optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0).minimize(loss)
\\

通过TensorFlow Session Run的方法执行模型训练

\\
\for inputs, labels in generate_batch(...): \feed_dict = {train_inputs: inputs, train_labels: labels} \_, cur_loss = session.run([optimizer, loss], feed_dict=feed_dict)
\\

TensorFlow语言预测模型

\\

本章主要回顾RNN、LSTM技术原理,并基于RNN/LSTM技术训练语言模型。也就是给定一个单词序列,预测最有可能出现的下一个单词。例如,给定[had, a, general] 3个单词的LSTM输入序列,预测下一个单词是什么?如下图所示:

\\

(点击放大图像)

\\

fe0549dec75c3690897db72e6f7cbec1.png

\\

RNN技术原理

\\

循环神经网络(Recurrent Neural Network, RNN)是一类用于处理序列数据的神经网络。和卷积神经网络的区别在于,卷积网络是适用于处理网格化数据(如图像数据)的神经网络,而循环神经网络是适用于处理序列化数据的神经网络。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNN之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。如下图所示:

\\

(点击放大图像)

\\

1a01ce96e712f094f070e0e0371c2643.png

\\

1d67b31757cc5c8a919865fe3cb1fbbf.jpg

\\

LSTM技术原理

\\

RNN有一问题,反向传播时,梯度也会呈指数倍数的衰减,导致经过许多阶段传播后的梯度倾向于消失,不能处理长期依赖的问题。虽然RNN理论上可以处理任意长度的序列,但实习应用中,RNN很难处理长度超过10的序列。为了解决RNN梯度消失的问题,提出了Long Short-Term Memory模块,通过门的开关实现序列上的记忆功能,当误差从输出层反向传播回来时,可以使用模块的记忆元记下来。所以 LSTM 可以记住比较长时间内的信息。常见的LSTM模块如下图所示:

\\

(点击放大图像)

\\

8ec74907b3c87ff0399d9a026c0b8e17.png

\\

fe267918bc22b6170bdd70e9b5442e96.jpg

\\

(点击放大图像)

\\

00d923109a8f08cd9f1ad4da34c9ee38.png

\\

output gate类似于input gate同样会产生一个0-1向量来控制Memory Cell到输出层的输出,如下公式所示:

\\

(点击放大图像)

\\

e74f03ca13aee1677c9fc0a229bfc2ed.png

\\

三个门协作使得 LSTM 存储块可以存取长期信息,比如说只要输入门保持关闭,记忆单元的信息就不会被后面时刻的输入所覆盖。

\\

使用TensorFlow构建单词预测模型

\\

首先下载PTB的模型数据,该数据集大概包含10000个不同的单词,并对不常用的单词进行了标注。

\\
\

首先需要对样本数据集进行预处理,把每个单词用整数标注,即构建词典索引,如下所示:

\
\\

读取训练数据

\\
\data = _read_words(filename) \#按照单词出现频率,进行排序 \counter = collections.Counter(data) \count_pairs = sorted(counter.items(), key=lambda x: (-x1, x[0])) \#构建词典及词典索引 \words, _ = list(zip(*count_pairs)) \word_to_id = dict(zip(words, range(len(words))))
\\
\

接着读取训练数据文本,把单词序列转换为单词索引序列,生成训练数据,如下所示:

\
\\

读取训练数据单词,并转换为单词索引序列

\\

data = _read_words(filename) data = [word_to_id[word] for word in data if word in word_to_id]

\\

生成训练数据的data和label,其中epoch_size为该epoch的训练迭代次数,num_steps为LSTM的序列长度

\\
\i = tf.train.range_input_producer(epoch_size, shuffle=False).dequeue() \x = tf.strided_slice(data, [0, i * num_steps], [batch_size, (i + 1) * num_steps]) \x.set_shape([batch_size, num_steps]) \y = tf.strided_slice(data, [0, i * num_steps + 1], [batch_size, (i + 1) * num_steps + 1]) \y.set_shape([batch_size, num_steps])
\\

构建LSTM Cell,其中size为隐藏神经元的数量

\\
\lstm_cell = tf.contrib.rnn.BasicLSTMCell(size,\ forget_bias=0.0, state_is_tuple=True)
\\

如果为训练模式,为保证训练鲁棒性,定义dropout操作

\\
\attn_cell = tf.contrib.rnn.DropoutWrapper(lstm_cell, \output_keep_prob=config.keep_prob)
\\

根据层数配置,定义多层RNN神经网络

\\
\cell = tf.contrib.rnn.MultiRNNCell( [ attn_cell for _ in range(config.num_layers)], \state_is_tuple=True)
\\

根据词典大小,定义词向量

\\
\embedding = tf.get_variable(\"embedding\
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 文本分类 #### 数据预处理 要求训练集和测试集分开存储,对于中文的数据必须先分词,对分词后的词用空格符分开,并且将标签连接到每条数据的尾部,标签和句子用分隔符\分开。具体的如下: * 今天 的 天气 真好\积极 #### 文件结构介绍 * config文件:配置各种模型的配置参数 * data:存放训练集和测试集 * ckpt_model:存放checkpoint模型文件 * data_helpers:提供数据处理的方法 * pb_model:存放pb模型文件 * outputs:存放vocab,word_to_index, label_to_index, 处理后的数据 * models:存放模型代码 * trainers:存放训练代码 * predictors:存放预测代码 #### 训练模型 * python train.py --config_path="config/textcnn_config.json" #### 预测模型 * 预测代码都在predictors/predict.py中,初始化Predictor对象,调用predict方法即可。 #### 模型的配置参数详述 ##### textcnn:基于textcnn的文本分类 * model_name:模型名称 * epochs:全样本迭代次数 * checkpoint_every:迭代多少步保存一次模型文件 * eval_every:迭代多少步验证一次模型 * learning_rate:学习速率 * optimization:优化算法 * embedding_size:embedding层大小 * num_filters:卷积核的数量 * filter_sizes:卷积核的尺寸 * batch_size:批样本大小 * sequence_length:序列长度 * vocab_size:词汇表大小 * num_classes:样本的类别数,二分类时置为1,多分类时置为实际类别数 * keep_prob:保留神经元的比例 * l2_reg_lambda:L2正则化的系数,主要对全连接层的参数正则化 * max_grad_norm:梯度阶段临界值 * train_data:训练数据的存储路径 * eval_data:验证数据的存储路径 * stop_word:停用词表的存储路径 * output_path:输出路径,用来存储vocab,处理后的训练数据,验证数据 * word_vectors_path:词向量的路径 * ckpt_model_path:checkpoint 模型的存储路径 * pb_model_path:pb 模型的存储路径 ##### bilstm:基于bilstm的文本分类 * model_name:模型名称 * epochs:全样本迭代次数 * checkpoint_every:迭代多少步保存一次模型文件 * eval_every:迭代多少步验证一次模型 * learning_rate:学习速率 * optimization:优化算法 * embedding_size:embedding层大小 * hidden_sizes:lstm的隐层大小,列表对象,支持多层lstm,只要在列表中添加相应的层对应的隐层大小 * batch_size:批样本大小 * sequence_length:序列长度 * vocab_size:词汇表大小 * num_classes:样本的类别数,二分类时置为1,多分类时置为实际类别数 * keep_prob:保留神经元的比例 * l2_reg_lambda:L2正则化的系数,主要对全连接层的参数正则化 * max_grad_norm:梯度阶段临界值 * train_data:训练数据的存储路径 * eval_data:验证数据的存储路径 * stop_word:停用词表的存储路径 * output_path:输出路径,用来存储vocab,处理后的训练数据,验证数据 * word_vectors_path:词向量的路径 * ckpt_model_path:checkpoint 模型的存储路径 * pb_model_path:pb 模型的存储路径 ##### bilstm atten:基于bilstm + attention 的文本分类 * model_name:模型名称 * epochs:全样本迭代次数 * checkpoint_every:迭代多少步保存一次模型文件 * eval_every:迭代多少步验证一次模型 * learning_rate:学习速率 * optimization:优化算法 * embedding_size:embedding层大小 * hidd

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值