參考來(lái)源:博客鏈接
使用線性模型來(lái)對(duì)數(shù)據(jù)點(diǎn)進(jìn)行建模。線性模型的數(shù)學(xué)表示是:
y = W.x + b
Where:
x: house size, in sqm
y: predicted house price, in $
(1) Tensors
TensorFlow中使用tensor數(shù)據(jù)結(jié)構(gòu)(實(shí)際上就是一個(gè)多維數(shù)據(jù))表示所有的數(shù)據(jù),并在圖計(jì)算中的節(jié)點(diǎn)之間傳遞數(shù)據(jù)一個(gè)tensor具有固定的類型、級(jí)別和大小,更加深入理解這些概念可參考Rank, Shape, and Type
(2) 在線性模型中,tensorflow 的基本組件是:
-
占位符(Placeholder)- 表示執(zhí)行梯度下降時(shí)將實(shí)際數(shù)據(jù)值輸入到模型中的一個(gè)入口點(diǎn)。例如房子面積 (x) 和房?jī)r(jià) (y_),
x=tf.placeholder(tf.float32,[None,1]) y_=tf.placeholder(tf.float32,[None,1]) -
變量:表示我們?cè)噲D尋找的能夠使成本函數(shù)降到最小的 「good」值的變量,例如 W 和 b,
W=tf.Variable(tf.zeros([1,1])) b=tf.Variable(tf.zeros[1])) y=tf.matmul(x,W)+b -
成本函數(shù):
cost=tf.reduce_sum(tf.pow((y_ - y),2)) -
梯度下降:有了線性模型、成本函數(shù)和數(shù)據(jù),我們就可以開(kāi)始執(zhí)行梯度下降從而最小化代價(jià)函數(shù),以獲得 W、b 的「good」值。
train_step = tf.train.GradientDescentOptimizer(0.00001).minimize(cost)
0.00001 是我們每次進(jìn)行訓(xùn)練時(shí)在最陡的梯度方向上所采取的「步」長(zhǎng);它也被稱作學(xué)習(xí)率(learning rate).
(3)訓(xùn)練模型
訓(xùn)練包含以預(yù)先確定好的次數(shù)執(zhí)行梯度下降,或者是直到成本函數(shù)低于某個(gè)預(yù)先確定的臨界值為止。TensorFlow的使用,所有變量都需要在訓(xùn)練開(kāi)始時(shí)進(jìn)行初始化,否則它們可能會(huì)帶有之前執(zhí)行過(guò)程中的殘余值。
init = tf.initialize_all_variables()
雖然 TensorFlow 是一個(gè) Python 庫(kù),Python 是一種解釋性的語(yǔ)言,但是默認(rèn)情況下不把 TensorFlow 運(yùn)算用作解釋性能的原因,因此不執(zhí)行上面的 init 。相反 TensorFlow 是在一個(gè)會(huì)話中進(jìn)行;創(chuàng)建一個(gè)會(huì)話 (sess) 然后使用 sess.run() 去執(zhí)行.
sess = tf.Session()
sess.run(init)
完整代碼
import numpy as np
import tensorflow as tf
# Model linear regression y = Wx + b
x = tf.placeholder(tf.float32, [None, 1])
W = tf.Variable(tf.zeros([1,1]))
b = tf.Variable(tf.zeros([1]))
product = tf.matmul(x,W)
y = product + b
y_ = tf.placeholder(tf.float32, [None, 1])
# Cost function sum((y_-y)**2)
cost = tf.reduce_mean(tf.square(y_-y))
# Training using Gradient Descent to minimize cost
train_step = tf.train.GradientDescentOptimizer(0.0000001).minimize(cost)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
steps = 1000
for i in range(steps):
# Create fake data for y = W.x + b where W = 2, b = 0
xs = np.array([[i]])
ys = np.array([[2*i]])
# Train
feed = { x: xs, y_: ys }
sess.run(train_step, feed_dict=feed)
print("After %d iteration:" % i)
print("W: %f" % sess.run(W))
print("b: %f" % sess.run(b))
# Suggested by @jihobak
print("cost: %f" % sess.run(cost, feed_dict=feed))
# NOTE: W should be close to 2, and b should be close to 0
在上面的訓(xùn)練中,我們?cè)诿總€(gè) epoch 送入單個(gè)數(shù)據(jù)點(diǎn),這被稱為隨機(jī)梯度下降(stochastic gradient descent)。我們也可以在每個(gè) epoch 送入一堆數(shù)據(jù)點(diǎn),這被稱為 mini-batch 梯度下降,或者甚至在一個(gè) epoch 一次性送入所有的數(shù)據(jù)點(diǎn),這被稱為 batch 梯度下降。
請(qǐng)看下圖的比較,注意這 3 張圖的 2 處不同:
- 每個(gè) epoch 送入 TensorFlow 圖(TF.Graph)的數(shù)據(jù)點(diǎn)的數(shù)量(圖右上方)
-
梯度下降優(yōu)化在調(diào)整 W 和 b 值時(shí)所考慮的數(shù)據(jù)點(diǎn)的數(shù)量(圖右下方)
隨機(jī)梯度下降
mini-batch 梯度下降
batch梯度下降
要在隨機(jī)/mini-batch/batch 梯度下降之間切換,我們只需要在將數(shù)據(jù)點(diǎn)送入訓(xùn)練步驟[D]之前將這些數(shù)據(jù)點(diǎn)分成不同的 batch 大小,即為 [C] 使用如下的代碼片段:
# * all_xs: 所有的特征值
# * all_ys: 所有的輸出值
# datapoint_size: all_xs/all_ys 中點(diǎn)/項(xiàng)的數(shù)量
# batch_size: 配置如下:
# 1: 隨機(jī)模型
# integer < datapoint_size: mini-batch模式
# datapoint_size: batch模式
# i: 當(dāng)前epoch數(shù)量
if datapoint_size == batch_size:
Batch 模式,所以選擇所有數(shù)據(jù)點(diǎn)從 index 0 開(kāi)始
batch_start_idx = 0
elif datapoint_size < batch_size:
不可能
raise ValueError(“datapoint_size: %d, must be greater than
batch_size: %d” % (datapoint_size, batch_size))
else:
隨機(jī)/mini-batch模式: 從所有可能的數(shù)據(jù)點(diǎn)中分批選擇數(shù)據(jù)點(diǎn)
batch_start_idx = (i * batch_size) % (datapoint_size — batch_size)
batch_end_idx = batch_start_idx + batch_size
batch_xs = all_xs[batch_start_idx:batch_end_idx]
batch_ys = all_ys[batch_start_idx:batch_end_idx]
將分批的數(shù)據(jù)點(diǎn)定義為xs, ys, 它們會(huì)被送入 'train_step'訓(xùn)練步驟
xs = np.array(batch_xs)
ys = np.array(batch_ys)
- 學(xué)習(xí)率變化
學(xué)習(xí)率(learn rate)是指梯度下降調(diào)整 W 和 b 遞增或遞減的速度。學(xué)習(xí)率較小時(shí),處理過(guò)程會(huì)更慢,但肯定能得到更小成本;而當(dāng)學(xué)習(xí)率更大時(shí),我們可以更快地得到最小成本,但有「沖過(guò)頭」的風(fēng)險(xiǎn),導(dǎo)致我們沒(méi)法找到最小成本。為了克服這一問(wèn)題,許多機(jī)器學(xué)習(xí)實(shí)踐者選擇開(kāi)始時(shí)使用較大的學(xué)習(xí)率(假設(shè)開(kāi)始時(shí)的成本離最小成本還很遠(yuǎn)),然后隨每個(gè) epoch 而逐漸降低學(xué)習(xí)率。
TensorFlow 帶有多種支持學(xué)習(xí)率變化的梯度下降優(yōu)化器,例如 tf.train.AdagradientOptimizer 和 tf.train.AdamOptimizer.
使用 tf.placeholder 調(diào)整學(xué)習(xí)率如同前面所看到的,如果我們?cè)谶@個(gè)例子中聲明了 tf.placeholder 來(lái)設(shè)置學(xué)習(xí)率,然后在 tf.train.GradientDescentOptimizer 中使用它,我們可以在每個(gè)訓(xùn)練 epoch 向其送入一個(gè)不同的值,這很像我們給x 和 y_ 送入不同的數(shù)據(jù)點(diǎn),這也是每個(gè) epoch 的 tf.placeholders.


