1、MLP,很好理解,就是一张网络清楚地显示了张量流向。general MLP是这样的拓扑: Xi 为输入特征向量,蓝色中间层为多个隐藏层,Y对应的是输出向量。



MLP模型python MLP模型 结果 怎样输出_MLP模型python



CNN也好理解,跟MLP无差若干  。CNN是这样的拓扑:


MLP模型python MLP模型 结果 怎样输出_深度学习_02




RecurrentNNs 结构理解


的拓扑发生了一个很大的改动,即一个MLP会在time_step这个维度上进行延伸,每个时序都会有input。


将1中的MLP图旋转并引入时间概念,如下视频




视频中的t我们称为时间步(time_step),每个t称为1步,t1-t5为1个周期。然后引入记忆概念。把上一个时间步产生的结果( Yt-1 )同X一起输入进去。RNN之所以有记忆力,是因为在每个t完成后,其产生的结果会在下一个t开始时,与X一起输送给RNN运算,相当于输入中包含了之前所有t的「精华」


或者可以参考这个图




MLP模型python MLP模型 结果 怎样输出_深度学习_03


每个时序t的输入 MLP模型python MLP模型 结果 怎样输出_词向量_04是一次time_step一张input tensor,隐状态 MLP模型python MLP模型 结果 怎样输出_MLP模型python_05 也就代表了一张MLP的hidden layer的一个cell。输出 MLP模型python MLP模型 结果 怎样输出_词向量_06理解无异。注意,红色的箭头指向时间维度。


4、简单例子讲解


例子1,文本分类


如果有一条长文本,给句子事先分割好句子,并且进行tokenize, dictionarize,接着再由look up table 查找到embedding,将token由embedding表示,再对应到上图的输入。流程如下


step1, raw text:  
  

   接触LSTM模型不久,简单看了一些相关的论文,还没有动手实现过。然而至今仍然想不通LSTM神经网络究竟是怎么工作的。…… 
 
  

  
   step2, tokenize (中文得分词):  
  

   sentence1: 接触 LSTM 模型 不久 ,简单 看了 一些 相关的 论文 , 还 没有 动手 实现过 。 
 
  

   sentence2: 然而 至今 仍然 想不通 LSTM 神经网络 究竟是 怎么 工作的。 
 
  

   …… 
 
  

  
   step3, dictionarize:  
  

   sentence1: 1 34 21 98 10 23 9 23 
 
  

   sentence2: 17 12 21 12 8 10 13 79 31 44 9 23 
 
  

   …… 
 
  

  
   step4, padding every sentence to fixed length:  
  

   sentence1: 1 34 21 98 10 23 9 23 0 0 0 0 0 
 
  

   sentence2: 17 12 21 12 8 10 13 79 31 44 9 23 0 
 
  

   …… 
 
  

  
   step5, mapping token to an embeddings:  
  

   sentence1:



MLP模型python MLP模型 结果 怎样输出_深度学习_07


,每一列代表一个词向量,词向量维度自行确定;矩阵列数固定为time_step length。

sentence2:

……


step6, feed into RNNs as input:

假设 一个RNN的time_step 确定为l, 则padded sentence length(step5中矩阵列数)固定为l。一次RNNs的run只处理一条sentence。每个sentence的每个token的embedding对应了每个时序t的输入 MLP模型python MLP模型 结果 怎样输出_词向量_04 。一次RNNs的run,连续地将整个sentence处理完。


step7, get output:

看图,每个time_step都是可以输出当前时序t的隐状态 MLP模型python MLP模型 结果 怎样输出_MLP模型python_05 ;但整体RNN的输出 MLP模型python MLP模型 结果 怎样输出_词向量_06 是在最后一个time_step  t=l 时获取,才是完整的最终结果。


step8, further processing with the output:

我们可以将output根据分类任务或回归拟合任务的不同,分别进一步处理。比如,传给cross_entropy&softmax进行分类……或者获取每个time_step对应的隐状态 MLP模型python MLP模型 结果 怎样输出_MLP模型python_05 ,做seq2seq 网络……或者搞创新……



例子2,mnist分类


MLP模型python MLP模型 结果 怎样输出_数据_12


在每一个时间步,维数是[batch_size,28]的数据进入LSTM。28表示每行数据的像素数目,一共有28行,也就是28个时间步,因此输入数据的维数是[batch_size,input_size,time_steps],输出数据的维数是[batch_size,num_units(LSTM隐藏层的个数),time_steps],但是我们只需要输出最后一个时间步的结果,维数是[batch_size,num_units],然后经过一个[num_units,num_class]的矩阵变换得到[batch_size,num_class]的输出结果,再和标准的结果比较计算Loss。


5、tensorflow 的一个简单例子的实现


import tensorflow as tf
import numpy as np

def dynamic_rnn(rnn_type='lstm'):

    X=np.random.rand(3,6,4)
    X[1,4:]=0
    X_length=[6,4,6]

    rnn_hidden_size=5
    if(rnn_type=='lstm'):
        cell=tf.contrib.rnn.BasicLSTMCell(num_units=rnn_hidden_size,state_is_tuple=True)
    else:
        cell=tf.contrib.rnn.GRUCell(num_units=rnn_hidden_size)

    num=cell.output_size

    outputs,last_states = tf.nn.dynamic_rnn(
        cell=cell,
        dtype=tf.float64,
        sequence_length=X_length,
        inputs=X
    )

    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        o1,s1 = session.run([outputs,last_states])
        print(X)
        print(np.shape(o1))
        print(o1)
        print(np.shape(s1))
        print(s1)
        print(num)


if __name__ == '__main__':
    dynamic_rnn(rnn_type='lstm')


代码分析


1)输入


LSTM单元中喂进的数据是一个3维数据,维度分别是input_size,batch_size,time_size。这里把X作为input的数据:


X=np.random.rand(3,6,4) #batch_size=3,time_size=6,input_size=4
 
input_size和Cell中的hidden_size有关;


time_size则是处理一组数据的步长;


batch_size则是用户自己选定的(通常开源文献中选为128、256等,从Memory中取出,再投喂给网络)


为了更好理解,将X的第二个batch的后两个步长数据置零,并通过X_length 设置掩码


2)构建网络


根据我们提供的hidden_size来创建LSTM单元

hidden_size=5
 
#创建LSTMcell
 
cell=tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size,state_is_tuple=True)
 
创建LSTM网络,  给上面的LSTM单元input等参数
 
outputs,last_states=tf.nn.dynamic_rnn(
 
    cell=cell,
 
    dtype=tf.float64,
 
    sequence_length=X_length,
 
input=X
 
    )
 
 
tf.nn.dynamic_run()有两个返回值,分别是outputs和last_states,这和LSTM的的结构是有关系的。
 
with tf.Session() as session:
 
    session.run(tf.global_variables_initializer())
 
    o1,s1 = session.run([outputs,lats_states])

3)输出


可以这样理解:o1指明了每个batch上的每个time_step的每个input的输出,而s1(=C_t + H_t)则表明了经过LSTM抽象处理后的最终结果。


[batch_size,time_size,hidden_size] 就是每一个batch 和step对应的输出特征


S1的维度为: [2,batch_size,hidden_size] 2是因为包含cell支路和ht支路,每个支路输出batch size个最后一个step结束后的特征(对应维度一般为hidden size)