TensorFlow框架(5)之機器學習實踐


1. Iris data set

  Iris數據集是常用的分類實驗數據集,由Fisher, 1936收集整理。Iris也稱鳶尾花卉數據集,是一類多重變量分析的數據集。數據集包含150個數據集,分為3類,每類50個數據,每個數據包含4個屬性。可通過花萼長度,花萼寬度,花瓣長度,花瓣寬度4個屬性預測鳶尾花卉屬於(Setosa,Versicolour,Virginica)三個種類中的哪一類。

該數據集包含了5個屬性:

  • Sepal.Length(花萼長度),單位是cm;
  • Sepal.Width(花萼寬度),單位是cm;
  • Petal.Length(花瓣長度),單位是cm;
  • Petal.Width(花瓣寬度),單位是cm;
  • species (種類)Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),以及Iris Virginica(維吉尼亞鳶尾)。

 

如表 11所示的iris部分數據集。

表 11

6.4

2.8

5.6

2.2

2

5

2.3

3.3

1

1

4.9

2.5

4.5

1.7

2

4.9

3.1

1.5

0.1

0

5.7

3.8

1.7

0.3

0

4.4

3.2

1.3

0.2

0

5.4

3.4

1.5

0.4

0

6.9

3.1

5.1

2.3

2

6.7

3.1

4.4

1.4

1

5.1

3.7

1.5

0.4

0

5.2

2.7

3.9

1.4

1

6.9

3.1

4.9

1.5

1

5.8

4

1.2

0.2

0

5.4

3.9

1.7

0.4

0

7.7

3.8

6.7

2.2

2

6.3

3.3

4.7

1.6

1

2. Neural Network

2.1 Perform

  TensorFlow提供一個高水平的機器學習 API (tf.contrib.learn),使得容易配置(configure)、訓練(train)和評估(evaluate)各種機器學習模型。tf.contrib.learn庫的使用可以概括為五個步驟,如下所示:

  1) Load CSVs containing Iris training/test data into a TensorFlow Dataset

  2) Construct a neural network classifier

  3) Fit the model using the training data

  4) Evaluate the accuracy of the model

  5)Classify new samples

2.2 Code

  本節以對 Iris 數據集進行分類為例進行介紹,如下所示是完整的TensorFlow程序:

from __future__ import absolute_import

from __future__ import division

from __future__ import print_function

 

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.urlopen(IRIS_TRAINING_URL).read()

with open(IRIS_TRAINING, "w") as f:

f.write(raw)

 

if not os.path.exists(IRIS_TEST):

raw = urllib.urlopen(IRIS_TEST_URL).read()

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()

3. Analysis

3.1 Load data

  對於本文的程序,Iris數據集被分為兩部分:

  • 訓練集:有120個樣例,保存在iris_training.csv文件中;
  • 測試集:有30個樣例,保存在iris_test.csv文件中。
1) import module

  首先程序引入必要module,然后定義了數據集的本地路徑和網絡路徑;

from __future__ import absolute_import

from __future__ import division

from __future__ import print_function

 

import os

import urllib

 

import tensorflow as tf

import numpy as np

 

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

2) Open File

  若本地路徑上不存在數據集指定的文件,則通過網上下載。

if not os.path.exists(IRIS_TRAINING):

raw = urllib.urlopen(IRIS_TRAINING_URL).read()

with open(IRIS_TRAINING,'w') as f:

f.write(raw)

 

if not os.path.exists(IRIS_TEST):

raw = urllib.urlopen(IRIS_TEST_URL).read()

with open(IRIS_TEST,'w') as f:

f.write(raw)

3) load Dataset

  接着將Iris數據集加載到TensorFlow框架中,使其TensorFlow能夠直接使用。這其中使用了learn.datasets.base模塊的load_csv_with_header()函數。該方法有三個參數:

  • filename:指定了CSV文件的名字;
  • target_dtype:指定了數據集中目標數據類型,其為numpy datatype類型;
  • features_dtype:指定了數據集中特征向量的數據類型,其為numpy datatype類型。

如表 11所示,Iris數據中的目標值為:0~2,所以可以定義為整型數據就可以了,即np.int,如下所示:

