一、監(jiān)督式機(jī)器學(xué)習(xí)的基本術(shù)語
1. 樣本、特征、標(biāo)簽與模型
標(biāo)簽是我們要預(yù)測的真實(shí)事物:y線性回歸中的y變量
特征是指用于描述數(shù)據(jù)的輸入變量:xi 線性回歸中的{x1,x2,...,xn}變量
樣本是指數(shù)據(jù)的特征實(shí)例:x
- 有標(biāo)簽樣本具有{特征, 標(biāo)簽}:{x, y} 用于訓(xùn)練模型
- 無標(biāo)簽樣本具有{特征, ?}:{x, ?} 用于對新數(shù)據(jù)做出預(yù)測
模型可將樣本映射到預(yù)測標(biāo)簽:y',由模型的內(nèi)部參數(shù)定義,這些內(nèi)部參數(shù)值是通過學(xué)習(xí)得到的。
2. 訓(xùn)練與損失
訓(xùn)練模型表示通過有標(biāo)簽樣本來學(xué)習(xí)(確定)所有權(quán)重和偏差的理想值,在監(jiān)督式學(xué)習(xí)中,機(jī)器學(xué)習(xí)算法通過以下方式構(gòu)建模型:檢查多個樣本并嘗試找出可最大限度減少損失的模型,這一過程稱為經(jīng)驗(yàn)風(fēng)險最小化。
損失是一個數(shù)值,表示對于單個樣本而言模型預(yù)測的準(zhǔn)確程度。訓(xùn)練模型的目標(biāo)是從所有樣本中找到一組平均損失較小的權(quán)重和偏差。
定義損失函數(shù)
- L1損失:基于模型預(yù)測的值與標(biāo)簽的實(shí)際值之差的絕對值
- 平方損失:一種常見的損失函數(shù),又稱為L2損失
均方誤差(MSE)指的是每個樣本的平均平方損失
MSE = \frac{1}{N}\sum_{(x,y)∈D}(y - prediction(x))^2
3. 模型訓(xùn)練與降低損失
模型訓(xùn)練要點(diǎn)
- 對權(quán)重w和偏差b進(jìn)行初始猜測
- 反復(fù)調(diào)整這些猜測
- 直到獲得損失可能最低的權(quán)重和偏差為止
在學(xué)習(xí)優(yōu)化過程中,機(jī)器學(xué)習(xí)系統(tǒng)可以不斷迭代,直到總體損失不再變化或至少變化極其緩慢為止,這時候可以說該模型已收斂。
4. 梯度下降法
梯度:一個向量(矢量),表示某一函數(shù)在該點(diǎn)處的方向導(dǎo)數(shù)沿著該方向取得最大值,即函數(shù)在該點(diǎn)處沿著該方向(此梯度的方向)變化最快,變化率最大。
5. 學(xué)習(xí)率與超參數(shù)
用梯度乘以一個稱為學(xué)習(xí)速率(步長)的標(biāo)量,以確定下一個點(diǎn)的位置
例如:如果梯度大小為2.5,學(xué)習(xí)速率為0.01,則梯度下降法算法會選擇距離前一個點(diǎn)0.025的位置作為下一個點(diǎn)。
超參數(shù)是在開始學(xué)習(xí)過程之前設(shè)置值的參數(shù),如:學(xué)習(xí)率、神經(jīng)網(wǎng)絡(luò)的隱含層數(shù)量等
二、線性回歸問題TensorFlow實(shí)戰(zhàn)
1. 產(chǎn)生人工數(shù)據(jù)集
單變量的線性方程可以表示為:y = w * x + b
本例通過生成人工數(shù)據(jù)集,隨機(jī)生成一個近似采樣隨機(jī)分布,使得 w = 2.0, b = 1, 并加入一個噪聲,噪聲的最大振幅為0.4。
#在Jupyter中,使用matplotlib顯示圖像需要設(shè)為inline模式,否則不會顯示圖像
%matplotlib inline
import matplotlib.pyplot as plt #載入matplotlib
import numpy as np #載入numpy
import tensorflow as tf #載入TensorFlow
#設(shè)置隨機(jī)數(shù)種子
np.random.seed(5)
#直接采用np生成等差數(shù)列的方法,生成100個點(diǎn),每個點(diǎn)的取值在-1~1之間
x_data = np.linspace(-1, 1, 100)
#y = 2x + 1 + 噪聲,其中,噪聲的維度與x_data一致
y_data = 2 * x_data + 1.0 + np.random.randn(*x_data.shape) * 0.4
2. 利用matplotlib畫圖
#畫出隨機(jī)生成數(shù)據(jù)的散點(diǎn)圖
plt.scatter(x_data, y_data)
#畫出我們想要學(xué)習(xí)到的線性函數(shù) y = 2x + 1
plt.plot(x_data, 2 * x_data + 1.0, color = 'red', linewidth = 3)
3. 定義模型
使機(jī)器自動求出最合適的 w 和 b,使得對于生成的100個樣本,總損失最小。
#構(gòu)建模型
#定義訓(xùn)練數(shù)據(jù)的占位符,x是特征值,y是標(biāo)簽值
x = tf.placeholder("float", name = "x")
y = tf.placeholder("float", name = "y")
#定義模型函數(shù)
def model(x, w, b):
return tf.multiply(x, w) + b
#定義模型結(jié)構(gòu)
#構(gòu)建線性函數(shù)的斜率,變量w
w = tf.Variable(1.0, name = "w0")
#構(gòu)建線性函數(shù)的截距,變量b
b = tf.Variable(0.0, name = "b0")
#pred是預(yù)測值,前向計算
pred = model(x, w, b)
4. 模型訓(xùn)練
設(shè)置訓(xùn)練參數(shù)
#迭代次數(shù)(訓(xùn)練輪數(shù))
train_epochs = 10
#學(xué)習(xí)率
learning_rate = 0.05
定義損失函數(shù)
- 損失函數(shù)用于描述預(yù)測值與真實(shí)值間的誤差,從而指導(dǎo)模型收斂方向
- 常見損失函數(shù):均方差和交叉熵
#采用均方差作為損失函數(shù)
loss_function = tf.reduce_mean(tf.square(y - pred)) #標(biāo)簽值和預(yù)測差值平方的均值
定義優(yōu)化器,設(shè)置學(xué)習(xí)率和優(yōu)化目標(biāo):最小化損失
#梯度下降優(yōu)化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
創(chuàng)建會話
#聲明會話
sess = tf.Session()
#初始化所有變量
init = tf.global_variables_initializer()
sess.run(init)
迭代訓(xùn)練:設(shè)置迭代輪次,每次通過將樣本逐個輸入模型,進(jìn)行梯度下降優(yōu)化操作,每輪迭代后,繪制出模型曲線。
#step = 0 #記錄訓(xùn)練步數(shù)
#loss_list = [] #用于保存loss值的列表
#開始訓(xùn)練,輪數(shù)為epoch,采用SGD隨機(jī)梯度下降優(yōu)化方法
for epoch in range(train_epochs):
for xs, ys in zip(x_data, y_data):
_, loss = sess.run([optimizer, loss_function], feed_dict={x: xs, y: ys})
#顯示損失值loss
#display_step:控制報告的粒度
#例如,如果display_step設(shè)為2,則將每訓(xùn)練2個樣本輸出一次損失值
#與超參數(shù)不同,修改display_step不會更改模型所學(xué)習(xí)的規(guī)律
#loss_list.append(loss)
#step = step + 1
#if step % display_step == 0:
# print("Train Epoch:", '%02d' %(epoch+1), "Step: %03d" %(step), "loss=",\
# "{:.9f}".format(loss))
#圖形化顯示損失值:plt.plot(loss_list,'r+')
b0temp = b.eval(session=sess)
w0temp = w.eval(session=sess)
plt.plot(x_data, w0temp * x_data + b0temp) #畫圖
[注]:本案例訓(xùn)練輪數(shù)設(shè)置為10,然而只出現(xiàn)了3根直線(其它覆蓋了),說明訓(xùn)練3次后已接近收斂。
結(jié)果查看和可視化:訓(xùn)練完成后,打印查看參數(shù)(數(shù)據(jù)每次運(yùn)行會有所不同,機(jī)器自動調(diào)整賦值w、b)
#查看結(jié)果:本例是通過逐漸降低損失值來訓(xùn)練參數(shù) w和b 擬合 y = 2x + 1 中的系數(shù) 2 和 1
print("w:", sess.run(w)) #w的值應(yīng)該在2附近
print("b:", sess.run(b)) #b的值應(yīng)該在1附近
#結(jié)果可視化
plt.scatter(x_data, y_data, label = 'Original data') #原始散點(diǎn)圖
plt.plot(x_data, x_data * sess.run(w) + sess.run(b), \
label = 'Fitted line', color = 'r', linewidth = 3)
#優(yōu)化出來的 w、b畫出來的直線(TensorFlow線性擬合)
plt.legend(loc=2) #通過參數(shù)loc指定圖例位置
利用模型進(jìn)行預(yù)測
#利用模型進(jìn)行預(yù)測
x_test = 3.21
predict = sess.run(pred, feed_dict = {x: x_test})
print("預(yù)測值:%f" % predict)
target = 2 * x_test + 1.0
print("目標(biāo)值: %f" % target)
# 預(yù)測值:7.405184
# 目標(biāo)值: 7.420000