使用IRIS資料集訓練第一個深度神經網路
本文主要以Iris資料集為例子講解如何訓練一個簡單的Deep Neural Network。
環境配置
python 3.5.4
TensorFlow 1.4
完整原始碼
import os import urllib import numpy as np import tensorflow as tf # Data sets IRIS_TRAINING = "iris_training.csv" IRIS_TRAINING_URL = "http://download.tensorflow.org/data/iris_training.csv" IRIS_TEST = "iris_test.csv" IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv" def main(): # If the training and test sets aren't stored locally, download them. if not os.path.exists(IRIS_TRAINING): raw = urllib.request.urlopen(IRIS_TRAINING_URL).read().decode() with open(IRIS_TRAINING, "w") as f: f.write(raw) if not os.path.exists(IRIS_TEST): raw = urllib.request.urlopen(IRIS_TEST_URL).read().decode() with open(IRIS_TEST, "w") as f: f.write(raw) # Load datasets. training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float32) # Specify that all features have real-value data feature_columns = [tf.contrib.layers.real_valued_column("", dimension=4)] # Build 3 layer DNN with 10, 20, 10 units respectively. classifier = tf.contrib.learn.DNNClassifier(feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=3, model_dir="/tmp/iris_model") # Define the training inputs def get_train_inputs(): x = tf.constant(training_set.data) y = tf.constant(training_set.target) return x, y # Fit model. classifier.fit(input_fn=get_train_inputs, steps=2000) # Define the test inputs def get_test_inputs(): x = tf.constant(test_set.data) y = tf.constant(test_set.target) return x, y # Evaluate accuracy. accuracy_score = classifier.evaluate(input_fn=get_test_inputs, steps=1)["accuracy"] print("\nTest Accuracy: {0:f}\n".format(accuracy_score)) # Classify two new flower samples. def new_samples(): return np.array( [[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=np.float32) predictions = list(classifier.predict(input_fn=new_samples)) print( "New Samples, Class Predictions: {}\n" .format(predictions)) if __name__ == "__main__": main()
分步講解
下載並載入資料集
Iris資料集是一個包含150個樣本的資料集,主要是用於區分花的種類,其結構如下所示:
如圖所示,花的種類有三種,用0,1,2表示,對應的特徵有4個。在本例中,將150個樣本劃分為訓練集(120個樣本)和測試集(30個樣本)。
首先第一次使用的時候,需要先從tensorflow上下載對應的訓練集資料和測試集資料。
import os import urllib import numpy as np import tensorflow as tf # Data sets IRIS_TRAINING = "iris_training.csv" IRIS_TRAINING_URL = "http://download.tensorflow.org/data/iris_training.csv" IRIS_TEST = "iris_test.csv" IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv" #如果本地沒有該資料集則從線上下載下來 if not os.path.exists(IRIS_TRAINING): raw = urllib.request.urlopen(IRIS_TRAINING_URL).read().decode() with open(IRIS_TRAINING, "w") as f: f.write(raw) if not os.path.exists(IRIS_TEST): raw = urllib.request.urlopen(IRIS_TEST_URL).read().decode() with open(IRIS_TEST, "w") as f: f.write(raw)
接下來,使用learn.datasets.base中的load_csv_with_header()方法將訓練和測試集裝入資料集。load_csv_with_header()方法需要三個必需的引數:
1.filename,CSV檔案的路徑
2.target_dtype,接受資料集的目標值的numpy資料型別。
3.features_dtype,接受資料集的特徵值的numpy資料型別。
在這裡,target(你訓練模型預測的值)是花種,它是一個從0-2的整數,所以對應的適當的numpy資料型別是np.int:
training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float32)
tf.contrib.learn中的Dataset是命名元組;您可以通過data和target欄位訪問特徵資料和目標值。這裡training_set.data和training_set.target分別包含訓練集的特徵資料和目標值;test_set.data和test_set.target分別包含測試集的特徵資料和目標值。
構建一個DNN分類器
tf.contrib.learn提供了一系列預定義的模型,叫做Estimators。通過Estimator,可以幫助我們很方便地對資料進行訓練和評估,在這裡,我們配置一個深層神經網路分類器模型來適配IRIS資料,通過使用tf.contrib.learn,可以使用一行程式碼就幫助我們例項化一個tf.contrib.learn.DNNClassifier.
首先我們要定義模型的特徵列,如下程式碼所示:
feature_columns = [tf.contrib.layers.real_valued_column("", dimension=4)]
它制定了資料集中特徵的資料型別,所有的特徵資料都是連續的,因此tf.contrib.layers.real_valued_column適用於構造特徵列的適當函式。資料集中有四個特徵(萼片寬度,萼片高度,花瓣寬度和花瓣高度),因此相應的尺寸必須設定為4以儲存所有資料。
然後,程式碼使用以下引數建立DNNClassifier模型:
feature_columns=feature_columns。上面定義的一組特徵
hidden_units=[10, 20, 10]。三個隱藏層分別包含10,20,10個神經元。
n_classes=3。三個目標類,代表三個鳶尾物種。
model_dir=/tmp/iris_model。TensorFlow在模型訓練期間將儲存檢查點資料的目錄。有關使用TensorFlow進行日誌記錄和監視的更多資訊,請見使用tf.contrib.learn記錄和監視的基本知識。
使用定義好的分類器用於IRIS訓練集訓練
現在,你已經配置好了你的DNNclassifier模型,你可以使用fit方法來將Iris訓練資料應用到分類器上。將特徵資料(training_set.data),目標值(training_set.target)和要訓練的步數(這裡是2000)作為引數傳遞:
classifier.fit(x=training_set.data, y=training_set.target, steps=2000)
模型的狀態儲存在classifier(分類器)中,這意味著如果你喜歡,你可以迭代地訓練。
執行結果如下圖:
可以看到,最後一輪迭代得到的loss為0.0252。這時候其實已經得到一個較好的訓練模型了。
評估訓練效果
現在已經將Iris的訓練資料適配到了DNNClassifier模型上;現在,可以使用evaluate方法在Iris測試資料上檢查其準確性。像fit(擬合)一樣,evaluate(評估操作)將特徵資料和目標值作為引數,並返回帶有評估結果的dict(字典)。以下程式碼通過了Iris測試資料-test_set.data和test_set.target來評估和列印結果的準確性:
accuracy_score = classifier.evaluate(x=test_set.data, y=test_set.target)["accuracy"]
print('Accuracy: {0:f}'.format(accuracy_score))
可以得到結果的準確度大概在97%左右,當然這個結果可能在不同機器上有差異。
分類新樣本
當我們有一個新的樣本的時候,我們可以使用predict()方法來分類一個新的樣本。
可以使用如下程式碼對他們的物種進行預測:
new_samples = np.array(
[[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=float)
prediction= list(classifier.predict(new_samples, as_iterable=True))
print('Predictions: {}'.format(str(prediction)))
predict()方法返回了一個預測陣列,每個樣本對應其中的一個結果:
Conclusion
這樣,利用IRIS資料我們完整的執行了一次深度神經網路的構建和訓練,可以看到,使用Tensorflow可以高效的完成這一工作,TF大法好。