# 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)

 

  由於tf.contrib.learn中的數據類型(Datasets)是以元祖類型定義的,所以用戶可以通過data 和 target兩個域屬性訪問特征向量數據和目標數據。即training_set.data 和 training_set.target為訓練數據集中的特征向量和目標數據。

3.2 Construct Estimator

  tf.contrib.learn預定義了許多模型,稱為:Estimators。用戶以黑箱模型使用Estimator來訓練和評估數據。本節使用tf.contrib.learn.DNNClassifier來訓練數據,如下所示:

# 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")

  首先程序定義了模型的feature columns,其指定了數據集中特征向量的數據類型。每種類型都有一個名字,由於本節的數據是實數型,所以這里使用.real_valued_column類型。該類型第一個參數指定了列名字,第二個參數指定了列的數量。其中所有的特征類型都定義在:tensorflow/contrib/layers/python/layers/feature_column.py.

    然后程序創建了DNNClassifier模型,

  • feature_columns=feature_columns:指定所創建的特征向量類型;
  • hidden_units=[10, 20, 10]:設置隱藏層的層數,並指定每層神經元的數據量;
  • n_classes=3:指定目標類型的數量,Iris數據有三類,所以這里為3
  • model_dir=/tmp/iris_model:指定模型在訓練期間保存的路徑。

3.3 Describe pipeline

  TensorFlow框架的數據都是以Tensor對象存在,即要么是constant、placeholder或Variable類型。通常訓練數據是以placeholder類型定義,然后用戶訓練時,傳遞所有的數據。本節則將訓練數據存儲在constant類型中。如下所示:

# Define the training inputs

def get_train_inputs():

x = tf.constant(training_set.data)

y = tf.constant(training_set.target)

 

return x, y

 

3.4 Fit DNNClassifier

  創建分類器后,就可以調用神經網絡中DNNClassifier模型的fit()函數來訓練模型了,如下所示:

# Fit model.

classifier.fit(input_fn=get_train_inputs, steps=2000)

通過向fit傳遞get_train_inputs函數返回的訓練數據,並指定訓練的步數為2000步。

3.5 Evaluate Model

  訓練模型后,就可以通過evaluate()函數來評估模型的泛化能力了。與fit函數類似,evaluate函數的輸入數據也需為Tensor類型,所以定義了get_test_inputs()函數來轉換數據。

# 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))

注意:

    由於evaluate函數的返回值是一個Map類型(即dict類型),所以直接根據"accuracy"鍵獲取值:accuracy_score。

3.6 Classify Samples

  在訓練模型后,就可以使用estimator模型的predict()函數來預測樣例。如表 31有所示的兩個樣例,希望預測其為什么類型。

表 31

Sepal Length

Sepal Width

Petal Length

Petal Width

6.4

3.2

4.5

1.5

5.8

3.1

5

1.7

 

如下所示的程序:

# 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))

輸出:

New Samples, Class Predictions: [1 2]

注意:

    由於predict()函數執行的返回結果類型是generator。所以上述程序將其轉換為一個list對象。

4. Logging and Monitoring

  由於TensorFlow的機器學習Estimator是黑箱學習,用戶無法了解模型執行發生了什么,以及模型什么時候收斂。所以tf.contrib.learn提供的一個Monitor API,可以幫助用戶記錄和評估模型。

4.1 Default ValidationMonitor

  默認使用fit()函數訓練Estimator模型時,TensorFlow會產生一些summary數據到fit()函數指定的路徑中。用戶可以使用Tensorborad來展示更詳細的信息。如圖 1所示,執行上述程序DNNClassifier的fit()和evaluate()函數后,默認在TensorBoard頁面顯示的常量信息。

圖 1

 

4.2 Monitors

  為了讓用戶更直觀地了解模型訓練過程的細節,tf.contrib.learn提供了一些高級Monitors,使得用戶在調用fit()函數時,可以使用Monitors來記錄和跟蹤模型的執行細節。如表 41所示是fitt()函數支持的Monitors類型:

表 41

Monitor

Description

CaptureVariable

