# 四、TensorFlow 中的經典機器學習
機器學習是計算機科學領域,涉及算法的研究,開發和應用,以使計算機器從數據中學習。計算機學習的模型用于進行預測和預測。機器學習研究人員和工程師通過構建模型然后使用這些模型進行預測來實現這一目標。現在眾所周知,機器學習已成功地應用于各種領域,如自然語言理解,視頻處理,圖像識別,語音和視覺。
我們來談談模型。所有機器學習問題都以一種或另一種形式抽象為以下等式:

這里,`y`是輸出或目標,`x`是輸入或特征。如果`x`是一組特征,我們也將其稱為特征向量,并用`X`表示。當我們說模型時,我們的意思是找到將特征映射到目標的函數`f`。因此,一旦我們找到`f`,我們就可以使用`x`的新值來預測`y`的值。
機器學習的核心是找到可用于從`x`的值預測`y`的函數`f`。正如您可能從高中數學周期回憶的那樣,該線的等式如下:

我們可以重寫前面的簡單等式如下:

這里,`W`稱為權重,`b`稱為偏差。不要擔心現在的權重和偏置,我們稍后會介紹它們。現在,您可以將`W`視為等效于`m`和`b`等效于`c`。因此,現在機器學習問題可以說是從`X`的當前值找到`W`和`b`的問題,這樣該方程可用于預測`y`的值。
回歸分析或回歸建模是指用于估計變量之間關系的方法和技術。輸入到回歸模型的變量稱為獨立變量或預測變量或特征,而回歸模型的輸出變量稱為因變量或目標。回歸模型定義如下:

其中`Y`是目標變量,`X`是特征向量,`β`是參數向量
通常,我們使用一種非常簡單的回歸形式,稱為簡單線性回歸來估計參數 β。
在機器學習問題中,我們必須從給定數據中學習模型參數`β0`和`β1`,以便我們有一個估計模型,從`X`的未來值預測`Y`的值。我們對偏置使用`β1`,對權重項使用`β0`,分別用`w`和`b`代表它們。
因此模型如下:

分類是機器學習中的經典問題之一。正在考慮的數據可以屬于一個或其他類別,例如,如果提供的圖像是數據,則它們可以是貓或狗的圖片。因此,在這種情況下,類別是貓和狗。分類是指識別或識別所考慮的數據或對象的標簽或類別。分類屬于監督機器學習的范疇。在分類問題中,提供具有特征或輸入及其相應輸出或標簽的訓練數據集。使用該訓練數據集,訓練模型;換句話說,計算模型的參數。然后將訓練的模型用于新數據以找到其正確的標簽。
分類問題可以有兩種類型:**兩類**或**多類**。兩類意味著數據被分類為兩個不同且不連續的標簽,例如,患者患有癌癥或患者沒有癌癥,圖像是貓或狗。多類意味著數據將被分類到多個類別中,例如,電子郵件分類問題會將電子郵件分成社交媒體電子郵件,與工作相關的電子郵件,個人電子郵件,與家人相關的電子郵件,垃圾郵件,購物優惠電子郵件等等。 。另一個例子是數字圖片的例子;每張圖片可以標記在 0 到 9 之間,具體取決于圖片所代表的數字。在本章中,我們將看到兩種分類的示例。
在本章中,我們將進一步擴展以下主題:
* 回歸
* 簡單的線性回歸
* 多元回歸
* 正則化回歸
* LASSO 正則化
* 嶺正則化
* ElasticNet 正則化
* 分類
* 使用邏輯回歸的分類
* 二分類
* 多類分類
# 簡單的線性回歸
您可能使用過其他機器學習庫;現在讓我們練習使用 TensorFlow 學習簡單的線性回歸模型。在繼續討論特定于域的示例之前,我們將首先使用生成的數據集解釋這些概念。
我們將使用生成的數據集,以便來自所有不同域的讀者可以學習而不會被示例的特定域的細節所淹沒。
您可以按照 Jupyter 筆記本中的代碼`ch-04a_Regression`。
# 數據準備
要生成數據集,我們使用`sklearn`庫的`datasets`模塊中的`make_regression`函數:
```py
from sklearn import datasets as skds
X, y = skds.make_regression(n_samples=200,
n_features=1,
n_informative=1,
n_targets=1,
noise = 20.0)
```
這將生成一個回歸數據集,其中包含一個特征的 200 個樣本值和每個特征的一個目標,并添加了一些噪聲。因為我們只生成一個目標,所以該函數使用一維 NumPy 數組生成`y`;因此,我們重塑`y`有兩個維度:
```py
if (y.ndim == 1):
y = y.reshape(len(y),1)
```
我們使用以下代碼繪制生成的數據集以查看數據:
```py
import matplotlib.pyplot as plt
plt.figure(figsize=(14,8))
plt.plot(X,y,'b.')
plt.title('Original Dataset')
plt.show()
```
我們得到以下繪圖。由于生成的數據是隨機的,您可能會得到不同的繪圖:

