循环神经网络变长文本处理

LSTM实现变长文本处理

https://img-blog.csdn.net/20171010144849872?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGN4MTk5Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

由于喂到模型中是fixed-size tensor(如256*100*50, batch size *sequence
length*embedding size),
RNN需要用mask来maintain序列真实长度,从而在计算loss的时候去除掉padding的部分。Padding和Mask是不一样的。Padding仅仅是补0,如果直接用到LSTM中这些0会参与计算,影响结果。因为LSTM中神经元不仅受当前状态影响,还会受之前状态影响,所以哪怕输入是0仍然可能会有非零输出。而mask是补0后还让LSTM在遇到0的时候溯回到上一个非零的状态,这样就相当于既统一了输入的长度,又告诉了模型每个输入的真实长度,避免这些补的0参与到输入中。

注意:rnn(
)可以利用buckets实现变长rnn的训练,虽然每个graph的RNN的time_step可能不同,但是在不同time_step间网络参数是共享的。所以对于不同的graph1和graph2,即使time_step参数不同,但所有网络参数是可以共享的。

对于dynamic_rnn( )与rnn( )有什么区别:

定义好了一个RNNCell,调用该RNNCell的call函数time_steps次,对应的代码就是:

outputs, state = tf.nn.dynamic_rnn(cell, inputs,
initial_state=initial_state)

得到的outputs就是time_steps步里所有的输出。它的形状为(batch_size, time_steps,
cell.output_size)。state是最后一步的隐状态,它的形状为(batch_size,
n(LSTMStateTuple)),这是因为LSTM的每层状态都是c与h构成的元组。state是整个seq输入完之后的得到的每层的state。如果有n
layer,则state有n个元素,对应每一层的state。

注意区分dynamic_run()与rnn()函数的区别

run()函数的输出.shape为[batch_size,
hidden_units_size],是某一t时刻的输出,对应着t时刻的输入[batch_size,
hidden_units_size]

而dynamic_run()的state强调序列最后一个时刻的输出,注意,是最后一个时刻!!!!!!!!!。而outputs仍然是各个时刻的输出。

其他坑:

preview

h就对应了BasicRNNCell的state_size。那么,y是不是就对应了BasicRNNCell的output_size呢?答案是否定的

方法一:

调用 dynamic_rnn() 来让我们构建好的网络运行起来

outputs,state=tf.nn.dynamic_rnn(mlstm_cell,inputs=X,initial_state=init_state,time_major=False)

当 time_major==False 时,

outputs.shape=[batch_size,timestep_size,hidden_size]

State存储各个隐层状态值,包括h_state与c_state【layer_num, 2, batch_size,
hidden_size】

h_state = outputs[:, -1, :]或者h_state = state[-1][1]

最后输出维度是 [batch_size, hidden_size]

写项目遇到的坑:

  1. 首先是有一个叫做int(
    )的参数不能是Variable,比如我想动态调整batch_size时,那么我的batch_size会被设置为变量Variable,在进行

self._initial_state=cell.zero_state(self.batch_size, dtype=tf.float32)报错

这时我们可以用强制类型转换,如下所示:

self._initial_state=cell.zero_state(tf.cast(self.batch_size,tf.int32),
dtype=tf.float32)

  1. Tf.graph()可以用来建立一个新的图

假如我们用g1=tf.Graph()建立了一个图之后,

With g1.as_default( ):

图内容

上述代码会把g1设置为默认图,当退出上述上下文环境后,系统默认图便不再是g1,而是原来默认的计算图。

  1. for time_step in range(num_step):

(cell_output,state)=cell(inputs[:,time_step,:],state)

Out_put.Append(cell_output)

其中输出cell_output这个time_step的输出,维度为[batch_size,
hidden_units],所以最后的out_put维度为[time_step, batch_size, hidden_units]

  1. reduce_sum(),reduce_mean()表示沿着某一维度压扁并进行运算

  2. Tensorboard到底指到哪个目录结构由tf.summary.FileWriter(
    )决定,该函数的路径参数即是tensorboard的指定路径

  3. 三维矩阵相乘,为对应页相乘

C:\Users\jzeng\Documents\Tencent
Files\1534357193\FileRecv\MobileFile\P80425-195942.jpg

循环神经网络处理变长文本

有多种方法:比如dynamic_rnn( )或者建立mask_x矩阵

在使用RNN的时候,需要指定num_step,也就是Tensorflow的roll
step步数,但对于变长的文本而言,指定num_step不可避免的需要执行padding操作,用mask方法先自动padding,再对padding的内容进行删除,需要我们定义mask矩阵。除了mask方法,tensorflow还提供了一种更为优雅的dynamic_rnn的方法