每執行n步訓練,就將保存指定的變量值到一個集合(collection)

PrintTensor

每執行n步訓練,記錄指定的Tensor

SummarySaver

每執行n步訓練,使用tf.summary.FileWriter函數保存tf.Summary 緩存

ValidationMonitor

每執行n步訓練,記錄一批評估metrics,同時可設置停止條件

 

如\tensorflow\examples\tutorials\monitors\ iris_monitors.py所示的程序:

from __future__ import absolute_import

from __future__ import division

from __future__ import print_function

 

import os

 

import numpy as np

import tensorflow as tf

 

tf.logging.set_verbosity(tf.logging.INFO)

 

# Data sets

IRIS_TRAINING = os.path.join(os.path.dirname(__file__), "iris_training.csv")

IRIS_TEST = os.path.join(os.path.dirname(__file__), "iris_test.csv")

 

 

def main(unused_argv):

# Load datasets.

training_set = tf.contrib.learn.datasets.base.load_csv_with_header(

filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float)

test_set = tf.contrib.learn.datasets.base.load_csv_with_header(

filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float)

 

validation_metrics = {

"accuracy":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_accuracy,

prediction_key="classes"),

"precision":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_precision,

prediction_key="classes"),

"recall":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_recall,

prediction_key="classes"),

"mean":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_mean,

prediction_key="classes")

}

validation_monitor = tf.contrib.learn.monitors.ValidationMonitor(

test_set.data,

test_set.target,

every_n_steps=50,

metrics=validation_metrics,

early_stopping_metric="loss",

early_stopping_metric_minimize=True,

early_stopping_rounds=200)

 

# 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",

config=tf.contrib.learn.RunConfig(save_checkpoints_secs=1))

 

# Fit model.

classifier.fit(x=training_set.data,

y=training_set.target,

steps=2000,

monitors=[validation_monitor])

 

# Evaluate accuracy.

accuracy_score = classifier.evaluate(

x=test_set.data, y=test_set.target)["accuracy"]

print("Accuracy: {0:f}".format(accuracy_score))

 

# Classify two new flower samples.

new_samples = np.array(

[[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=float)

y = list(classifier.predict(new_samples))

print("Predictions: {}".format(str(y)))

 

 

if __name__ == "__main__":

tf.app.run()

 

4.3 Configuring ValidationMonitor

  如圖 1所示,如果沒有指定任何evaluation metrics,那么ValidationMonitor默認會記錄loss和accuracy信息。但用戶可以通過創建ValidationMonitor對象來自定義metrics信息。

即通過向ValidationMonitor構造函數傳遞一個metrics參數,該參數是一個Map類型(dist),其中的key是希望顯示的名字,value是一個MetricSpec對象。

其中tf.contrib.learn.MetricSpec類的構造函數有如下四個參數:

  1. metric_fn:是一個函數,TensorFlowtf.contrib.metrics模塊中預定義了一些函數,用戶可以直接使用;
  2. prediction_key:如果模型返回一個Tensor或與一個單一的入口,那么這個參數可以被忽略;
  3. label_key:可選
  4. weights_key:可選

 

如下所示創建一個dist類型的對象:

validation_metrics = {

"accuracy":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_accuracy,

prediction_key="classes"),

"precision":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_precision,

prediction_key="classes"),

"recall":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_recall,

prediction_key="classes"),

"mean":

tf.contrib.learn.MetricSpec(

metric_fn=tf.contrib.metrics.streaming_mean,

prediction_key="classes")

}

validation_monitor = tf.contrib.learn.monitors.ValidationMonitor(

test_set.data,

test_set.target,

every_n_steps=50,

metrics=validation_metrics,

early_stopping_metric="loss",

early_stopping_metric_minimize=True,

early_stopping_rounds=200)

注意:Python中的dist可以直接以一對"{}"初始化元素,如上validation_metrics對象創建所示。

5. 參考文獻

  [1].TensorFlowà Develop à Get Started àtf.contrib.learn Quickstart
  [2].TensorFlowà Develop à Get Started à Logging and Monitoring Basics with tf.contrib.learn
 

 


免責聲明!

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



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