摘要: Tensorflow高層API
高層封裝API
有同學問,我們學習Tensorflow就是想學習一套可以用的套,像程式設計一樣呼叫就行了,不想學習機器學習的細節,有沒有這樣的方式?
針對於已經有成熟解決方案的模型,why not呢?
在前面已經快速將CNN, RNN的大致概念和深度學習的簡史走馬觀花過了一遍之後,我們就可以開始嘗試使用高層封裝的API。
模型 – 訓練 – 評估 三條語句搞定
既然高層封裝,我們就採用最簡單的方式:首先是一個模型,然後就開始訓練,最後評估一下效果如何。
我們還是舉祖傳的MNIST的例子。
核心三條語句,一句模型,一句訓練,一句評估:
estimator = tf.estimator.LinearClassifier(feature_columns=[image_column], n_classes=10)
# Train.
estimator.train(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
我們首先知道MNIST是把手寫影像分成十類,那麼就用個線性迴歸分類器,指定分成10類:
estimator = tf.estimator.LinearClassifier(feature_columns=[image_column], n_classes=10)
訓練也是無腦的,指定訓練多少步就是了:
estimator.train(input_fn=train_input_fn, steps=2000)
評估也不需要懂啥,給個測試集就是了:
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
給大家一個完整能執行的例子,主要的工作量都在處理輸入資料上,真正有功能的就是那三條語句:
import numpy as np
import tensorflow as tf
def get_input_fn(dataset_split, batch_size, capacity=10000, min_after_dequeue=3000):
def _input_fn():
images_batch, labels_batch = tf.train.shuffle_batch(
tensors=[dataset_split.images, dataset_split.labels.astype(np.int32)],
batch_size=batch_size,
capacity=capacity,
min_after_dequeue=min_after_dequeue,
enqueue_many=True,
num_threads=4)
features_map = {`images`: images_batch}
return features_map, labels_batch
return _input_fn
data = tf.contrib.learn.datasets.mnist.load_mnist()
train_input_fn = get_input_fn(data.train, batch_size=256)
eval_input_fn = get_input_fn(data.validation, batch_size=5000)
# Specify the feature(s) to be used by the estimator.
image_column = tf.contrib.layers.real_valued_column(`images`, dimension=784)
estimator = tf.estimator.LinearClassifier(feature_columns=[image_column], n_classes=10)
# Train.
estimator.train(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
print(eval_metrics)
三步法進階
現在我們已經學會三步法了。雖然不涉及底層細節,我們還是有很多工具可以做得更好的。
比如我們要自己設計優化方法, 從三條語句變成四條:
optimizer2 = tf.train.FtrlOptimizer(learning_rate=5.0, l2_regularization_strength=1.0)
estimator2 = tf.estimator.LinearClassifier(
feature_columns=[image_column], n_classes=10, optimizer=optimizer2)
# Train.
estimator2.train(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics2 = estimator2.evaluate(input_fn=eval_input_fn, steps=1)
print(eval_metrics2)
這段程式碼不是片斷,拼接到上面的程式碼的後面就可以直接執行。
更進一步:支援向量機
預設的雖然通用,但是效果可能不如更專業的更好。比如我們想用前深度學習時代最強大的工具之一 – 支援向量機來進行MNIST識別。我們還是可以用高層API來實現。將LinearClassifier換成KernelLinearClassifier。
optimizer3 = tf.train.FtrlOptimizer(
learning_rate=50.0, l2_regularization_strength=0.001)
kernel_mapper3 = tf.contrib.kernel_methods.RandomFourierFeatureMapper(
input_dim=784, output_dim=2000, stddev=5.0, name=`rffm`)
kernel_mappers3 = {image_column: [kernel_mapper3]}
estimator3 = tf.contrib.kernel_methods.KernelLinearClassifier(
n_classes=10, optimizer=optimizer3, kernel_mappers=kernel_mappers3)
# Train.
estimator3.fit(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics3 = estimator3.evaluate(input_fn=eval_input_fn, steps=1)
print(eval_metrics3)
我們來比較一下三種方法:
Elapsed time: 80.69186925888062 seconds
{`loss`: 0.26811677, `accuracy`: 0.9228, `global_step`: 2000}
Elapsed time: 80.33205699920654 seconds
{`loss`: 0.26356304, `accuracy`: 0.9276, `global_step`: 2000}
Elapsed time: 98.87778902053833 seconds
{`loss`: 0.10834637, `accuracy`: 0.9668, `global_step`: 2000}
SVM支援向量機力量果然強大,從92%的識別率提升到了96%.
高層深度學習API
準備資料的語句不變,我們再加一種採用深度學習的方式,也是三步:
classifier = tf.estimator.DNNClassifier(
feature_columns=[image_column],
hidden_units=[784, 625],
n_classes=10)
# Train.
classifier.train(
input_fn=train_input_fn,
steps=2000)
eval_result = classifier.evaluate(
input_fn=eval_input_fn, steps=1)
print(eval_result)
列印出來的結果如下:
{`accuracy`: 0.9812, `average_loss`: 0.064692736, `loss`: 323.46368, `global_step`: 2000}
識別率達到98%,比支援向量機還要強一些。
Tensorflow的API結構
Tensorflow API
我們從第一講到第十講學習的都是Mid-Level API。這一講講的是High-Level API。
Tensorflow r1.8 Estimators API的變化
Tensorflow API的變化一向以迅速著稱,相容性也不是很好。
tf.estimator.Estimators的前身是tf.contrib.learn.Estimators。
我們對比一下LinearClassifier在這兩個版本的區別:
新版:
estimator = tf.estimator.LinearClassifier(feature_columns=[image_column],
n_classes=10)
# Train.
estimator.train(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
舊版:
estimator = tf.contrib.learn.LinearClassifier(feature_columns=[image_column], n_classes=10)
# Train.
estimator.fit(input_fn=train_input_fn, steps=2000)
# Evaluate and report metrics.
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
print(eval_metrics)
主要區別為:
- 包名改變了
- 新版的訓練方法是train,而舊版是fit。
- 因為新版本沒有提供支援向量機的分類器,我們用的核函式版本的KernelLinearClassifier還是老的包中的,所以還是用的fit來訓練。
本文作者:lusing
本文為雲棲社群原創內容,未經允許不得轉載。