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