摘要:最近在学习RNN的TensorFlow用法,发现TensorFlow官网的解析对于新手还是有些难懂,尤其是初次接触RNN的小伙伴,因此根据自己的理解,按原文的顺序梳理一遍,着重描述含有GRU的单元网络结构,以及训练流程。
!!! 只有Neural Networks在时间步上重复训练才称为RNN
本人在第一次接触RNN的时候,看到最多的就是类似上图一样的图例。因此就误将h0、h1...等看作为相互独立的RNN单元,例如上图,我就曾经把他看成了,输入维度为4,RNN单元为4,输出维度为4的一个RNN网络。
然而,大错特错!
实际上从h1一直到h4,h代表的一直是同一个RNN网络,只不过按时间步1(time step1)到时间步4(time step4)展开展示罢了。
一.网络结构
上图是TensorFlow官方文档对于一个Batch训练的网络结构,其以单一字符为时间步(time step),将RNN的结构与训练过程以Seq_length次展开,由于其中混杂了Seq_length次训练、Batch_size的训练,使网络结构的展示与理解变得复杂,因此下图是对于单一时间步下的训练网络结构。
根据上述图片以及原文解析可以知道:
首先输入数据如下:
First Citizen:
Before we proceed any further, hear me speak.
All:
Speak, speak.
……
共有1115394个字符,其中不重复的字符一共有65个,包括“\n”与” ”。
根据SEQ_LENGTH将输入的文本分块,每块文本含有SEQ_LENGTH+1个字符。
每一个文本块中都含有一对Input和Output,其尺寸为SEQ_LENGTH个字符,Output与Input相错1个字符。
对于RNN,训练过程中强调“时间步”(time step)的概念。输入是以字符为单位,因此一对Input和Ouput所含的时间步为SEQ_LENGTH个。
再最后输入训练之前,所有的文本块必须被打乱输入,否则重复训练则没有意义。因此,将11154个文本块以BATCH_SIZE个文本块为一批,共约172批。
再以EPOCH为训练循环次数,将172批数据训练EPOCH次,获得最后的网络权值结果。
二.单一时间步(time step)下的网络结构
1. Embedding Input layer(输入层)
对于语言生成RNN网络学习来说,与普通直接数据输入的网络学习不同,在输入网络学习之前,语言字符首先需要根据相应元的尺寸做向量化处理,并做嵌入处理(将) ,然后再输入网络中进行训练。
BATCH_SIZE = 64 # 一批数据集中所包含的文字块的个数
SEQ_LENGTH = 100 # 一个文字块内包含的字符个数
BUFFER_SIZE = 10000 # 打乱Batch顺序的指标,越大混乱程度越大
EMBEDDING_DIM = 256 # 嵌入后输出的向量维数
Embedding层是针对自然语言处理提出的一种将文字向量映射到高维空间的特殊处理层,即以一定模式将文字向量转换为数值型向量,并且嵌入后的向量在处理过程时更有效率。
因此,在一批共BATCH_SIZE个文本块的训练中,以EMBEDDING_DIM为嵌入后输出向量的尺寸,即将shape为[BATCH_SIZE,SEQ_LENGTH]的输入向量输入到嵌入层后,嵌入层将SEQ_LENGTH个单一数值映射成SEQ_LENGTH个高维向量,其维度为EMBEDDING_DIM。最终,嵌入层产生的数据shape为[BATCH_SIZE,SEQ_LENGTH,EMBEDDING_DIM]。
2. GRU layer (LSTM的变体层)
UNITS = 1024 # GRU单元中所含的节点数
GRU层根据UNITS值来设置,使该层具有1024个隐藏节点。
关于GRU的单元描述详见"深度学习之GRU网络":https://www.cnblogs.com/jiangxinyang/p/9376021.html
3.All connected layer (全连接层)
VOCB_SIZE = 65 # 全连接层的单元数等于Unique字符的个数
全连接层的单元个数为VOCB_SIZE,即该层具有65个节点
三. 训练逻辑
对于某一批训练
{ # 共有64个文字块,即该批训练次数为64次。训练后,计算损失函数,修正系数。
对于该批中的某一次训练
{ # 将100个维度为256的字符向量按先后顺序输入到具有1000个单元的GRU层中
对于该次训练中的某一个输入
{ # 将字符向量输入到1000个单元的GRU中,经过全连接层输出维度为65的输出向量
} 依次完成上述100次输入,则会得到[100,65]维度的组合输出向量
} 依次完成上述64次训练,则会得到[64,100,65]维度的组合输出向量
# 对于一批训练获得的[64,100,65]维度的组合输出
#reshape其维度,则可得到输出为[64*100,65]的组合输出,
} 下一批训练时,再将该批GRU的状态输入到下一批GRU中,直到完成171批训练