1、背景
2018年tensorflow進行了版本升級1.8.0,新版tensorflow對原來版本進行了進一步的封裝,編程方式也與之前的內容有了很多的不同。本文介紹在新版TensorFlow 中解決鳶尾花分類問題。
2、新版tensorflow的基本結構
衆所周知,人工智能的核心組成部分就是模型與數據,新版的tensorflow將這兩個內容進行了更高級別的封裝,如果不是定製化需求的很高的問題,我們都建議使用高級別的api與中級別的api來實現,當然這種封裝都是給予puthon語言的。在本實例中重點介紹下面兩個高級API。
- Estimator:代表一個完整的模型。Estimator API 提供一些方法來訓練模型、判斷模型的準確率並生成預測。
- 數據集:構建數據輸入管道。Dataset API 提供一些方法來加載和操作數據,並將數據饋送到您的模型中。Dataset API 與 Estimator API 合作無間。衆所周知,人工智能的核心組成部分就是模型與數據,新版的tensorflow將這兩個內容進行了更高級別的封裝,如果不是定製化需求的很高的問題,我們都建議使用高級別的api與中級別的api來實現,當然這種封裝都是給予puthon語言的。在本實例中重點介紹下面兩個高級API。
3、鳶尾花進行分類問題描述
下面大部分資料來源於tensorflow的官方文檔
本文檔中的示例程序構建並測試了一個模型,此模型根據鳶尾花的花萼和花瓣大小將其分爲三種不同的品種。
數據集
鳶尾花數據集包含四個特徵和一個標籤。這四個特徵確定了單株鳶尾花的下列植物學特徵:
- 花萼長度
- 花萼寬度
- 花瓣長度
- 花瓣寬度
我們的模型會將這些特徵表示爲 float32
數值數據。
該標籤確定了鳶尾花品種,品種必須是下列任意一種:
- 山鳶尾 (0)
- 變色鳶尾 (1)
- 維吉尼亞鳶尾 (2)
我們的模型會將該標籤表示爲 int32
分類數據。
下表顯示了數據集中的三個樣本:
算法
該程序會訓練一個具有以下拓撲結構的深度神經網絡分類器模型:
- 2 個隱藏層。
- 每個隱藏層包含 10 個節點。
下圖展示了特徵、隱藏層和預測(並未顯示隱藏層中的所有節點):
推理
在無標籤樣本上運行經過訓練的模型會產生三個預測,即相應鳶尾花屬於指定品種的可能性。這些輸出預測的總和是 1.0。例如,對無標籤樣本的預測可能如下所示:
- 0.03(山鳶尾)
- 0.95(變色鳶尾)
- 0.02(維吉尼亞鳶尾)
上面的預測表示指定無標籤樣本是變色鳶尾的概率爲 95%。
4、使用tensorflow實現上述分類功能
- 數據分析
所有功能的出發點都是數據,下面來對數據進行全面的分析。首先,這個數據集是網上公開的一個csv格式的數據集,可以將數據下載,使用pandas對數據進行分析。
http://download.tensorflow.org/data/iris_training.csv
:其中包含訓練集。http://download.tensorflow.org/data/iris_test.csv
:其中包含測試集。
使用wget下載數據,當然也可以使用tensorflow提供的數據下載函數,這裏使用wget直接下載數據。
兩個文件下載方式相同,下載結果如下圖所示:
下面使用pandas對數據進行讀取,並部分展示,由於下載數據自帶格式所以做了一下處理
import pandas as pd
import tensorflow as tf
CSV_COLUMN_NAMES = ['SepalLength','SepalWidth','PetalLength', 'PetalWidth', 'Species']
data_train=pd.read_csv('iris_test.csv',names=CSV_COLUMN_NAMES,header=0)
data_test=pd.read_csv('iris_training.csv',names=CSV_COLUMN_NAMES,header=0)
data_train.head()
執行效果如下圖所示:
- 構建模型
在構建模型結構時暫時不需要數據的輸入,但需要制定有幾個特徵需要輸入,從上面的結構中可以看出。輸入的特徵有四個
- 花萼長度(seqpallength)
- 花萼寬度(sepalwidth)
- 花瓣長度 (petallength)
- 花瓣寬度 (petalwidth)
而最後一個是預測值 species 代表他是哪種鳶尾花
- 山鳶尾 (0)
- 變色鳶尾 (1)
- 維吉尼亞鳶尾 (2)
所以我們先將屬性值與標記值區分開
train_x, train_y = data_train, data_train.pop('Species')
test_x, test_y = data_test, data_test.pop('Species')
train_x.head()
輸出效果如下圖所示,可以從train_x,或者test_x提取特徵值,請參考下面代碼:
my_feature_columns = []
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
print(my_feature_columns)
注意這裏對特徵的描述不是單純的列名那麼簡單:
下面可以開始構建訓練模型
classifier = tf.estimator.DNNClassifier(
# 這個模型接受哪些輸入的特徵
feature_columns=my_feature_columns,
# 包含兩個隱藏層,每個隱藏層包含10個神經元.
hidden_units=[10, 10],
# 最終結果要分成的幾類
n_classes=3)
- 訓練模型
下面就需要爲模型提供數據並進行訓練,由於tensorflow採用 一個批量梯度下降算法更新參數,這裏可以構造一個函數來生成數據,並且可以在這個函數當中對數據進行打亂。
def train_func(train_x,train_y):
dataset=tf.data.Dataset.from_tensor_slices((dict(train_x), train_y))
dataset = dataset.shuffle(1000).repeat().batch(100)
return dataset
下面可以進行模型訓練,進行1000 個回合的訓練,每次100調數據
classifier.train(
input_fn=lambda:train_func(train_x,train_y),
steps=1000)
輸出結果如下圖所示:
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpc0_cffvl/model.ckpt-10
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 11 into /tmp/tmpc0_cffvl/model.ckpt.
INFO:tensorflow:step = 11, loss = 53.429516
INFO:tensorflow:global_step/sec: 647.575
INFO:tensorflow:step = 111, loss = 13.04604 (0.156 sec)
INFO:tensorflow:global_step/sec: 998.922
INFO:tensorflow:step = 211, loss = 7.959083 (0.100 sec)
INFO:tensorflow:global_step/sec: 986.828
INFO:tensorflow:step = 311, loss = 5.6491127 (0.102 sec)
INFO:tensorflow:global_step/sec: 989.708
INFO:tensorflow:step = 411, loss = 5.1326213 (0.101 sec)
INFO:tensorflow:global_step/sec: 986.271
INFO:tensorflow:step = 511, loss = 4.5728106 (0.102 sec)
INFO:tensorflow:global_step/sec: 998.328
INFO:tensorflow:step = 611, loss = 4.9600344 (0.100 sec)
INFO:tensorflow:global_step/sec: 992.068
INFO:tensorflow:step = 711, loss = 4.493 (0.101 sec)
INFO:tensorflow:global_step/sec: 1004.25
INFO:tensorflow:step = 811, loss = 4.1192536 (0.099 sec)
INFO:tensorflow:global_step/sec: 1012.11
INFO:tensorflow:step = 911, loss = 3.456455 (0.099 sec)
INFO:tensorflow:Saving checkpoints for 1010 into /tmp/tmpc0_cffvl/model.ckpt.
INFO:tensorflow:Loss for final step: 4.035604.
- 模型預測
可以使用下面方法對測試集的數據進行預測,並查看效果
def eval_input_fn(features, labels, batch_size):
features=dict(features)
if labels is None:
# No labels, use only features.
inputs = features
else:
inputs = (features, labels)
dataset = tf.data.Dataset.from_tensor_slices(inputs)
assert batch_size is not None, "batch_size must not be None"
dataset = dataset.batch(batch_size)
return dataset
預測模型代碼如下
predict_arr = []
predictions = classifier.predict(
input_fn=lambda:eval_input_fn(test_x,labels=test_y,batch_size=100))
for predict in predictions:
predict_arr.append(predict['probabilities'].argmax())
result = predict_arr == test_y
result1 = [w for w in result if w == True]
print("準確率爲 %s"%str((len(result1)/len(result))))