TensorFlow 機器學習軟體工具入門教學與範例實作

tf.train API

在建立好模型之後,接著就是要使用既有的資料對模型進行訓練,TensorFlow 所提供的 optimizers 可以對模型的 variable 進行微調,讓 loss function 達到最小,而最簡單的 optimizer 就是 gradient descent,他會依照 loss function 對個變數的 gradient 方向調整變數,TensorFlow 的 tf.gradients 可以幫助我們計算函數的微分,而 optimizers 也會自動幫我們處理這部分的問題。

首先建立一個 gradient descent optimizer,並指定 loss function:

optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

將原本的變數設定為預設的錯誤組合,然後使用使用迴圈訓練模型,找出最佳的變數組合:

sess.run(init) # 將變數重設為錯誤的組合
for i in range(1000):
  sess.run(train, {x:[1,2,3,4], y:[0,-1,-2,-3]})

輸出結果:

print(sess.run([W, b]))
[array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]

完整的線性迴歸模型程式

前面我們完成了一個簡單的線性迴歸模型程式,其完整的程式碼如下:

import tensorflow as tf

# 模型參數
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)

# 輸入與輸出的資料
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)

# loss function
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares

# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

# training data
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]

# 初始化、重設模型參數
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

# 最佳化迴圈
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

# 輸出結果
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x:x_train, y:y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11

整個模型以 TensorBoard 畫出來會像這樣:

TensorFlow 線性迴歸模型

這樣就完成一個基本的機器學習程式了,接下來我們要介紹一些比較高階的 TensorFlow API,使用這些高階 API 可以讓使用者在處理典型的問題上更快速、更簡單。

tf.contrib.learn

tf.contrib.learn 是一個高階的 TensorFlow API,可以處理模型的訓練與評估等各種常用的機器學習工作。

以下是使用 tf.contrib.learn 來實作線性迴歸模型的程式碼:

import tensorflow as tf

# NumPy 時常用於載入與整理資料
import numpy as np

# 宣告特徵(fetures),此例中只有一個實數的特徵
features = [tf.contrib.layers.real_valued_column("x", dimension=1)]

# 定義模型,此例使用線性迴歸模型
estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)

# 定義資料,並指定 batch 與 epochs 的大小
x_train = np.array([1., 2., 3., 4.])
y_train = np.array([0., -1., -2., -3.])
x_eval = np.array([2., 5., 8., 1.])
y_eval = np.array([-1.01, -4.1, -7, 0.])
input_fn = tf.contrib.learn.io.numpy_input_fn({"x":x_train}, y_train,
                                              batch_size = 4,
                                              num_epochs = 1000)
eval_input_fn = tf.contrib.learn.io.numpy_input_fn(
    {"x":x_eval}, y_eval, batch_size = 4, num_epochs = 1000)

# 進行模型的訓練
estimator.fit(input_fn = input_fn, steps = 1000)

# 驗證模型
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("train loss: %r"% train_loss)
print("eval loss: %r"% eval_loss)
train loss: {'loss': 2.0923761e-07, 'global_step': 1000}
eval loss: {'loss': 0.0025518893, 'global_step': 1000}

自訂模型

tf.contrib.learn 也允許使用者自訂模型,以下是自訂模型的範例:

import numpy as np
import tensorflow as tf

# 自訂模型
def model(features, labels, mode):
  # 建立線性迴歸模型
  W = tf.get_variable("W", [1], dtype=tf.float64)
  b = tf.get_variable("b", [1], dtype=tf.float64)
  y = W * features['x'] + b
  # loss function 的 sub-graph
  loss = tf.reduce_sum(tf.square(y - labels))
  # 訓練的 sub-graph
  global_step = tf.train.get_global_step()
  optimizer = tf.train.GradientDescentOptimizer(0.01)
  train = tf.group(optimizer.minimize(loss),
                   tf.assign_add(global_step, 1))
  # 使用 ModelFnOps 將我們建立的 subgraphs 包裝好
  return tf.contrib.learn.ModelFnOps(
      mode=mode, predictions=y,
      loss=loss,
      train_op=train)

# 定義模型
estimator = tf.contrib.learn.Estimator(model_fn=model)

# 定義資料,並指定 batch 與 epochs 的大小
x_train = np.array([1., 2., 3., 4.])
y_train = np.array([0., -1., -2., -3.])
x_eval = np.array([2., 5., 8., 1.])
y_eval = np.array([-1.01, -4.1, -7, 0.])
input_fn = tf.contrib.learn.io.numpy_input_fn({"x": x_train}, y_train, 4, num_epochs=1000)

# 進行模型的訓練
estimator.fit(input_fn=input_fn, steps=1000)

# 驗證模型
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("train loss: %r"% train_loss)
print("eval loss: %r"% eval_loss)
train loss: {'loss': 2.0923761e-07, 'global_step': 1000}
eval loss: {'loss': 0.0025518893, 'global_step': 1000}

參考資料:TensorFlow

程式設計, 統計學
  1. thomas

    解得太讚了,期待之後的教學

  2. Hubert

    讚! 要是能以此水準逐步把課程進階展示下去,絕對是TensorFlow神人#1。

Leave a Reply