iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
0
AI & Data

Machine Learning for Dummies系列 第 26

[Day 26] 用 TensorFlow 實作梯度下降

  • 分享至 

  • xImage
  •  

昨天的文章 安裝完 TensorFlow,之後,今天讓我們來看看怎麼用 TenforFlow 來實作梯度下降

起手式:載入套件與資料

# 載入套件
import tensorflow as tf
import numpy as np

# 訓練資料
x_data = np.array([ 9,  4,  7 , 3 , 10  , 7 , 4 ,  3 , 1,  9])
y_data = np.array([  45  , 24 ,  59  , 28  , 91 , 28  ,  42 ,  18 , 14, 82])

這邊跟我們先前的做法是一樣的

定義變數

# 假設模型為 y = a * x + b
# 模型參數
a = tf.Variable([7], dtype=tf.float32)
b = tf.Variable([2], dtype=tf.float32)

# 定義變數
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)

這裡我們假設模型還是 y = a * x + b,先用 tf.Variable 的方法定義了 a 和 b 的初始值,以及用 tf.placeholder 創造出未來存放 x 與 y 值的地方。其中 Variable 和 Placeholder 是兩種 TensorFlow 當中的資料型態。

Variable 顧名思義就就是變數,和我們在一般的程式語言使用的方法一樣,但是在 TensorFlow 有兩個需要注意的地方,第一個是當我們宣告一個變數的時候,除了給定初始值外,也可以定義他的類型,另外,在使用前需要初始化,待會在後面的程式我們將會看到初始化的地方。Variable 的值除了可以是單一的數字之外,也可以是數列或陣列,像是

variable_1 = tf.Variable(17,dtype=tf.float32)
variable_2 = tf.Variable([17,27],dtype=tf.float32)

Placeholder 顧名思義就是一個先佔有空間的東西,這裡可以想像是我們創造了一個佔有一定空間的空白陣列,一樣我們也可以先指定這個 placeholder 裡面的值得資料型態,以及它的 shape。

variable 跟 placeholder 看起來都是可以存放數值的東西,那麼兩者差在哪裡呢?在實作上,通常會把需要被訓練的變數設定為 variable,譬如在我們的案例裡,就是 ab(兩個我們想要透過機器訓練出來的結果),在過程中這裡兩個會不斷的變化;而 placeholder 主要會放置我們提供的訓練資料,像是最一開的 x_data 和 y_data

設定模型與工具

# 定義模型
linear_model = a*x + b

# 損失函數
loss = tf.reduce_sum(tf.square(linear_model - y)) 

# 優化器 optimizer
optimizer = tf.train.GradientDescentOptimizer(0.00001)
train = optimizer.minimize(loss)

這裡我們定義了 model 的樣子,以及損失函數該怎麼計算。接著,就到了 TensorFlow 厲害的地方了,這裡我們可以選擇不同的「優化器 optimizer」來幫助我們訓練機器。在 TenforFlow 當中有很多種優化器,也就是不同的算法,像是

這裡我們選擇了 GradientDescentOptimizer,另外也定義了 learning rate 0.00001,以及訓練的目的:最小化損失函數

執行訓練

# 執行梯度下降
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
for i in range(100000):
  sess.run(train, {x: x_data, y: y_data})

這裡我們先初始化變數,接著用 sess 來執行 初始化 (init) 以及我們剛剛決定好的 訓練方式 (train)。在 TensorFlow 的世界當中,基本上做任何事情都得靠 tf.Session() 來幫忙。

印出結果

把上面提到的程式碼組合起來之後,就可以開始跑訓練囉!完成之後,再用下面的方法把訓練完的結果給印出來(你看這邊連印個變數的值都要用 sess.run() 來看)

print(sess.run(a))
print(sess.run(b))
print(sess.run(loss, {x: x_data, y: y_data}))

結果如下

[7.215693]    #a
[1.9708481]   #b
1879.5819     #loss

回頭看看一樣用 learning rate 為 0.00001、iteration 為 100000 的情況下,用我們自己寫的 Python code 的結果

7.20311491829791     #a
2.061284742936665    #b
1879.599863360517    #loss

會發現兩者之間是有小小的差異的(好吧,我承認不知道這個差異真正是從哪裡來的)

小結

我們用 TensorFlow 實現了梯度下降的方式來訓練機器,看起來的確是比自己寫 Python code 還要來得簡單多了。明天讓我們來繼續探索 TensorFlow 吧!


上一篇
[Day 25] Hello TensorFlow
下一篇
[Day 27] 不同的 Optimizer
系列文
Machine Learning for Dummies30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言