Tensorflow实现LSTM
2017-10-14 16:48
627 查看
RNN和LSTM
RNN
RNN循环神经网络对处理时间系列的数据或周期性数据很有用。在传统的神经网络中,只是在深度上进行多层的连接,层与层之间具有连接,但是在同一层内部节点之间没有连接。这对于处理前后有关系的数据无能为力,RNN则考虑了这一点,在广度上也进行连接。具体的,RNN网络会对前面的信息进行记忆并应用于当前的输出的计算中,即隐藏层的输入不仅包含输入层的输出还包含上一时刻隐藏层的输出。
理论上,RNN可以接受任何长度的输入,但是在实践中,为了降低复杂性,我们一般假设当前状态只与前面几个状态相关。比如手写字体的 28*28 图片, 一般把下一行像素当作是上一行元素的下一时刻,那么相应的RNN输入节点就为28个,RNN的Step为28。
接下来看RNN的输入:seq/step时间序列, 对于一个28*28图像来说,可以看做是step为28,输入为28。因此tf中输入纬度[batch_size, seq_length, rnn_size], 其中rnn_size是对应的节点数
而对于tensorflow定义的RNN的输入来说,每次需要输入的是step=seq_length的(batch_size, rnn_size)这样的一层层上下文计算,对于每一个step得到相应的state状态以及输出。
LSTM
RNN可以使用历史的信息来帮助当前的决策,但是在某些问题中仅仅需要短期内的信息来执行当前的任务,RNN就可以实现利用先前的信息。但是对于某些问题,要需要之前很长一段的信息来进行决策。RNN的性能就受到了限制,因此LSTM自然而然的产生的。
LSTM通过一些“门”(输入门、遗忘门、输出门)结构让信息有选择性的影响循环神经网络中的每个时刻的状态。这里的所谓的‘门’就是sigmoid神经网络和一个按位做乘法的操作。之所以叫做门:就是因为sigmoid激活函数的全连接神经网络会输出0到1之间的数值,描述当前输入有多少信息量可以通过这个结构。
遗忘门的作用是让RNN“忘记”之前没有用的信息。输入门的作用是根据当前节点输入xt,之前状态c(t-1),上一时刻输出h(t-1)决定当前哪些信息进入到当前的ct。
LSTM结构通过输入们和遗忘门决定哪些信息被遗忘,哪些信息得到保留。
# 这里用mnist数据集来简单说明下lstm的搭建 import numpy as np import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data
# 首先观察下数据 mnist = input_data.read_data_sets('MNIST_data/', one_hot=True) print(mnist.train.images.shape)
Extracting MNIST_data/train-images-idx3-ubyte.gz Extracting MNIST_data/train-labels-idx1-ubyte.gz Extracting MNIST_data/t10k-images-idx3-ubyte.gz Extracting MNIST_data/t10k-labels-idx1-ubyte.gz (55000, 784)
由于mnist得到的输出是一行向量,因此在输入之前要进行reshape, X.reshape(batch_size, n_step, n_input)
另外原始的RGB图像数据是[weight,hight, channel],对应到RNN 即为[input_size, step, channel],因此首先对图像的纬度进行交换:
tf.transpose(X, [1, 0, 2])
将原来为[0, 1, 2]的X纬度交换为[0, 1, 2]。
对于RNN的输入(batch_size, rnn_size)还要再次reshape tf.reshape(X, [-1, n_input])
# 使用LSTM来实现mnist的分类,将输入28*28的图像每一行看作输入像素序列,行行之间具有时间信息。即step=28 # 设置超参数 #超参数 lr = 0.001 training_inter = 100000 batch_size = 128 # display_step = 10 # n_input = 28 # w n_step = 28 # h n_hidden = 128 n_classes = 10 # placeholder x = tf.placeholder(tf.float32, [None, n_input, n_step]) y = tf.placeholder(tf.float32, [None, n_classes]) weights = { 'in': tf.Variable(tf.random_normal([n_input, n_hidden])), # (28, 128) 'out': tf.Variable(tf.random_normal([n_hidden, n_classes])) # (128, 10) } biases = { 'in': tf.Variable(tf.constant(0.1, shape=[n_hidden])), 'out': tf.Variable(tf.constant(0.1, shape=[n_classes])) } def RNN(x, weights, biases): # 原始的x是3维,需要将其变为2为的,才能和weight矩阵乘法 # x=(128, 28, 28) ->> (128*28, 28) X = tf.reshape(x, [-1, n_input]) X_in = tf.matmul(X, weights['in']) + biases['in'] # (128*28, 128) X_in = tf.reshape(X_in, [-1, n_step, n_hidden]) # (128, 28, 128) # 定义LSTMcell lstm_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden) init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32) outputs, final_state = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False) results = tf.matmul(final_state[1], weights['out']) + biases['out'] return results pre = RNN(x, weights, biases) cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pre)) train_op = tf.train.AdamOptimizer(lr).minimize(cost) correct_pred = tf.equal(tf.argmax(pre, 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_inter: batch_xs, batch_ys = mnist.train.next_batch(batch_size) batch_xs = batch_xs.reshape([batch_size, n_step, n_input]) 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
0.203125 0.664063 0.734375 0.796875 0.875 0.882813 0.882813 0.921875 0.90625 0.929688 0.921875 0.867188 0.945313 0.9375 0.929688 0.898438 0.945313 0.960938 0.921875 0.945313 0.953125 0.953125 0.945313 0.976563 0.945313 0.984375 0.96875 0.945313 0.96875 0.96875 0.976563 0.96875 0.945313 0.945313 0.976563 1.0 0.960938 0.984375 0.984375 0.976563
注:
在tensorflow中实现LSTM的主要三句为:tf.contrib.rnn.BasicLSTMCell(n_hidden) init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32) outputs, final_state = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False)
其中: 若 time_major =False, input的格式为[batch, steps inputs] 否则为 [steps, batch, inputs]
相关文章推荐
- 利用 TensorFlow 高级 API Keras 实现 MLP,CNN,LSTM
- 解读tensorflow之rnn 的示例 ptb_word_lm.py 这两天想搞清楚用tensorflow来实现rnn/lstm如何做,但是google了半天,发现tf在rnn方面的实现代码或者教程
- TensorFlow 实现多层 LSTM 的 MNIST 分类 + 可视化
- TensorFlow (RNN)深度学习 双向LSTM(BiLSTM)+CRF 实现 sequence labeling 序列标注问题 源码下载
- 深度学习(08)_RNN-LSTM循环神经网络-03-Tensorflow进阶实现
- tensorflow38《TensorFlow实战》笔记-07-02 TensorFlow实现基于LSTM的语言模型 code
- TensorFlow实现基于LSTM的语言模型
- 如何基于TensorFlow使用LSTM和CNN实现时序分类任务
- LSTM模型简介及Tensorflow实现
- 一文详解如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
- Tensorflow实现基于Bidirectional LSTM Classifier
- tensorflow39《TensorFlow实战》笔记-07-03 TensorFlow实现Bidirectional LSTM Classifier code
- Tensorflow实现基于LSTM的文本分类方法
- 86、使用Tensorflow实现,LSTM的时间序列预测,预测正弦函数
- tensorflow 学习专栏(七):使用RNN (LSTM)实现mnist手写数据集分类
- Tensorflow实现 Bidirectional LSTM Classifier
- tensorflow实现基于LSTM的文本分类方法
- RNN-LSTM循环神经网络-03Tensorflow进阶实现
- 如何用 TensorFlow 实现基于 LSTM 的文本分类
- Tensorflow实战学习(三十五)【实现基于LSTM语言模型】