心胸决定格局,眼界决定境界...

rnn 手写代码理解

RNN主要用途是处理和预测序列数据

RNN广泛的用于 语音识别、语言模型、机器翻译

RNN的来源就是为了刻画一个序列当前的输出与之前的信息影响后面节点的输出

RNN 是包含循环的网络,允许信息的持久化

RNN会记忆之前的信息,并利用之前的信息影响后面节点的输出

RNN的隐藏层之间的节点是有相连的,隐藏层的输入不仅仅包括输入层的输出,还包括上一时刻隐藏层的输出。

RNN会对于每一个时刻的输入结合当前模型的状态给出一个输出

RNN理论上被看作同一个神经网络结构被无限复制的结果,目前RNN无法做到真正的无限循环,一般以循环体展开。

RNN图:

RNN最擅长的问题是与时间序列相关的

RNN对于一个序列数据,可以将序列上不同时刻的数据依次输入循环神经网络的输入层,而输出可以是对序列中下一个时刻的预测,也可以是对当前时刻信息的处理结果。

RNN 的关键点之一就是他们可以用来连接先前的信息到当前的任务上

展开后的RNN

循环体网络中的参数在不同的时刻也是共享的

RNN的状态是通过一个向量来表示,这个向量的维度也称为RNN隐藏层的大小

假如该向量为h,输入为x,激活函数为tanh,则有如图:

前向传播的计算过程:

 

理论上RNN可以支持任意长度的序列,但是如果序列太长会导致优化时实现梯度消失的问题,一般会设置最大长度,超长会对其截断。

 代码实现简单的RNN:

import numpy as np
  
# 定义RNN的参数。
#序列长度为1*2 X = [1,2]
#隐层两个节点 state = [0.0, 0.0]
#隐层间的权重大小为2*2; w_cell_state = np.asarray([[0.1, 0.2], [0.3, 0.4]])
#隐层两个节点,输入层到隐层的权重为 1*2 X 输入层节点为1,time_step为2(等于序列长度) w_cell_input = np.asarray([0.5, 0.6])
#隐层两个节点,偏置为1*2 b_cell = np.asarray([0.1, -0.1])
#输出层节点为1,所以权重大小为2*1 w_output = np.asarray([[1.0], [2.0]])
#输出层节点为1,偏置也为1 b_output = 0.1 # 执行前向传播过程。 for i in range(len(X)):#按照time_step展开 before_activation = np.dot(state, w_cell_state) + X[i] * w_cell_input + b_cell state = np.tanh(before_activation)#更新 state final_output = np.dot(state, w_output) + b_output #计算出output print ("before activation: ", before_activation) print ("state: ", state) print ("output: ", final_output)

  

LSTM(long short-term memory)长短时记忆网络

import tensorflow as tf 
  
  
# 定义一个LSTM结构 
lstm = rnn_cell.BasicLSTMCell(lstm_hidden_size) 
  
# 将LSTM中的状态初始化为全0数组,每次使用一个batch的训练样本 
state = lstm.zero_state(batch_size,tf.float32) 
  
# 定义损失函数 
loss = 0.0
  
# 规定一个最大序列长度 
for i in range(num_steps): 
  # 复用之前定义的变量 
  if i > 0: 
    tf.get_variable_scope().reuse_variables() 
  # 将当前输入和前一时刻的状态传入定义的LSTM结构,得到输出和更新后的状态 
  lstm_output, state = lstm(current_input,state) 
    
  # 将当前时刻的LSTM结构的输出传入一个全连接层得到最后的输出。 
  final_output = fully_connectd(lstm_output) 
    
  # 计算当前时刻输出的损失 
  loss += calc_loss(final_output,expected_output)

 

posted @ 2018-10-08 18:23  WELEN  阅读(1134)  评论(0)    收藏  举报