一、循环神经网络原理
式一计算输出层,式2计算隐层
将式2带入式1结果如上图所示,这就是为什么循环神经网络可以往前看任意多个输入值的原因。
二、rnn的训练算法bptt
BPTT算法是针对循环层的训练算法,它的基本原理和BP算法是一样的,也包含同样的三个步骤:
1. 前向计算每个神经元的输出值;
2. 反向计算每个神经元的误差项值,它是误差函数E对神经元j的加权输入的偏导数;
将第 l 层 t 时刻的误差值沿两个方向传播: 1,传到上一层神经网络,此时只与u有关。2,沿时间传,此时只与w有关
3,计算每个权重梯度:
用随机梯度下降法更新权重。
三、一个循环神经网络的示例:
1,输入一段话:我的家在东北松花江上
2,把词表达为one-hot n维向量形式(高维稀疏向量)
3,降维。例如tf.nn.embedding_lookup:用稀疏矩阵乘以词典=矩阵中的某一行
4,采用到 softmax 层作为输出层,用概率表示特征
5,训练:把语料转换成语言模型的训练数据集,即对输入 x 和标签 y 进行向量化,y 也是一个 one-hot 向量
在对概率进行建模,常用交叉熵误差函数作为优化目标
交叉熵误差函数:
小结过程:
有了模型,优化目标,梯度表达式,就可以用梯度下降算法进行训练了
四,各种rnn
1、双向循环神经网络:Bidirectional RNNs(双向循环神经网络)
即:当前的序列与前后序列均有关
Bidirectional RNNs是一个相对较简单的RNNs,是由两个RNNs上下叠加在一起组成的:
2、深层循环神经网络:Deep(Bidirectional)RNNs(深层循环神经网络)
即在brnns上多加了几个隐层:
3、GRU:一般的RNNs的改良版本
改进:1.前一状态对当前影响进行了距离加权。越前面的序列对当前隐藏层的影响越小,例如:我的家在东北松花江上,其中’家‘对’上‘的影响就很小
2.仅对引发误差的单词进行权值更新
GRUs的结构如下图所示:
当reset gate为1的时候,new memory content忽略之前的所有memory content,最终的memory是之前的hidden state与new memory content的结合。
4、LSTM:Long Short Term Memory networks长短期记忆神经网络
改进:传统的 RNN 每个神经元和一般神经网络的感知机没区别,但在 LSTM 中,每个神经元是一个“记忆细胞”,细胞里面有一个“输入门”(input gate), 一个“遗忘门”(forget gate), 一个“输出门”(output gate),俗称“三重门”。
五、RNN的tensorflow源码实现
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.set_random_seed(1)
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# hyperparameters
lr = 0.001
training_iters = 100000
batch_size = 128
n_inputs = 28 # shape 28*28
n_steps = 28 # time steps
n_hidden_unis = 128 # neurons in hidden layer
n_classes = 10 # classes 0-9
# tf Graph input
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])
# Define weights
weights = {
# (28,128)
'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_unis])),
# (128,10)
'out': tf.Variable(tf.random_normal([n_hidden_unis, n_classes]))
}
biases = {
# (128,)
'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_unis, ])),
# (10,)
'out': tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}
def RNN(X, weights, biases):
# hidden layer for input to cell
# X(128 batch, 28 steps, 28 inputs) => (128*28, 28)
X = tf.reshape(X, [-1, n_inputs])
# ==>(128 batch * 28 steps, 28 hidden)
X_in = tf.matmul(X, weights['in'])+biases['in']
# ==>(128 batch , 28 steps, 28 hidden)
X_in = tf.reshape(X_in,[-1, n_steps, n_hidden_unis])
# cell
lstm_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden_unis, forget_bias=1.0, state_is_tuple=True)
# lstm cell is divided into two parts(c_state, m_state)
_init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
outputs, states = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=_init_state, time_major=False)
# hidden layer for output as the final results
results = tf.matmul(states[1], weights['out']) + biases['out'] # states[1]->m_state states[1]=output[-1]
# outputs = tf.unstack(tf.transpose(outputs,[1,0,2]))
# results = tf.matmul(outputs[-1], weights['out']) + biases['out']
return results
pred = RNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
step = 0
while step * batch_size < training_iters:
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
sess.run([train_op], feed_dict={
x: batch_xs,
y: batch_ys
})
if step % 20 ==0:
print (sess.run(accuracy, feed_dict={
x: batch_xs,
y: batch_ys
}))
step += 1
参考文献:
http://lib.csdn.net/article/aiframework/66348?knId=1756