深度學習之循環神經網絡RNN概述,雙向LSTM實現字符識別


深度學習之循環神經網絡RNN概述,雙向LSTM實現字符識別

2. RNN概述

Recurrent Neural Network - 循環神經網絡,最早出現在20世紀80年代,主要是用於時序數據的預測和分類。它的基本思想是:前向將上一個時刻的輸出和本時刻的輸入同時作為網絡輸入,得到本時刻的輸出,然后不斷地重復這個過程。后向通過BPTT(Back Propagation Through Time)算法來訓練得到網絡的權重。RNN比CNN更加徹底的是,CNN通過卷積運算共享權重從而減少計算量,而RNN從頭到尾所有的權重都是公用的,不同的只是輸入和上一時刻的輸出。RNN的缺點在於長時依賴容易被遺忘,從而使得長時依賴序列的預測效果較差。

LSTM(Long Short Memory)是RNN最著名的一次改進,它借鑒了人類神經記憶的長短時特性,通過門電路(遺忘門,更新門)的方式,保留了長時依賴中較為重要的信息,從而使得RNN的性能大幅度的提高。
為了提高LSTM的計算效率,學術界又提供了很多變體形式,最著名的要數GRU(Gated Recurrent Unit),在減少一個門電路的前提下,仍然保持了和LSTM近似的性能,成為了語音和nlp領域的寵兒。

這篇文章翻譯自海外著名的一篇RNN的科普博客,具有很好的借鑒意義。

3. 雙向LSTM實現字符識別

下面的代碼實現了一個雙向的LSTM網絡來進行mnist數據集的字符識別問題,雙向的LSTM優於單向LSTM的是它可以同時利用過去時刻和未來時刻兩個方向上的信息,從而使得最終的預測更加的准確。

Tensorflow提供了對LSTM Cell的封裝,這里我們使用BasicLSTMCell,定義前向和后向的LSTM Cell:

lstm_fw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0)
lstm_bw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0)
然后通過static_bidrectional_rnn函數將這兩個cell以及時序輸入x進行整合:

outputs, _, _ = tf.contrib.rnn.static_bidirectional_rnn(
lstm_fw_cell,
lstm_bw_cell,
x,
dtype=tf.float32
)
完整的代碼如下:

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data", one_hot=True)

learning_rate = 0.01
max_samples = 400000
batch_size = 128
display_step = 10

n_input = 28
n_steps = 28
n_hidden = 256
n_classes = 10

x = tf.placeholder(tf.float32, [None, n_steps, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])

weights = tf.Variable(tf.random_normal([2 * n_hidden, n_classes]))
biases = tf.Variable(tf.random_normal([n_classes]))


def BiRNN(x, weights, biases):
x = tf.transpose(x, [1, 0, 2])
x = tf.reshape(x, [-1, n_input])
x = tf.split(x, n_steps)

lstm_fw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0)
lstm_bw_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0)

outputs, _, _ = tf.contrib.rnn.static_bidirectional_rnn(
lstm_fw_cell,
lstm_bw_cell,
x,
dtype=tf.float32
)
return tf.matmul(outputs[-1], weights) + biases

pred = BiRNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,
labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).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 = 1
while step * batch_size < max_samples:
batch_x, batch_y = mnist.train.next_batch(batch_size)
batch_x = batch_x.reshape((batch_size, n_steps, n_input))
sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})
if step % display_step == 0:
acc = sess.run(accuracy, feed_dict={x: batch_x, y: batch_y})
loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y})
print ("Iter" + str(step * batch_size) + ", Minibatch Loss=" + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print ("Optimization Finishes!")

test_len = 50000
test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
test_label = mnist.test.labels[:test_len]
print ("Testing accuracy:",
sess.run(accuracy, feed_dict={x: test_data, y: test_label}))
這里選擇了400000個sample進行訓練,圖像按行讀入像素序列(總共n_step=28行),每128個樣本看成一個batch做一次BPTT,每10個batch打印一次training loss。

Iter396800, Minibatch Loss=0.038339, Training Accuracy= 0.98438
Iter398080, Minibatch Loss=0.007602, Training Accuracy= 1.00000
Iter399360, Minibatch Loss=0.024104, Training Accuracy= 0.99219
Optimization Finishes!
取50000個樣本作為測試集,准確率為:

('Testing accuracy:', 0.98680007)
可以發現,雙向LSTM做圖像分類雖然也有不錯的性能,但是還是比CNN略微遜色。主要原因應該還是因為圖像數據屬於層次性比較高的數據,CNN能夠逐層抽取圖像的層次特征,從而達到比較高的精度。
但是可以想象,對於時序性比較強的無空間結構數據,RNN會有更加出色的表現。

===================

CNN是做圖像識別的,對彩票一點用都沒有。彩票預測分為兩種,一直是M選N型,比如雙色球,大樂透,另外一種是M選1型,比如福彩3d在各位上選一個。

M選1型 的可以用非線性回歸算法進行預測。KNN這個是典型的非線下回歸算法,測試效果並不理想。貝葉斯,隨機森林,SVM, GBDT可以測試看看。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM