您的位置:首页 > 其它

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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: