TensorFlow深度学习笔记 循环神经网络实践

转载请注明作者:梦里风林

Github工程地址:https://github.com/ahangchen/GDLnotes

欢迎star,有问题可以到Issue区讨论

官方教程地址

视频/字幕下载

加载数据

使用text8作为训练的文本数据集

text8中只包含27种字符:小写的从a到z,以及空格符。如果把它打出来,读起来就像是去掉了所有标点的wikipedia。

直接调用lesson1中maybe_download下载text8.zip

用zipfile读取zip内容为字符串,并拆分成单词list

用connections模块统计单词数量并找出最常见的单词

达成随机取数据的目标

构造计算单元

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

构造一个vocabulary_size x embedding_size的矩阵,作为embeddings容器,

有vocabulary_size个容量为embedding_size的向量,每个向量代表一个vocabulary,

每个向量的中的分量的值都在-1到1之间随机分布

embed = tf.nn.embedding_lookup(embeddings, train_dataset)

调用tf.nn.embedding_lookup,索引与train_dataset对应的向量,相当于用train_dataset作为一个id,去检索矩阵中与这个id对应的embedding

loss = tf.reduce_mean(

        tf.nn.sampled_softmax_loss(softmax_weights, softmax_biases, embed,

                                  train_labels, num_sampled, vocabulary_size))

采样计算训练损失

optimizer = tf.train.AdagradOptimizer(1.0).minimize(loss)

自适应梯度调节器,调节embedding列表的数据,使得偏差最小

预测,并用cos值计算预测向量与实际数据的夹角作为预测准确度(相似度)指标

传入数据进行训练

切割数据用于训练,其中:

data_index = (data_index +1) % len(data)

依旧是每次取一部分随机数据传入

等距离截取一小段文本

构造训练集:每个截取窗口的中间位置作为一个train_data

构造标签:每个截取窗口中,除了train_data之外的部分,随机取几个成为一个list,作为label(这里只随机取了一个)

这样就形成了根据目标词汇预测上下文的机制,即Skip-gram

训练100001次,每2000次输出这两千次的平均损失

每10000次计算相似度,并输出与验证集中的词最接近的词汇列表

用tSNE降维呈现词汇接近程度

用matplotlib绘制结果

实现代码见word2vec.py

CBOW

上面训练的是Skip-gram模型,是根据目标词汇预测上下文,而word2vec还有一种方式,CBOW,根据上下文预测目标词汇。

实际上就是将Skip-gram中的输入输出反过来。

修改截取数据的方式

构造标签:每个截取窗口的中间位置作为一个train_label

构造训练集:每个截取窗口中,除了train_label之外的部分,作为train_data(这里只随机取了一个)

这样就形成了根据上下文预测目标词汇的机制,即CBOW

分别从embeding里找到train_data里每个word对应的vector,用tf.reduce_sum将其相加,将相加结果与train_label比较

# Look up embeddings for inputs.embed = tf.nn.embedding_lookup(embeddings, train_dataset)# sum up vectors on first dimensions, as context vectorsembed_sum = tf.reduce_sum(embed,0)

训练中依旧是调节embeding的参数来优化loss

训练结果如下图,可以看到不同单词的接近程度

代码见:

cbow.py

RNN 造句

整体思路是,以一个文本中的一个词作为train data,后续的所有词作为train label,从而能够根据一个给定词,预测后续的片段。

训练数据

BatchGenerator

text: 全部的文本数据

text_size:全部文本的字符串长度

batch_size:每段训练数据的大小

num_unrollings:要生成的训练数据段的数目

segment:整个训练数据集可以分成几个训练数据片段

cursor:重要,

一开始记录每个训练数据片段的起始位置坐标,即这个片段位于text的哪个index

执行next_batch生成一个训练数据的时候,游标会从初始位置自增,直到取够batch_size个数据

last_batch:上一个训练数据片段

每调用一次next,生成一个num_unrollings长的array,以last_batch开头,跟着num_unrollings个batch

每个batch的作为train_input,每个batch后面的一个batch作为train_label,每个step训练num_unrolling个batch

lstm-cell

为了解决消失的梯度问题,引入lstm-cell,增强model的记忆能力

根据这篇论文设计lstm-cell:http://arxiv.org/pdf/1402.1128v1.pdf

分别有三个门:输入门,遗忘门,输出门,构成一个cell

输入数据是num_nodes个词,可能有vocabulary_size种词

输入门:

  input_gate = sigmoid(i * ix + o * im + ib)

- 给输入乘一个vocabulary_size * num_nodes大小的矩阵,给输出乘一个num_nodes * num_nodes大小的矩阵;

- 用这两个矩阵调节对输入数据的取舍程度

- 用sigmoid这个非线性函数进行激活

遗忘门:

  forget_gate = sigmoid(i * fx + o * fm + fb)

思路同输入门,用以对历史数据做取舍

