长短期记忆(LSTM)是在深度学习领域中使用的人工循环神经网络(RNN)架构。它是由 Sepp Hochreiter 和 Jurgen schmidhuber 在1997年提出的。与标准前馈神经网络不同,LSTM具有反馈连接。它不仅可以处理单个数据点(例如图像),还可以处理整个数据序列(例如语音或视频)。
例如, LSTM是用于未分段,连接的手写识别,或语音识别等任务的应用程序。
一般的 LSTM 单元由一个单元,一个Input Gate,一个Output Gate和一个Forget Gate组成。单元会记住任意时间间隔内的值,并且三个Gate控制着进出单元的信息流。 LSTM非常适合对未知持续时间给出的时间序列进行分类,处理和预测。
1. Input Gate - 它发现应该使用输入中的哪个值来修改内存。 Sigmoid 函数确定要让0或1允许的值。 tanh 函数对所传递的值进行加权,并确定其重要性级别为 -1 到 1 。
2. Forget Gate - 它会发现要从块中丢弃的详细信息。Sigmoid函数决定。它查看先前的状态(ht-1)和内容输入(Xt),并为单元格状态 Ct-1 。中的每个数字输出一个介于0(忽略此)和1(保留这个)之间的数字>
3. Output Gate - 块的输入和存储器用于确定输出。 Sigmoid函数确定要让0或1允许的值。 tanh 函数要让0或1允许的值。tanh函数对所传递的值进行加权,从而确定其重要性范围从 -1到1 并乘以 Sigmoid 的输出。
它代表一个完整的RNN单元,该单元采用序列xi的当前输入,并输出当前隐藏状态hi,将其传递给输入序列的下一个RNN单元。 LSTM单元的内部比传统RNN单元复杂得多,而常规RNN单元具有作用于当前状态(ht-1)和输入(xt)的单个"内部层"。
在上图中,无涯教程看到了一个"未展开的" LSTM网络,该网络具有一个嵌入层,一个随后的 LSTM 层和一个S型激活函数。认识到输入(在这种情况下,即电影评论中的单词)是按顺序输入的。
单词被输入到嵌入查找中。在大多数情况下,使用文本数据集时,词汇量异常大。
这是向量空间中单词的多维分布表示。可以使用其他深度学习技术(例如 word2vec )来学习这些嵌入,可以以端到端的方式训练模型,以便根据教学来确定嵌入。
然后将这些嵌入内容输入到的 LSTM层,在这里,输出将被馈送到S型输出层和 LSTM单元格,用于序列中的下一个单词。
将建立一个函数来构建LSTM层,以动态处理层数和大小。该服务将获取一个LSTM大小列表,该列表可以根据列表的长度指示LSTM层的数量(例如,示例将使用长度为2的列表,其中包含大小为128和64的LSTM列表,表示两层LSTM网络其中第一层尺寸128和第二层具有隐藏层尺寸64)。
def build_lstm_layers(lstm_sizes, embed, keep_prob_, batch_size): """ Create the LSTM layers """ lstms = [tf.contrib.rnn.BasicLSTMCell(size) for size in lstm_sizes] # Add dropout to the cell drops = [tf.contrib.rnn.DropoutWrapper(lstm, output_keep_prob=keep_prob_) for lstm in lstms] # Stacking up multiple LSTM layers, for deep learning cell = tf.contrib.rnn.MultiRNNCell(drops) # Getting an initial state of all zeros initial_state = cell.zero_state(batch_size, tf.float32) lstm_outputs, final_state = tf.nn.dynamic_rnn(cell, embed, initial_state=initial_state)
然后,将丢失的包裹LSTM列表传递到TensorFlow MultiRNN 单元,以将各层堆叠在一起。
最后,创建函数来定义模型损失函数,优化器和准确性。即使只是根据结果计算损失和准确性,但在TensorFlow中所有内容都是计算图的一部分。
def build_cost_fn_and_opt(lstm_outputs, labels_, learning_rate): """ Creating the Loss function and Optimizer """ predictions = tf.contrib.layers.fully_connected(lstm_outputs[:, -1], 1, activation_fn=tf.sigmoid) loss = tf.losses.mean_squared_error(labels_, predictions) optimzer = tf.train.AdadeltaOptimizer (learning_rate).minimize(loss) def build_accuracy(predictions, labels_): """ Create accuracy """ correct_pred = tf.equal(tf.cast(tf.round(predictions), tf.int32), labels_) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
首先,无涯教程调用已定义的用于构建网络的每个函数,并调用TensorFlow会话以使用迷你批处理在预定义数量的纪元上训练模型。在每个阶段结束时,将打印损失,训练准确性和验证准确性,以在训练模型时监视结果。
def build_and_train_network(lstm_sizes, vocab_size, embed_size, epochs, batch_size, learning_rate, keep_prob, train_x, val_x, train_y, val_y): # Build Graph with tf.Session() as sess: # Train Network # Save Network
接下来,定义模型超参数,然后将构建一个两层LSTM网络,其隐藏层大小分别为 128 和 64 。
在完成模型训练后,使用TensorFlow保护程序保存模型参数供以后使用。
Epoch: 1/50 Batch: 303/303 Train Loss: 0.247 Train Accuracy: 0.562 Val Accuracy: 0.578 Epoch: 2/50 Batch: 303/303 Train Loss: 0.245 Train Accuracy: 0.583 Val Accuracy: 0.596 Epoch: 3/50 Batch: 303/303 Train Loss: 0.247 Train Accuracy: 0.597 Val Accuracy: 0.617 Epoch: 4/50 Batch: 303/303 Train Loss: 0.240 Train Accuracy: 0.610 Val Accuracy: 0.627 Epoch: 5/50 Batch: 303/303 Train Loss: 0.238 Train Accuracy: 0.620 Val Accuracy: 0.632 Epoch: 6/50 Batch: 303/303 Train Loss: 0.234 Train Accuracy: 0.632 Val Accuracy: 0.642 Epoch: 7/50 Batch: 303/303 Train Loss: 0.230 Train Accuracy: 0.636 Val Accuracy: 0.648 Epoch: 8/50 Batch: 303/303 Train Loss: 0.227 Train Accuracy: 0.641 Val Accuracy: 0.653 Epoch: 9/50 Batch: 303/303 Train Loss: 0.223 Train Accuracy: 0.646 Val Accuracy: 0.656 Epoch: 10/50 Batch: 303/303 Train Loss: 0.221 Train Accuracy: 0.652 Val Accuracy: 0.659
最后,在测试集上检查模型结果,以确保它们与在训练中观察到的结果一致。
def test_network(model_dir, batch_size, test_x, test_y): # Build Network with tf.Session() as sess: # Restore Model # Test Model
测试准确性为 72%。这完全符合无涯教程的验证准确性,并表明在数据拆分过程中以适当的数据分布捕获了数据。
INFO:tensorflow:Restoring parameters from checkpoints/sentiment.ckpt Test Accuracy: 0.717
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)