deep_learning 01. tf.nn.rnn_cell.BasicRNNCell()

开始的话:
学习了快一年的深度学习中自然语言处理相关的知识包括:各种各样的模型、各类的task,也参加了各种各样的比赛。所以准备好好整理下自己学过的这些知识,从头开始,打好基础(代码基础和理论基础)。为成为一个从容的有经验的攻城狮不断努力。
一位爱生活爱技术来自火星的程序汪

RNN 想必从开始学习深度学习的时候就开始接触这个很简单但是很重要的结构了。
所以今天就先从 RNN 开始我的笔记之旅吧!
话不多说先上图:
basic_rnn.png

t t t-> 表示不同的时间步
X t X_t Xt -> 表示此时刻的输入
O t O_t Ot -> 表示此时刻的输出
W W W -> 表示cell中的weights

这里的 S t S_t St的输出 O t O_t Ot,不仅仅取决于 X t X_t Xt,同时还取决于 S t − 1 S_{t-1} St1的值。

公式为(在tensorflow的源码实现中会有一点差别后面再讲):

S t = f 1 ( U X t + W S t − 1 ) S_t = f_1(UX_t + WS_{t-1}) St=f1(UXt+WSt1)
S t = f 2 ( V S t ) S_t = f_2(VS_t) St=f2(VSt)

f f f 表示的就是激活函数activation,在basic_rnn的tensorflow代码中,没有指定的话,默认就是tanh作为激活函数。
下面就从代码角度看下:

def basic_rnn_demo():

    cell = tf.nn.rnn_cell.BasicRNNCell(num_units=4)
    zero_state = cell.zero_state(batch_size=2, dtype=tf.float32)
    a = tf.random_normal([2, 3, 4])
    out, state = tf.nn.dynamic_rnn(
        cell=cell,
        initial_state=zero_state,
        inputs=a
    )
    print(out)
    print(state)

tf.nn.rnn_cell.BasicRNNCell 是最基础的一个RNN的实现了,接下来就说明下这个方法具体做了些什么。
下面这段代码是主要的实现源码

  def call(self, inputs, state):
    """Most basic RNN: output = new_state = act(W * input + U * state + B)."""

    gate_inputs = math_ops.matmul(
        array_ops.concat([inputs, state], 1), self._kernel)
    gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
    output = self._activation(gate_inputs)
    return output, output

结合demo代码说明下具体流程

	Most basic rnn
    tanh(W * input + U * state + B)

    #   inputs [2,3,4]  state = [2,4]
    #   unstack(inputs) = 3 size [2,4]
    #   每次进行的是每个batch中的第一个字
    #   a = [2, 8]
    #	zero_state 也可以不传,但是要指定dtype,这样会自己初始化一个zero_state了
    #	这里可以看到此时刻的输入和上一时刻的state也就是上一刻的输出指直接concat
    #	然后和weights做matmul
    a = concat([inputs,state], 1)
    #   kernel_ = [8, 4] inputs_dim=4 num_units=4 kernel_在每个时间步都是共享的
    kernel_ = [inputs_dim + num_units,num_units]
    #   b = [2, 4]
    b = matmul(a, kernel_)
    #   c = [2, 4] bias初始化为0 bias 在每个时间步都是共享的
    c = b + bias
    #   [2, 4]
    #   会返回一个tuple,内容都是output,一个作为此时刻的state,这样state就可以了从第一个一直往后更新(默认的activation就是tanh)
    output,output = tanh(c)

dynamic_rnn和static_rnn,前者支持变长,后者不支持。并且前者是循环展开每一个cell,更加的高效,而后者是创建一个静态的graph。

tf.nn.rnn creates an unrolled graph for a fixed RNN length. 
That means, if you call tf.nn.rnn with inputs having 200 time steps you are creating a static graph with 200 RNN steps. 
First, graph creation is slow. 
Second, you’re unable to pass in longer sequences (> 200) than you’ve originally specified.
tf.nn.dynamic_rnn solves this. 
It uses a tf.While loop to dynamically construct the graph when it is executed. 
That means graph creation is faster and you can feed batches of variable size.

output,state = tf.nn.dynamic_rnn()

out的shape为: [2, 3, 4] 表示的是每个时间步的输出

    tf.Tensor(
    [[[ 0.7875833   0.11634824  0.31249827  0.11648687]
      [ 0.6418752  -0.9281747   0.6534868   0.3821376 ]
      [ 0.9750985  -0.40439364  0.9770327   0.8529797 ]]
    
     [[-0.09945039 -0.49678802 -0.32603818  0.20098403]
      [-0.57557577  0.15389016 -0.7197561  -0.36572933]
      [ 0.4485007  -0.51780844 -0.6015551   0.16041796]]], shape=(2, 3, 4), dtype=float32)

state的shape为: [2, 4] 表示最后的状态输出

tf.Tensor(
    [[ 0.9750985  -0.40439364  0.9770327   0.8529797 ]
     [ 0.4485007  -0.51780844 -0.6015551   0.16041796]], shape=(2, 4), dtype=float32)

更多代码请移步我的个人github,会不定期更新各种框架。
本章代码见code
欢迎关注

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值