输出门:

  output_gate = sigmoid(i * ox + o * om + ob)

思路同输入门,用以对输出状态做取舍

组合:

  update = i * cx + o * cm + cb

  state = forget_gate * state + input_gate * tanh(update)

  lstm_cell = output_gate * tanh(state)

- 用同样的方式构造新状态update- 用遗忘门处理历史状态state- 用tanh激活新状态update- 用输入门处理新状态update- 整合新旧状态,再用tanh激活状态state- 用输出门处理state

lstm优化

上面的cell中,update,output_gate,forget_gate,input_gate计算方法都是一样的,

可以把四组参数分别合并,一次计算,再分别取出:

values = tf.split(1, gate_count, tf.matmul(i, input_weights) + tf.matmul(o, output_weights) + bias)input_gate = tf.sigmoid(values[0])forget_gate = tf.sigmoid(values[1])update = values[2]

再将lstm-cell的输出扔到一个WX+b中调整作为输出

实现代码见singlew_lstm.py

Optimizer

采用one-hot encoding作为label预测

采用交叉熵计算损失

引入learning rate decay

Flow

填入训练数据到placeholder中

验证集的准确性用logprob来计算,即对可能性取对数

每10次训练随机挑取5个字母作为起始词,进行造句测试

你可能注意到输出的sentence是由sample得到的词组成的,而非选择概率最高的词,这是因为,如果一直取概率最高的词,最后会一直重复这个概率最高的词

实现代码见lstm.py

Beam Search

上面的流程里,每次都是以一个字符作为单位,可以使用多一点的字符做预测,取最高概率的那个,防止特殊情况导致的误判

在这里我们增加字符为2个,形成bigram,代码见:bigram_lstm.py

主要通过BigramBatchGenerator类实现

Embedding look up

由于bigram情况下,vocabulary_size变为 27*27个,使用one-hot encoding 做predict的话会产生非常稀疏的矩阵,浪费算力,计算速度慢

因此引入embedding_lookup,代码见embed_bigram_lstm.py

数据输入:BatchGenerator不再生成one-hot-encoding的向量作为输入,而是直接生成bigram对应的index列表

embedding look up调整embedding,使bigram与vector对应起来

将embedding look up的结果喂给lstm cell即可

输出时,需要将label和output都转为One-hot-encoding,才能用交叉熵和softmax计算损失

在tensor里做data到one-hot-encoding转换时,主要依赖tf.gather函数

在对valid数据做转换时,主要依赖one_hot_voc函数

Drop out

在lstm cell中对input和output做drop out

Refer to thisarticle

Seq2Seq

最后一个问题是,将一个句子中每个词转为它的逆序字符串,也就是一个seq到seq的转换

正经的实现思路是,word 2 vector 2 lstm 2 vector 2 word

不过tensorflow已经有了这样一个模型来做这件事情:Seq2SeqModel,关于这个模型可以看这个分析

以及tensorflow的example

只需要从batch中,根据字符串逆序的规律生成target sequence,放到seq2seqmodel里即可,主要依赖rev_id函数

实现见seq2seq.py

注意,用Seq2SeqModel的时候,size和num_layer会在学习到正确的规律前就收敛,我把它调大了一点

defcreate_model(sess, forward_only):model = seq2seq_model.Seq2SeqModel(source_vocab_size=vocabulary_size,                                      target_vocab_size=vocabulary_size,                                      buckets=[(20,21)],                                      size=256,                                      num_layers=4,                                      max_gradient_norm=5.0,                                      batch_size=batch_size,                                      learning_rate=1.0,                                      learning_rate_decay_factor=0.9,                                      use_lstm=True,                                      forward_only=forward_only)returnmodel

参数含义

source_vocab_size: size of the source vocabulary.

target_vocab_size: size of the target vocabulary.

buckets: a list of pairs (I, O), where I specifies maximum input length

that will be processed in that bucket, and O specifies maximum output

length. Training instances that have inputs longer than I or outputs

longer than O will be pushed to the next bucket and padded accordingly.

We assume that the list is sorted, e.g., [(2, 4), (8, 16)].

size: number of units in each layer of the model.

num_layers: number of layers in the model.

max_gradient_norm: gradients will be clipped to maximally this norm.

batch_size: the size of the batches used during training;

the model construction is independent of batch_size, so it can be

changed after initialization if this is convenient, e.g., for decoding.

learning_rate: learning rate to start with.

learning_rate_decay_factor: decay learning rate by this much when needed.

use_lstm: if true, we use LSTM cells instead of GRU cells.

num_samples: number of samples for sampled softmax.

forward_only: if set, we do not construct the backward pass in the model.

参考链接

林洲汉-知乎

词向量

rudolfix - udacity_deeplearn

Edwardbi - 解析Tensorflow官方English-Franch翻译器demo

作者:梦里茶

链接:https://www.jianshu.com/p/45dbfe5809d4

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容