現在讓我們將數據分為訓練集和測試集:
```py
X_train, X_test, y_train, y_test = skms.train_test_split(X, y,
test_size=.4,
random_state=123)
```
# 構建一個簡單的回歸模型
要在 TensorFlow 中構建和訓練回歸模型,通常采取以下步驟:
1. 定義輸入,參數和其他變量。
2. 定義模型。
3. 定義損失函數。
4. 定義優化器函數。
5. 訓練模型進行多次迭代,稱為周期。
# 定義輸入,參數和其他變量
在我們使用 TensorFlow 構建和訓練回歸模型之前,讓我們定義一些重要的變量和操作。我們從`X_train`和`y_train`中找出輸出和輸入變量的數量,然后使用這些數字來定義`x`(`x_tensor`),`y`(`y_tensor`),權重(`w`)和偏置(`b`):
```py
num_outputs = y_train.shape[1]
num_inputs = X_train.shape[1]
x_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_inputs],
name="x")
y_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_outputs],
name="y")
w = tf.Variable(tf.zeros([num_inputs,num_outputs]),
dtype=tf.float32,
name="w")
b = tf.Variable(tf.zeros([num_outputs]),
dtype=tf.float32,
name="b")
```
* `x_tensor`被定義為具有可變行和`num_inputs`列的形狀,并且在我們的示例中列數僅為 1
* `y_tensor`定義為具有可變行和`num_outputs`列的形狀,列數在我們的示例中只有一個
* `w`被定義為維度`num_inputs` x `num_outputs`的變量,在我們的例子中是`1 x 1`
* `b`被定義為維度`num_outputs`的變量,在我們的例子中是一個
# 定義模型
接下來,我們將模型定義為`x_tensor × w + b`:
```py
model = tf.matmul(x_tensor, w) + b
```
# 定義損失函數
接下來,我們使用**均方誤差**(**MSE**)定義損失函數。 MSE 定義如下:
有關 MSE 的更多詳細信息,[請訪問此鏈接](http://www.statisticshowto.com/mean-squared-error/)
`y`的實際值和估計值的差異稱為**殘差**。損失函數計算殘差平方的平均值。我們通過以下方式在 TensorFlow 中定義它:
```py
loss = tf.reduce_mean(tf.square(model - y_tensor))
```
* `model - y_tensor`計算殘差
* `tf.square(model - y_tensor)`計算每個殘差的平方
* `tf.reduce_mean( ... )`最終計算在前一步驟中計算的平方均值
我們還定義**均方誤差**(**MSE**)和 **R 平方**(**RS**)函數來評估訓練模型。我們使用單獨的`mse`函數,因為在接下來的章節中,損失函數將改變但`mse`函數將保持不變。
```py
# mse and R2 functions
mse = tf.reduce_mean(tf.square(model - y_tensor))
y_mean = tf.reduce_mean(y_tensor)
total_error = tf.reduce_sum(tf.square(y_tensor - y_mean))
unexplained_error = tf.reduce_sum(tf.square(y_tensor - model))
rs = 1 - tf.div(unexplained_error, total_error)
```
# 定義優化器函數
接下來,我們實例化學習率為 0.001 的`theGradientDescentOptimizer`函數并將其設置為最小化損失函數:
```py
learning_rate = 0.001
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
```
有關梯度下降的更多詳細信息,請訪問此鏈接:
<https://en.wikipedia.org/wiki/Gradient_descent>
<https://www.analyticsvidhya.com/blog/2017/03/introduction-to-gradient-descent-algorithm-along-its-variants/>
TensorFlow 提供了許多其他優化器函數,如 Adadelta,Adagrad 和 Adam。我們將在以下章節中介紹其中一些內容。
# 訓練模型
現在我們已經定義了模型,損失函數和優化函數,訓練模型來學習參數`w`和`b`。要訓??練模型,請定義以下全局變量:
* `num_epochs`:運行訓練的迭代次數。每次迭代,模型都會學習更好的參數,我們將在后面的圖中看到。
* `w_hat`和`b_hat`:收集估計的`w`和`b`參數。
* `loss_epochs`,`mse_epochs`,`rs_epochs`:收集訓練數據集中的總誤差值,以及每次迭代中測試數據集上模型的 mse 和 R 平方值。
* `mse_score`和`rs_score`:收集最終訓練模型的 mse 和 R 平方值。
```py
num_epochs = 1500
w_hat = 0
b_hat = 0
loss_epochs = np.empty(shape=[num_epochs],dtype=float)
mse_epochs = np.empty(shape=[num_epochs],dtype=float)
rs_epochs = np.empty(shape=[num_epochs],dtype=float)
mse_score = 0
rs_score = 0
```
初始化會話和全局變量后,運行`num_epoch`次的訓練循環:
```py
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(num_epochs):
```
在循環的每次迭代中,在訓練數據上運行優化器:
```py
tfs.run(optimizer, feed_dict={x_tensor: X_train, y_tensor: y_train})
```
使用學習的`w`和`b`值,計算誤差并將其保存在`loss_val`中以便稍后繪制:
```py
loss_val = tfs.run(loss,feed_dict={x_tensor: X_train, y_tensor: y_train})
loss_epochs[epoch] = loss_val
```
計算測試數據預測值的均方誤差和 R 平方值:
```py
mse_score = tfs.run(mse,feed_dict={x_tensor: X_test, y_tensor: y_test})
mse_epochs[epoch] = mse_score
rs_score = tfs.run(rs,feed_dict={x_tensor: X_test, y_tensor: y_test})
rs_epochs[epoch] = rs_score
```
最后,一旦完成循環,保存`w`和`b`的值以便稍后繪制它們:
```py
w_hat,b_hat = tfs.run([w,b])
w_hat = w_hat.reshape(1)
```
讓我們在 2,000 次迭代后打印模型和測試數據的最終均方誤差:
```py
print('model : Y = {0:.8f} X + {1:.8f}'.format(w_hat[0],b_hat[0]))
print('For test data : MSE = {0:.8f}, R2 = {1:.8f} '.format(
mse_score,rs_score))
```
This gives us the following output:
```py
model : Y = 20.37448120 X + -2.75295663
For test data : MSE = 297.57995605, R2 = 0.66098368
```
因此,我們訓練的模型不是一個非常好的模型,但我們將在后面的章節中看到如何使用神經網絡來改進它。
本章的目標是介紹如何使用 TensorFlow 構建和訓練回歸模型,而無需使用神經網絡。
讓我們繪制估計模型和原始數據:
```py
plt.figure(figsize=(14,8))
plt.title('Original Data and Trained Model')
x_plot = [np.min(X)-1,np.max(X)+1]
y_plot = w_hat*x_plot+b_hat
plt.axis([x_plot[0],x_plot[1],y_plot[0],y_plot[1]])
plt.plot(X,y,'b.',label='Original Data')
plt.plot(x_plot,y_plot,'r-',label='Trained Model')
plt.legend()
plt.show()
```
我們得到以下原始數據與受訓模型數據的關系圖:

讓我們繪制每次迭代中訓練和測試數據的均方誤差:
```py
plt.figure(figsize=(14,8))
plt.axis([0,num_epochs,0,np.max(loss_epochs)])
plt.plot(loss_epochs, label='Loss on X_train')
plt.title('Loss in Iterations')
plt.xlabel('# Epoch')
plt.ylabel('MSE')
plt.axis([0,num_epochs,0,np.max(mse_epochs)])
plt.plot(mse_epochs, label='MSE on X_test')
plt.xlabel('# Epoch')
plt.ylabel('MSE')
plt.legend()
plt.show()
```
我們得到以下圖,顯示每次迭代時,均方誤差減小,然后保持在 500 附近的相同水平:

讓我們繪制 R 平方的值:
```py
plt.figure(figsize=(14,8))
plt.axis([0,num_epochs,0,np.max(rs_epochs)])
plt.plot(rs_epochs, label='R2 on X_test')
plt.xlabel('# Epoch')
plt.ylabel('R2')
plt.legend()
plt.show()
```
當我們繪制 R 平方超過周期的值時,我們得到以下圖:

這基本上表明該模型以 R 的平均值開始,但隨著模型的訓練并減少誤差,R 平方的值開始變高,最終在某一點變得穩定略高于 0.6。
繪制 MSE 和 R 平方可以讓我們看到我們的模型得到多快的訓練以及它開始變得穩定的地方,以便進一步的訓練在減少誤差方面產生微不足道的好處或幾乎沒有好處。
# 使用訓練的模型進行預測
現在您已經擁有訓練有素的模型,它可用于預測新數據。線性模型的預測是通過理解我們在前一個圖中看到的一些最小均方誤差得出的,因為直線可能不完全適合數據。
為了獲得更好的擬合模型,我們必須使用不同的方法擴展我們的模型,例如添加變量的線性組合。
# 多元回歸
現在您已經學習了如何使用 TensorFlow 創建基本回歸模型,讓我們嘗試在不同域的示例數據集上運行它。我們作為示例數據集生成的數據集是單變量的,即目標僅依賴于一個特征。
實際上,大多數數據集都是多變量的。為了強調一點,目標取決于多個變量或特征,因此回歸模型稱為**多元回歸**或**多維回歸**。
我們首先從最受歡迎的波士頓數據集開始。該數據集包含波士頓 506 所房屋的 13 個屬性,例如每個住所的平均房間數,一氧化氮濃度,到波士頓五個就業中心的加權距離等等。目標是自住房屋的中位數值。讓我們深入探索這個數據集的回歸模型。
從`sklearn`庫加載數據集并查看其描述:
```py
boston=skds.load_boston()
print(boston.DESCR)
X=boston.data.astype(np.float32)
y=boston.target.astype(np.float32)
if (y.ndim == 1):
y = y.reshape(len(y),1)
X = skpp.StandardScaler().fit_transform(X)
```
我們還提取`X`,一個特征矩陣,和`y`,一個前面代碼中的目標向量。我們重塑`y`使其成為二維的,并將`x`中的特征縮放為平均值為零,標準差為 1。現在讓我們使用這個`X`和`y`來訓練回歸模型,就像我們在前面的例子中所做的那樣:
您可能會發現該示例的代碼與上一部分有關簡單回歸的代碼相似; 但是,我們正在使用多種特征來訓練模型,因此將其稱為多元回歸。
```py
X_train, X_test, y_train, y_test = skms.train_test_split(X, y,
test_size=.4, random_state=123)
num_outputs = y_train.shape[1]
num_inputs = X_train.shape[1]
x_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_inputs], name="x")
y_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_outputs], name="y")
w = tf.Variable(tf.zeros([num_inputs,num_outputs]),
dtype=tf.float32, name="w")
b = tf.Variable(tf.zeros([num_outputs]),
dtype=tf.float32, name="b")
model = tf.matmul(x_tensor, w) + b
loss = tf.reduce_mean(tf.square(model - y_tensor))
# mse and R2 functions
mse = tf.reduce_mean(tf.square(model - y_tensor))
y_mean = tf.reduce_mean(y_tensor)
total_error = tf.reduce_sum(tf.square(y_tensor - y_mean))
unexplained_error = tf.reduce_sum(tf.square(y_tensor - model))
rs = 1 - tf.div(unexplained_error, total_error)
learning_rate = 0.001
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
num_epochs = 1500
loss_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
rs_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_score = 0
rs_score = 0
with tf.Session() as tfs:
tfs.run(tf.global_variables_initializer())
for epoch in range(num_epochs):
feed_dict = {x_tensor: X_train, y_tensor: y_train}
loss_val, _ = tfs.run([loss, optimizer], feed_dict)
loss_epochs[epoch] = loss_val
feed_dict = {x_tensor: X_test, y_tensor: y_test}
mse_score, rs_score = tfs.run([mse, rs], feed_dict)
mse_epochs[epoch] = mse_score
rs_epochs[epoch] = rs_score
print('For test data : MSE = {0:.8f}, R2 = {1:.8f} '.format(
mse_score, rs_score))
```
我們從模型中獲得以下輸出:
```py
For test data : MSE = 30.48501778, R2 = 0.64172244
```
讓我們繪制 MSE 和 R 平方值。
下圖顯示了 MSE 的繪圖:

下圖顯示了 R 平方值的繪圖:

正如我們在單變量數據集中看到的那樣,我們看到了 MSE 和 R 平方的類似模式。
# 正則化回歸
在線性回歸中,我們訓練的模型返回訓練數據的最佳擬合參數。但是,在訓練數據上找到最合適的參數可能會導致過擬合。
**過擬合**意味著模型最適合訓練數據,但會給測試數據帶來更大的誤差。因此,我們通常在模型中添加懲罰項以獲得更簡單的模型。
該懲罰項稱為**正則化**項,由此獲得的回歸模型稱為正則化回歸模型。正則化模型有三種主要類型:
* **LASSO 回歸**:在 LASSO 正則化中,也稱為 L1 正則化,正則化項是 LASSO 參數`α`乘以權重`w`絕對值之和。因此,損失函數如下:

* **嶺回歸**:在嶺正則化中,也稱為 L2 正則化,正則化項是嶺參數`α`乘以`i-th`權重`w`的平方和。因此,損失函數如下:

* **ElasticNet 回歸**:當我們添加 LASSO 和嶺正則化項時,得到的正則化稱為 ElasticNet 正則化。因此,損失函數如下:

有關正則化的更多詳細信息,[請參閱互聯網上的這些資源](http://www.statisticshowto.com/regularization/)。
一個簡單的經驗法則是當我們想要刪除某些特征時使用 L1 或 LASSO,從而減少計算時間,但代價是降低了準確率。
現在讓我們看看在 TensorFlow 中實現的這些正則化損失函數。我們將繼續使用前面示例中使用的波士頓數據集。
# LASSO 正則化
我們將 lasso 參數定義為值 0.8:
```py
lasso_param = tf.Variable(0.8, dtype=tf.float32)
lasso_loss = tf.reduce_mean(tf.abs(w)) * lasso_param
```
將 LASSO 參數設置為零意味著沒有正則化,因為該項變為零。正則化項的值越高,懲罰越高。以下是 LASSO 正則化回歸的完整代碼,用于訓練模型以預測波士頓房屋定價:
下面的代碼假定訓練和測試數據集已按照前面的示例進行拆分。
```py
num_outputs = y_train.shape[1]
num_inputs = X_train.shape[1]
x_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_inputs], name='x')
y_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_outputs], name='y')
w = tf.Variable(tf.zeros([num_inputs, num_outputs]),
dtype=tf.float32, name='w')
b = tf.Variable(tf.zeros([num_outputs]),
dtype=tf.float32, name='b')
model = tf.matmul(x_tensor, w) + b
lasso_param = tf.Variable(0.8, dtype=tf.float32)
lasso_loss = tf.reduce_mean(tf.abs(w)) * lasso_param
loss = tf.reduce_mean(tf.square(model - y_tensor)) + lasso_loss
learning_rate = 0.001
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
mse = tf.reduce_mean(tf.square(model - y_tensor))
y_mean = tf.reduce_mean(y_tensor)
total_error = tf.reduce_sum(tf.square(y_tensor - y_mean))
unexplained_error = tf.reduce_sum(tf.square(y_tensor - model))
rs = 1 - tf.div(unexplained_error, total_error)
num_epochs = 1500
loss_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
rs_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_score = 0.0
rs_score = 0.0
num_epochs = 1500
loss_epochs = np.empty(shape=[num_epochs], dtype=np.float32)
mse_epochs = np.empty(shape=[num_epochs], dtype=np.float32)
rs_epochs = np.empty(shape=[num_epochs], dtype=np.float32)
mse_score = 0.0
rs_score = 0.0
with tf.Session() as tfs:
tfs.run(tf.global_variables_initializer())
for epoch in range(num_epochs):
feed_dict = {x_tensor: X_train, y_tensor: y_train}
loss_val,_ = tfs.run([loss,optimizer], feed_dict)
loss_epochs[epoch] = loss_val
feed_dict = {x_tensor: X_test, y_tensor: y_test}
mse_score,rs_score = tfs.run([mse,rs], feed_dict)
mse_epochs[epoch] = mse_score
rs_epochs[epoch] = rs_score
print('For test data : MSE = {0:.8f}, R2 = {1:.8f} '.format(
mse_score, rs_score))
```
我們得到以下輸出:
```py
For test data : MSE = 30.48978233, R2 = 0.64166653
```
讓我們使用以下代碼繪制 MSE 和 R 平方的值:
```py
plt.figure(figsize=(14,8))
plt.axis([0,num_epochs,0,np.max([loss_epochs,mse_epochs])])
plt.plot(loss_epochs, label='Loss on X_train')
plt.plot(mse_epochs, label='MSE on X_test')
plt.title('Loss in Iterations')
plt.xlabel('# Epoch')
plt.ylabel('Loss or MSE')
plt.legend()
plt.show()
plt.figure(figsize=(14,8))
plt.axis([0,num_epochs,np.min(rs_epochs),np.max(rs_epochs)])
plt.title('R-squared in Iterations')
plt.plot(rs_epochs, label='R2 on X_test')
plt.xlabel('# Epoch')
plt.ylabel('R2')
plt.legend()
plt.show()
```
我們得到以下損失繪圖:

迭代中 R 平方的圖如下:

讓我們用嶺回歸重復相同的例子。
# 嶺正則化
以下是嶺正則化回歸的完整代碼,用于訓練模型以預測波士頓房屋定價:
```py
num_outputs = y_train.shape[1]
num_inputs = X_train.shape[1]
x_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_inputs], name='x')
y_tensor = tf.placeholder(dtype=tf.float32,
shape=[None, num_outputs], name='y')
w = tf.Variable(tf.zeros([num_inputs, num_outputs]),
dtype=tf.float32, name='w')
b = tf.Variable(tf.zeros([num_outputs]),
dtype=tf.float32, name='b')
model = tf.matmul(x_tensor, w) + b
ridge_param = tf.Variable(0.8, dtype=tf.float32)
ridge_loss = tf.reduce_mean(tf.square(w)) * ridge_param
loss = tf.reduce_mean(tf.square(model - y_tensor)) + ridge_loss
learning_rate = 0.001
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
mse = tf.reduce_mean(tf.square(model - y_tensor))
y_mean = tf.reduce_mean(y_tensor)
total_error = tf.reduce_sum(tf.square(y_tensor - y_mean))
unexplained_error = tf.reduce_sum(tf.square(y_tensor - model))
rs = 1 - tf.div(unexplained_error, total_error)
num_epochs = 1500
loss_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
rs_epochs = np.empty(shape=[num_epochs],dtype=np.float32)
mse_score = 0.0
rs_score = 0.0
with tf.Session() as tfs:
tfs.run(tf.global_variables_initializer())
for epoch in range(num_epochs):
feed_dict = {x_tensor: X_train, y_tensor: y_train}
loss_val, _ = tfs.run([loss, optimizer], feed_dict=feed_dict)
loss_epochs[epoch] = loss_val
feed_dict = {x_tensor: X_test, y_tensor: y_test}
mse_score, rs_score = tfs.run([mse, rs], feed_dict=feed_dict)
mse_epochs[epoch] = mse_score
rs_epochs[epoch] = rs_score
print('For test data : MSE = {0:.8f}, R2 = {1:.8f} '.format(
mse_score, rs_score))
```
我們得到以下結果:
```py
For test data : MSE = 30.64177132, R2 = 0.63988018
```
繪制損失和 MSE 的值,我們得到以下損失圖:

我們得到以下 R 平方圖:

讓我們來看看 LASSO 和嶺正則化方法的組合。
# ElasticNet 正則化
筆記本`ch-04a_Regression`提供了 ElasticNet 正規回歸的完整代碼,用于訓練模型以預測波士頓房屋定價。在運行模型時,我們得到以下結果:
```py
For test data : MSE = 30.64861488, R2 = 0.63979971
```
繪制損失和 MSE 的值,我們得到以下圖:

我們得到以下 R 平方圖:

# 邏輯回歸和分類
最常用的分類方法是使用邏輯回歸。邏輯回歸是概率和線性分類器。輸入是特征向量,特定類的成員的概率可以正式寫成如下等式:
In the above equation:
* `y`代表輸出,
* `i`代表其中一個類
* `x`代表輸入
* `w`代表權重
* `b`代表偏置
* `z`代表回歸方程`z = w × x + b`
* `φ`代表我們案例中的平滑函數或模型
前面的等式表示當`w`和`b`被給出時`x`屬于`i`類的概率由函數表示`φ((z)`。因此,必須訓練模型以最大化概率值。
# 二分類的邏輯回歸
對于二分類,我們將模型函數`φ(z)`定義為 sigmoid 函數,如下所示:

sigmoid 函數在范圍`[0, 1]`之間產生 y 的值。因此,我們可以使用`y = φ(z)`的值來預測類:如果`y > 0.5`則類別等于 1,否則類別等于 0。
正如我們在本章的前幾節中所見,對于線性回歸,可以通過查找最小化損失函數的參數來訓練模型,并且損失函數可以是平方誤差或均方誤差的總和。對于邏輯回歸,我們希望最大化可能性:`L(w) = P(y|x, w, b)`。
但是,由于更容易使對數似然最大化,因此我們使用對數似然`l(w)`作為成本函數。因此,損失函數(`J(w)`)被寫為`-1(w)`,其可以使用諸如梯度下降的優化算法來最小化。
二元邏輯回歸的損失函數在數學上寫成如下:

其中`φ(z)`是 Sigmoid 函數。
我們將在下一節中實現這個損失函數。
# 多類分類的邏輯回歸
當涉及兩個以上的類時,邏輯回歸是已知的多項邏輯回歸。在多項邏輯回歸中,我們使用 softmax 函數代替 sigmoid,它是最受歡迎的函數之一。 Softmax 可以用數學表示如下:

Softmax 函數產生每個類的概率,概率向量和為 1。在預測時,具有最高 softmax 值的類成為輸出或預測類。正如我們前面討論的那樣,損失函數是負對數似然函數`-l(w)`,它可以被優化器最小化,例如梯度下降。
多項邏輯回歸的損失函數正式寫成如下:

其中`φ(z)`是 softmax 函數。
我們將在本章后面實現這種損失函數。
讓我們在下一節中深入研究一些例子。
您可以按照 Jupyter 筆記本中的代碼`ch-04b_Classification`。
# 二分類
二分類是指僅有兩個不同類的問題。正如我們在上一章中所做的那樣,我們將使用 SciKit Learn 庫中的便捷函數`make_classification()`生成數據集:
```py
X, y = skds.make_classification(n_samples=200,
n_features=2,
n_informative=2,
n_redundant=0,
n_repeated=0,
n_classes=2,
n_clusters_per_class=1)
if (y.ndim == 1):
y = y.reshape(-1,1)
```
`make_classification()`的論據是不言自明的;`n_samples`是要生成的數據點數,`n_features`是要生成的特征數,`n_classes`是類的數量,即 2:
* `n_samples`是要生成的數據點數。我們將其保持在 200 以保持數據集較小。
* `n_features`是要生成的特征數量;我們只使用兩個特征,因此我們可以將它作為一個簡單的問題來理解 TensorFlow 命令。
* `n_classes`是類的數量,它是 2,因為它是二分類問題。
讓我們使用以下代碼繪制數據:
```py
plt.scatter(X[:,0],X[:,1],marker='o',c=y)
plt.show()
```
我們得到以下繪圖;您可能會得到一個不同的圖,因為每次運行數據生成函數時都會隨機生成數據:

然后我們使用 NumPy `eye`函數將`y`轉換為單熱編碼目標:
```py
print(y[0:5])
y=np.eye(num_outputs)[y]
print(y[0:5])
```
單熱編碼目標如下所示:
```py
[1 0 0 1 0]
[[ 0\. 1.]
[ 1\. 0.]
[ 1\. 0.]
[ 0\. 1.]
[ 1\. 0.]]
```
將數據劃分為訓練和測試類別:
```py
X_train, X_test, y_train, y_test = skms.train_test_split(
X, y, test_size=.4, random_state=42)
```
在分類中,我們使用 sigmoid 函數來量化模型的值,使得輸出值位于范圍[0,1]之間。以下等式表示由`φ(z)`表示的 Sigmoid 函數,其中`z`是等式`w × x + b`。損失函數現在變為由`J(θ)`表示的值,其中`θ`表示參數。



我們使用以下代碼實現新模型和損失函數:
```py
num_outputs = y_train.shape[1]
num_inputs = X_train.shape[1]
learning_rate = 0.001
# input images
x = tf.placeholder(dtype=tf.float32, shape=[None, num_inputs], name="x")
# output labels
y = tf.placeholder(dtype=tf.float32, shape=[None, num_outputs], name="y")
# model paramteres
w = tf.Variable(tf.zeros([num_inputs,num_outputs]), name="w")
b = tf.Variable(tf.zeros([num_outputs]), name="b")
model = tf.nn.sigmoid(tf.matmul(x, w) + b)
loss = tf.reduce_mean(-tf.reduce_sum(
(y * tf.log(model)) + ((1 - y) * tf.log(1 - model)), axis=1))
optimizer = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate).minimize(loss)
```
最后,我們運行我們的分類模型:
```py
num_epochs = 1
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(num_epochs):
tfs.run(optimizer, feed_dict={x: X_train, y: y_train})
y_pred = tfs.run(tf.argmax(model, 1), feed_dict={x: X_test})
y_orig = tfs.run(tf.argmax(y, 1), feed_dict={y: y_test})
preds_check = tf.equal(y_pred, y_orig)
accuracy_op = tf.reduce_mean(tf.cast(preds_check, tf.float32))
accuracy_score = tfs.run(accuracy_op)
print("epoch {0:04d} accuracy={1:.8f}".format(
epoch, accuracy_score))
plt.figure(figsize=(14, 4))
plt.subplot(1, 2, 1)
plt.scatter(X_test[:, 0], X_test[:, 1], marker='o', c=y_orig)
plt.title('Original')
plt.subplot(1, 2, 2)
plt.scatter(X_test[:, 0], X_test[:, 1], marker='o', c=y_pred)
plt.title('Predicted')
plt.show()
```
我們獲得了大約 96% 的相當好的準確率,原始和預測的數據圖如下所示:

很簡約!!現在讓我們讓我們的問題變得復雜,并嘗試預測兩個以上的類。
# 多類分類
多類分類的一個流行示例是標記手寫數字的圖像。此示例中的類或標簽為{0,1,2,3,4,5,6,7,8,9}。在以下示例中,我們將使用 MNIST。讓我們像前面章節中所做的那樣加載 MNIST 圖像,代碼如下:
```py
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(os.path.join(
datasetslib.datasets_root, 'mnist'), one_hot=True)
```
如果已按照前一章的說明下載了 MNIST 數據集,那么我們將獲得以下輸出:
```py
Extracting /Users/armando/datasets/mnist/train-images-idx3-ubyte.gz
Extracting /Users/armando/datasets/mnist/train-labels-idx1-ubyte.gz
Extracting /Users/armando/datasets/mnist/t10k-images-idx3-ubyte.gz
Extracting /Users/armando/datasets/mnist/t10k-labels-idx1-ubyte.gz
```
現在讓我們設置一些參數,如下面的代碼所示:
```py
num_outputs = 10 # 0-9 digits
num_inputs = 784 # total pixels
learning_rate = 0.001
num_epochs = 1
batch_size = 100
num_batches = int(mnist.train.num_examples/batch_size)
```
上面代碼中的參數如下:
* `num_outputs`:由于我們必須預測圖像代表十位數中的哪一位,因此我們將輸出數設置為 10.數字由打開或設置為 1 的輸出表示。
* `num_inputs`:我們知道我們的輸入數字是`28 x 28`像素,因此每個像素都是模型的輸入。因此,我們總共有 784 個輸入。
* `learning_rate`:此參數表示梯度下降優化器算法的學習率。我們將學習率任意設定為 0.001。
* `num_epochs`:我們將僅針對一次迭代運行我們的第一個示例,因此我們將周期數設置為 1。
* `batch_size`:在現實世界中,我們可能擁有龐大的數據集并加載整個數據集以便訓練模型可能是不可能的。因此,我們將輸入數據分成隨機選擇的批次。我們將`batch_size`設置為 100 個圖像,可以使用 TensorFlow 的內置算法一次選擇。
* `num_batches`:此參數設置應從總數據集中選擇批次的次數;我們將其設置為等于數據集中的項目數除以批量中的項目數。
我們鼓勵您嘗試使用這些參數的不同值。
現在讓我們使用以下代碼定義輸入,輸出,參數,模型和損失函數:
```py
# input images
x = tf.placeholder(dtype=tf.float32, shape=[None, num_inputs], name="x")
# output labels
y = tf.placeholder(dtype=tf.float32, shape=[None, num_outputs], name="y")
# model paramteres
w = tf.Variable(tf.zeros([784, 10]), name="w")
b = tf.Variable(tf.zeros([10]), name="b")
model = tf.nn.softmax(tf.matmul(x, w) + b)
loss = tf.reduce_mean(-tf.reduce_sum(y * tf.log(model), axis=1))
optimizer = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate).minimize(loss)
```
代碼類似于二分類示例,但有一個顯著差異:我們使用`softmax`而不是`sigmoid`函數。 Softmax 用于多類分類,而 sigmoid 用于二元類分類。 Softmax 函數是 sigmoid 函數的推廣,它將任意實數值的 n 維向量 z 轉換為實數值的 n 維向量`σ(z)`,范圍`(0, 1]`和為 1。
現在讓我們運行模型并打印精度:
```py
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(num_epochs):
for batch in range(num_batches):
batch_x, batch_y = mnist.train.next_batch(batch_size)
tfs.run(optimizer, feed_dict={x: batch_x, y: batch_y})
predictions_check = tf.equal(tf.argmax(model, 1), tf.argmax(y, 1))
accuracy_function = tf.reduce_mean(
tf.cast(predictions_check, tf.float32))
feed_dict = {x: mnist.test.images, y: mnist.test.labels}
accuracy_score = tfs.run(accuracy_function, feed_dict)
print("epoch {0:04d} accuracy={1:.8f}".format(
epoch, accuracy_score))
```
我們得到以下準確率:
```py
epoch 0000 accuracy=0.76109999
```
讓我們嘗試在多次迭代中訓練我們的模型,以便在每次迭代中學習不同的批次。我們建立了兩個支持函數來幫助我們:
```py
def mnist_batch_func(batch_size=100):
batch_x, batch_y = mnist.train.next_batch(batch_size)
return [batch_x, batch_y]
```
上述函數將批量中的示例數作為輸入,并使用`mnist.train.next_batch()`函數返回一批特征(`batch_x`)和目標(`batch_y`):
```py
def tensorflow_classification(num_epochs, num_batches, batch_size,
batch_func, optimizer, test_x, test_y):
accuracy_epochs = np.empty(shape=[num_epochs], dtype=np.float32)
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(num_epochs):
for batch in range(num_batches):
batch_x, batch_y = batch_func(batch_size)
feed_dict = {x: batch_x, y: batch_y}
tfs.run(optimizer, feed_dict)
predictions_check = tf.equal(
tf.argmax(model, 1), tf.argmax(y, 1))
accuracy_function = tf.reduce_mean(
tf.cast(predictions_check, tf.float32))
feed_dict = {x: test_x, y: test_y}
accuracy_score = tfs.run(accuracy_function, feed_dict)
accuracy_epochs[epoch] = accuracy_score
print("epoch {0:04d} accuracy={1:.8f}".format(
epoch, accuracy_score))
plt.figure(figsize=(14, 8))
plt.axis([0, num_epochs, np.min(
accuracy_epochs), np.max(accuracy_epochs)])
plt.plot(accuracy_epochs, label='Accuracy Score')
plt.title('Accuracy over Iterations')
plt.xlabel('# Epoch')
plt.ylabel('Accuracy Score')
plt.legend()
plt.show()
```
上述函數獲取參數并執行訓練迭代,打印每次迭代的準確率分數并打印準確率分數。它還可以保存`accuracy_epochs`數組中每個周期的準確率分數。之后,它繪制了每個周期的準確率。讓我們使用我們之前設置的參數運行此函數 30 個周期,使用以下代碼:
```py
num_epochs=30
tensorflow_classification(num_epochs=num_epochs,
num_batches=num_batches,
batch_size=batch_size,
batch_func=mnist_batch_func,
optimizer=optimizer,
test_x=mnist.test.images,test_y=mnist.test.labels)
```
我們得到以下準確率和圖表:
```py
epoch 0000 accuracy=0.76020002
epoch 0001 accuracy=0.79420000
epoch 0002 accuracy=0.81230003
epoch 0003 accuracy=0.82309997
epoch 0004 accuracy=0.83230001
epoch 0005 accuracy=0.83770001
--- epoch 6 to 24 removed for brevity ---
epoch 0025 accuracy=0.87930000
epoch 0026 accuracy=0.87970001
epoch 0027 accuracy=0.88059998
epoch 0028 accuracy=0.88120002
epoch 0029 accuracy=0.88180000
```

從圖中我們可以看出,初始迭代中的準確率會急劇提高,然后準確率的提高速度會降低。稍后,我們將看到如何在 TensorFlow 中使用神經網絡的全部功能,并將此分類精度提高到更大的值。
# 總結
在本章中,我們學習了如何在 TensorFlow 中應用經典機器學習算法,而不使用神經網絡。在本章的第一部分,我們了解了回歸模型。我們解釋了如何訓練具有一個或多個特征的線性回歸模型。我們使用 TensorFlow 編寫線性回歸代碼。我們還討論了正則化基本上是增加一個懲罰項,以便模型在訓練階段學習參數時不會過擬合訓練數據。我們使用 TensorFlow 實現了 Lasso,Ridge 和 ElasticNet 正則化。 TensorFlow 有一些內置的正則化方法,我們將在下一章中學習。
在本章的后續章節中,我們了解了有監督機器學習中的分類問題。我們討論了兩類和多類分類的模型函數,平滑函數和損失函數。我們在本章中使用了邏輯回歸,因為這是實現分類的最簡單方法。對于二分類,我們使用 sigmoid 函數,對于多類分類,我們使用 softmax 函數來平滑線性模型的值,以產生輸出在特定類中的概率。
我們在 TensorFlow 中實現了模型和損失函數的邏輯,并訓練模型進行二分類和多類分類。雖然我們在本章中使用了經典的機器學習方法,并使用 TensorFlow 實現了它們,但是當我們實現神經網絡和深度神經網絡來解決機器學習問題時,TensorFlow 的全部功能得以釋放。我們將在本書的神經網絡相關章節中研究這些高級方法。
建議您閱讀以下書籍以了解有關回歸和分類的更多詳細信息:
Sebastian Raschka,Python 機器學習,第 2 版,Packt Publishing,2017
Trevor Hastie,Robert Tibshirani,Jerome Friedman,統計學習的要素,第二版,施普林格,2013
- TensorFlow 1.x 深度學習秘籍
- 零、前言
- 一、TensorFlow 簡介
- 二、回歸
- 三、神經網絡:感知器
- 四、卷積神經網絡
- 五、高級卷積神經網絡
- 六、循環神經網絡
- 七、無監督學習
- 八、自編碼器
- 九、強化學習
- 十、移動計算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度學習
- 十三、AutoML 和學習如何學習(元學習)
- 十四、TensorFlow 處理單元
- 使用 TensorFlow 構建機器學習項目中文版
- 一、探索和轉換數據
- 二、聚類
- 三、線性回歸
- 四、邏輯回歸
- 五、簡單的前饋神經網絡
- 六、卷積神經網絡
- 七、循環神經網絡和 LSTM
- 八、深度神經網絡
- 九、大規模運行模型 -- GPU 和服務
- 十、庫安裝和其他提示
- TensorFlow 深度學習中文第二版
- 一、人工神經網絡
- 二、TensorFlow v1.6 的新功能是什么?
- 三、實現前饋神經網絡
- 四、CNN 實戰
- 五、使用 TensorFlow 實現自編碼器
- 六、RNN 和梯度消失或爆炸問題
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用協同過濾的電影推薦
- 十、OpenAI Gym
- TensorFlow 深度學習實戰指南中文版
- 一、入門
- 二、深度神經網絡
- 三、卷積神經網絡
- 四、循環神經網絡介紹
- 五、總結
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高級庫
- 三、Keras 101
- 四、TensorFlow 中的經典機器學習
- 五、TensorFlow 和 Keras 中的神經網絡和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于時間序列數據的 RNN
- 八、TensorFlow 和 Keras 中的用于文本數據的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自編碼器
- 十一、TF 服務:生產中的 TensorFlow 模型
- 十二、遷移學習和預訓練模型
- 十三、深度強化學習
- 十四、生成對抗網絡
- 十五、TensorFlow 集群的分布式模型
- 十六、移動和嵌入式平臺上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、調試 TensorFlow 模型
- 十九、張量處理單元
- TensorFlow 機器學習秘籍中文第二版
- 一、TensorFlow 入門
- 二、TensorFlow 的方式
- 三、線性回歸
- 四、支持向量機
- 五、最近鄰方法
- 六、神經網絡
- 七、自然語言處理
- 八、卷積神經網絡
- 九、循環神經網絡
- 十、將 TensorFlow 投入生產
- 十一、更多 TensorFlow
- 與 TensorFlow 的初次接觸
- 前言
- 1.?TensorFlow 基礎知識
- 2. TensorFlow 中的線性回歸
- 3. TensorFlow 中的聚類
- 4. TensorFlow 中的單層神經網絡
- 5. TensorFlow 中的多層神經網絡
- 6. 并行
- 后記
- TensorFlow 學習指南
- 一、基礎
- 二、線性模型
- 三、學習
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 構建簡單的神經網絡
- 二、在 Eager 模式中使用指標
- 三、如何保存和恢復訓練模型
- 四、文本序列到 TFRecords
- 五、如何將原始圖片數據轉換為 TFRecords
- 六、如何使用 TensorFlow Eager 從 TFRecords 批量讀取數據
- 七、使用 TensorFlow Eager 構建用于情感識別的卷積神經網絡(CNN)
- 八、用于 TensorFlow Eager 序列分類的動態循壞神經網絡
- 九、用于 TensorFlow Eager 時間序列回歸的遞歸神經網絡
- TensorFlow 高效編程
- 圖嵌入綜述:問題,技術與應用
- 一、引言
- 三、圖嵌入的問題設定
- 四、圖嵌入技術
- 基于邊重構的優化問題
- 應用
- 基于深度學習的推薦系統:綜述和新視角
- 引言
- 基于深度學習的推薦:最先進的技術
- 基于卷積神經網絡的推薦
- 關于卷積神經網絡我們理解了什么
- 第1章概論
- 第2章多層網絡
- 2.1.4生成對抗網絡
- 2.2.1最近ConvNets演變中的關鍵架構
- 2.2.2走向ConvNet不變性
- 2.3時空卷積網絡
- 第3章了解ConvNets構建塊
- 3.2整改
- 3.3規范化
- 3.4匯集
- 第四章現狀
- 4.2打開問題
- 參考
- 機器學習超級復習筆記
- Python 遷移學習實用指南
- 零、前言
- 一、機器學習基礎
- 二、深度學習基礎
- 三、了解深度學習架構
- 四、遷移學習基礎
- 五、釋放遷移學習的力量
- 六、圖像識別與分類
- 七、文本文件分類
- 八、音頻事件識別與分類
- 九、DeepDream
- 十、自動圖像字幕生成器
- 十一、圖像著色
- 面向計算機視覺的深度學習
- 零、前言
- 一、入門
- 二、圖像分類
- 三、圖像檢索
- 四、對象檢測
- 五、語義分割
- 六、相似性學習
- 七、圖像字幕
- 八、生成模型
- 九、視頻分類
- 十、部署
- 深度學習快速參考
- 零、前言
- 一、深度學習的基礎
- 二、使用深度學習解決回歸問題
- 三、使用 TensorBoard 監控網絡訓練
- 四、使用深度學習解決二分類問題
- 五、使用 Keras 解決多分類問題
- 六、超參數優化
- 七、從頭開始訓練 CNN
- 八、將預訓練的 CNN 用于遷移學習
- 九、從頭開始訓練 RNN
- 十、使用詞嵌入從頭開始訓練 LSTM
- 十一、訓練 Seq2Seq 模型
- 十二、深度強化學習
- 十三、生成對抗網絡
- TensorFlow 2.0 快速入門指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 簡介
- 一、TensorFlow 2 簡介
- 二、Keras:TensorFlow 2 的高級 API
- 三、TensorFlow 2 和 ANN 技術
- 第 2 部分:TensorFlow 2.00 Alpha 中的監督和無監督學習
- 四、TensorFlow 2 和監督機器學習
- 五、TensorFlow 2 和無監督學習
- 第 3 部分:TensorFlow 2.00 Alpha 的神經網絡應用
- 六、使用 TensorFlow 2 識別圖像
- 七、TensorFlow 2 和神經風格遷移
- 八、TensorFlow 2 和循環神經網絡
- 九、TensorFlow 估計器和 TensorFlow HUB
- 十、從 tf1.12 轉換為 tf2
- TensorFlow 入門
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 數學運算
- 三、機器學習入門
- 四、神經網絡簡介
- 五、深度學習
- 六、TensorFlow GPU 編程和服務
- TensorFlow 卷積神經網絡實用指南
- 零、前言
- 一、TensorFlow 的設置和介紹
- 二、深度學習和卷積神經網絡
- 三、TensorFlow 中的圖像分類
- 四、目標檢測與分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