循环神经网络应用案例
基礎介紹可以參考:
https://blog.csdn.net/lilong117194/article/details/82958326
https://blog.csdn.net/lilong117194/article/details/81978203
tensorflow的編程堆棧示意圖:
強烈建議使用以下API編寫TensorFlow程序:
- 評估器Estimators,代表一個完整的模型。 Estimator API提供方法來訓練模型,判斷模型的準確性并生成預測。
- 訓練集Datasets,它構建了一個數據輸入管道。Datasets API具有加載和操作數據的方法,并將其輸入到你的模型中。Datasets API與Estimators API良好地協作。
1. 基于TFlearn的iris分類
下面介紹利用tensorflow的一個高層封裝TFlearn。
iris數據集需要通過4個特征來分辨三種類型的植物,iris數據集中總共包含了150個樣本,下面是TFlearn解決iris分類問題:
數據集
鳶尾花數據集包含四個特征和一個標簽。這四個特征確定了單個鳶尾花的以下植物學特征:
- 萼片長度
- 萼片寬度
- 花瓣長度
- 花瓣寬度
下表顯示了數據集中的三個示例:
| 5.1 | 3.3 | 1.7 | 0.5 | 0(Setosa) |
| 5.0 | 2.3 | 3.3 | 1.0 | 1(Versicolor) |
| 6.4 | 2.8 | 5.6 | 2.2 | 2(virginica) |
完整代碼:
from sklearn import model_selection from sklearn import datasets from sklearn import metrics import tensorflow as tf import numpy as np from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat# 導入TFlearn learn = tf.contrib.learn# 自定義softmax回歸模型:在給定輸入的訓練集、訓練集標簽,返回在這些輸入上的預測值、損失值以及訓練步驟 def my_model(features, target):# 將預測目標轉化為one-hot編碼的形式,共有三個類別,所以向量長度為3target = tf.one_hot(target, 3, 1, 0)# 計算預測值及損失函數:封裝了一個單層全連接的神經網絡logits = tf.contrib.layers.fully_connected(features, 3, tf.nn.softmax)loss = tf.losses.softmax_cross_entropy(target, logits)# 創建模型的優化器,并優化步驟train_op = tf.contrib.layers.optimize_loss(loss, # 損失函數tf.contrib.framework.get_global_step(), # 獲取訓練步驟并在訓練時更新optimizer='Adam', # 定義優化器learning_rate=0.01) # 定義學習率# 返回給定數據集上的預測結果、損失值以及優化步驟return tf.arg_max(logits, 1), loss, train_op# 加載iris數據集,并劃分為訓練集和測試集 iris = datasets.load_iris() x_train, x_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, test_size=0.2, random_state=0)#將數據轉化成TensorFlow要求的float32格式 x_train, x_test = map(np.float32, [x_train, x_test])# 封裝和訓練模型,輸出準確率 classifier = SKCompat(learn.Estimator(model_fn=my_model, model_dir="Models/model_1")) classifier.fit(x_train, y_train, steps=100)# 預測 y_predicted = [i for i in classifier.predict(x_test)] # 計算準確度 score = metrics.accuracy_score(y_test, y_predicted)print('Accuracy: %.2f%%' % (score * 100))運行結果:
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_task_type': None, '_task_id': 0, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x12a8484e0>, '_master': '', '_num_ps_replicas': 0, '_num_worker_replicas': 0, '_environment': 'local', '_is_chief': True, '_evaluation_master': '', '_train_distribute': None, '_device_fn': None, '_tf_config': gpu_options {per_process_gpu_memory_fraction: 1.0 } , '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_secs': 600, '_log_step_count_steps': 100, '_session_config': None, '_save_checkpoints_steps': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_model_dir': 'Models/model_1'} INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from Models/model_1/model.ckpt-300 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 300 into Models/model_1/model.ckpt. INFO:tensorflow:loss = 0.66411054, step = 301 INFO:tensorflow:Saving checkpoints for 400 into Models/model_1/model.ckpt. INFO:tensorflow:Loss for final step: 0.64143056. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from Models/model_1/model.ckpt-400 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. Accuracy: 100.00%下圖說明了特征,隱藏層和預測(并未顯示隱藏層中的所有節點):
下面是評估器(Estimator)編程的基本概念:
Estimator是TensorFlow對完整模型的高級表示。它處理初始化,記錄,保存和恢復以及許多其他功能的細節。
Estimator是從tf.estimator.Estimator派生的通用類。 TensorFlow提供了一系列定制的評估器(例如LinearRegressor)來實現常用的ML算法。除此之外,也可以編寫自己的定制評估器。但建議在剛開始使用TensorFlow時使用內置的Estimator。在獲得內置的Estimator的專業知識后,就可以通過創建定制Estimator來優化模型。
要根據內置的Estimator編寫TensorFlow程序,必須執行以下任務:
- 創建一個或多個輸入函數。
- 定義模型的特征列。
- 實例化Estimator,指定特征列和各種超參數。
- 在Estimator對象上調用一個或多個方法,傳遞適當的輸入函數作為數據源。
2. lstm預測正弦函數
下面是利用lstm來實現預測正弦函數sin。
#!/usr/bin/env python3 # -*- coding: utf-8 -*-import numpy as np import tensorflow as tf from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat from tensorflow.python.ops import array_ops as array_ops_import matplotlib.pyplot as pltlearn = tf.contrib.learn# 設置神經網絡的參數 HIDDEN_SIZE = 30 # LSTM中隱藏的節點個數 NUM_LAYERS = 2 # LSTM的層數TIMESTEPS = 10 # 循環神經網路的截斷長度 TRAINING_STEPS = 3000 # 循環輪數 BATCH_SIZE = 32 # batch大小TRAINING_EXAMPLES = 10000 # 訓練數據的個數 TESTING_EXAMPLES = 1000 # 測試數據的個數 SAMPLE_GAP = 0.01 # 采樣間隔# 定義生成正弦數據的函數 def generate_data(seq):X = []y = []# 序列的第i項和后面的TIMESTEPS-1項合在一起作為輸入;第i + TIMESTEPS項作為輸# 出。即用sin函數前面的TIMESTEPS個點的信息,預測第i + TIMESTEPS個點的函數值。for i in range(len(seq) - TIMESTEPS):X.append([seq[i: i + TIMESTEPS]])y.append([seq[i + TIMESTEPS]])return np.array(X, dtype=np.float32), np.array(y, dtype=np.float32) # 用正弦函數生成訓練和測試數據集合。 test_start = (TRAINING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP # (10000+10)*0.01=100 test_end = test_start + (TESTING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP # 100+(1000+10)*0.01=110 train_X, train_y = generate_data(np.sin(np.linspace(0, test_start, TRAINING_EXAMPLES + TIMESTEPS, dtype=np.float32))) test_X, test_y = generate_data(np.sin(np.linspace(test_start, test_end, TESTING_EXAMPLES + TIMESTEPS, dtype=np.float32)))# 定義lstm模型 def lstm_model(X, y, is_training):# 使用多層的LSTM結構。cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE) for _ in range(NUM_LAYERS)]) # 使用TensorFlow接口將多層的LSTM結構連接成RNN網絡并計算其前向傳播結果。outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)#print(len(outputs))output = outputs[:, -1, :]# 對LSTM網絡的輸出再做加一層全鏈接層并計算損失。注意這里默認的損失為平均平方差損失函數。predictions = tf.contrib.layers.fully_connected(output, 1, activation_fn=None)# 只在訓練時計算損失函數和優化步驟。測試時直接返回預測結果。if not is_training:return predictions, None, None# 計算損失函數。loss = tf.losses.mean_squared_error(labels=y, predictions=predictions)# 創建模型優化器并得到優化步驟。train_op = tf.contrib.layers.optimize_loss(loss, tf.train.get_global_step(),optimizer="Adagrad", learning_rate=0.1)return predictions, loss, train_op"""定義測試方法 """ def run_eval(sess, test_X, test_y):# 將測試數據以數據集的方式提供給計算圖。ds = tf.data.Dataset.from_tensor_slices((test_X, test_y))ds = ds.batch(1)X, y = ds.make_one_shot_iterator().get_next()# 調用模型得到計算結果。這里不需要輸入真實的y值。with tf.variable_scope("model", reuse=True):prediction, _, _ = lstm_model(X, [0.0], False)# 將預測結果存入一個數組。predictions = []labels = []for i in range(TESTING_EXAMPLES):p, l = sess.run([prediction, y])predictions.append(p)labels.append(l)# 計算mse作為評價指標。predictions = np.array(predictions).squeeze()labels = np.array(labels).squeeze()rmse = np.sqrt(((predictions - labels) ** 2).mean(axis=0))print("Root Mean Square Error is: %f" % rmse)#對預測的sin函數曲線進行繪圖。plt.figure()plt.plot(predictions, label='predictions')plt.plot(labels, label='real_sin')plt.legend()plt.show()""" 執行訓練和測試 """ # 將訓練數據以數據集的方式提供給計算圖。 print(train_X.shape) print(train_y.shape) ds = tf.data.Dataset.from_tensor_slices((train_X, train_y)) ds = ds.repeat().shuffle(1000).batch(BATCH_SIZE)X, y = ds.make_one_shot_iterator().get_next()# 定義模型,得到預測結果、損失函數,和訓練操作。 with tf.variable_scope("model"):_, loss, train_op = lstm_model(X, y, True)with tf.Session() as sess:sess.run(tf.global_variables_initializer()) # 測試在訓練之前的模型效果。print ("Evaluate model before training.")run_eval(sess, test_X, test_y)# 訓練模型。for i in range(TRAINING_STEPS):_, l = sess.run([train_op, loss])if i % 1000 == 0:print("train step: " + str(i) + ", loss: " + str(l))# 使用訓練好的模型對測試數據進行預測。print ("Evaluate model after training.")run_eval(sess, test_X, test_y)運行結果:
(10000, 1, 10) (10000, 1) Evaluate model before training. Root Mean Square Error is: 0.688176 train step: 0, loss: 0.5273397 train step: 1000, loss: 0.000585775 train step: 2000, loss: 0.0003093369 Evaluate model after training. Root Mean Square Error is: 0.007838
預測曲線基本重合與目標曲線。
3. tf.data.Dataset.from_tensor_slices和repeat()、shuffle()、batch()使用
(1)簡單數組數列使用
import tensorflow as tf import numpy as np ## 數據集對象實例化 dataset = tf.data.Dataset.from_tensor_slices(np.array([1.0, 2.0, 3.0, 4.0, 5.0])) # # 迭代器對象實例化 iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next() with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
1.0 2.0 3.0 4.0 5.0 end!(2)多維數據使用
import tensorflow as tf import numpy as npdataset = tf.data.Dataset.from_tensor_slices(np.random.uniform(size=(5, 2))) print('dataset:',dataset) iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next() with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
dataset: <TensorSliceDataset shapes: (2,), types: tf.float64> [0.1792582 0.9751422] [0.19793807 0.33374795] [0.03978658 0.6808261 ] [0.98788989 0.07403864] [0.32259662 0.50171158] end!傳入的數值是一個矩陣,它的形狀為(5, 2),tf.data.Dataset.from_tensor_slices就會切分它形狀上的第一個維度,最后生成的dataset中一個含有5個元素(但這里的元素個數不知道),每個元素的形狀是(2, ),即每個元素是矩陣的一行。
(3)字典使用
import tensorflow as tf import numpy as np# 數據集對象實例化 dataset = tf.data.Dataset.from_tensor_slices({"a": np.array([1.0, 2.0, 3.0, 4.0, 5.0]), "b": np.random.uniform(size=(5, 2))})# 迭代器對象實例化 iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next()with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
{'a': 1.0, 'b': array([0.04879087, 0.22908515])} {'a': 2.0, 'b': array([0.11519196, 0.78684246])} {'a': 3.0, 'b': array([0.86009348, 0.41073689])} {'a': 4.0, 'b': array([0.80116343, 0.4113549 ])} {'a': 5.0, 'b': array([0.545203 , 0.23978585])} end!對于復雜的情形,比如元素是一個python中的元組或者字典:在圖像識別中一個元素可以是{”image”:image_tensor,”label”:label_tensor}的形式。 如上所示,這時函數會分別切分”label”中的數值以及”fea”中的數值,最后總dataset中的一個元素就是類似于{ “a”:1.0, “b”:[0.9,0.1] }的形式。
(4)復雜的tuple組合數據
import tensorflow as tf import numpy as npdataset = tf.data.Dataset.from_tensor_slices((np.array([1.0, 2.0, 3.0, 4.0, 5.0]), np.random.uniform(size=(5, 2))) )iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next() with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
(1.0, array([0.61708973, 0.73534924])) (2.0, array([0.64866959, 0.04011806])) (3.0, array([0.07455173, 0.02324372])) (4.0, array([0.53580828, 0.19761375])) (5.0, array([0.63886913, 0.56859266])) end!Dataset支持一類特殊的操作:Transformation。一個Dataset通過Transformation變成一個新的Dataset。通常我們可以通過Transformation完成數據變換,打亂,組成batch,生成epoch等一系列操作。
(1)batch的使用
import tensorflow as tf import numpy as np# 數據集對象實例化 dataset = tf.data.Dataset.from_tensor_slices({"a": np.array([1.0, 2.0, 3.0, 4.0, 5.0]), "b": np.random.uniform(size=(5, 2))})dataset = dataset.batch(2) # 迭代器對象實例化 iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next()with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
{'a': array([1., 2.]), 'b': array([[0.34187133, 0.40294537],[0.14411398, 0.06565229]])} {'a': array([3., 4.]), 'b': array([[0.58521367, 0.1550559 ],[0.39541026, 0.87366261]])} {'a': array([5.]), 'b': array([[0.10484032, 0.75835755]])} end!可以看出每兩個數據組成一個batch
(2)shuffle的使用
shuffle的功能為打亂dataset中的元素,它有一個參數buffersize,表示打亂時使用的buffer的大小,建議設置不要太小,一般是1000:
運行結果:
{'a': 3.0, 'b': array([0.60925085, 0.60532416])} {'a': 2.0, 'b': array([0.66688525, 0.29313125])} {'a': 1.0, 'b': array([0.10190033, 0.3020232 ])} {'a': 4.0, 'b': array([0.20525341, 0.50205214])} {'a': 5.0, 'b': array([0.4151064 , 0.00696569])}(3)repeat的使用
repeat的功能就是將整個序列重復多次,主要用來處理機器學習中的epoch,假設原先的數據是一個epoch,使用repeat(2)就可以將之變成2個epoch:
import tensorflow as tf import numpy as npdataset = tf.data.Dataset.from_tensor_slices({"a": np.array([1.0, 2.0, 3.0, 4.0, 5.0]), "b": np.random.uniform(size=(5, 2))})dataset = dataset.repeat(3) iterator = dataset.make_one_shot_iterator() one_element = iterator.get_next() with tf.Session() as sess:try:while True:print(sess.run(one_element))except tf.errors.OutOfRangeError:print("end!")運行結果:
{'a': 1.0, 'b': array([0.14897444, 0.444479 ])} {'a': 2.0, 'b': array([0.10113141, 0.89834262])} {'a': 3.0, 'b': array([0.18748515, 0.95026317])} {'a': 4.0, 'b': array([0.56672754, 0.26056881])} {'a': 5.0, 'b': array([0.5487119 , 0.28498332])} {'a': 1.0, 'b': array([0.14897444, 0.444479 ])} {'a': 2.0, 'b': array([0.10113141, 0.89834262])} {'a': 3.0, 'b': array([0.18748515, 0.95026317])} {'a': 4.0, 'b': array([0.56672754, 0.26056881])} {'a': 5.0, 'b': array([0.5487119 , 0.28498332])} {'a': 1.0, 'b': array([0.14897444, 0.444479 ])} {'a': 2.0, 'b': array([0.10113141, 0.89834262])} {'a': 3.0, 'b': array([0.18748515, 0.95026317])} {'a': 4.0, 'b': array([0.56672754, 0.26056881])} {'a': 5.0, 'b': array([0.5487119 , 0.28498332])} end!參考:
https://zhuanlan.zhihu.com/p/27238630
https://www.cnblogs.com/hellcat/p/8569651.html
總結
以上是生活随笔為你收集整理的循环神经网络应用案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 循环神经网络基础介绍
- 下一篇: CRF++使用简介(windows下非接