## 2. TensorFlow 中的線性回歸
在本章中,我將開始使用簡單模型:線性回歸來探索 TensorFlow 編程。基于這個例子,我將介紹一些代碼基礎知識,以及,如何調用學習過程中的各種重要組件,如函數函數或算法梯度下降。
### 變量之間的關系模型
線性回歸是一種用于衡量變量之間關系的統計技術。它的有趣之處在于實現它的算法在概念上不復雜,并且還可以適應各種各樣的情況。由于這些原因,我發現用線性回歸的例子開始深入研究 TensorFlow 很有意思。
請記住,在兩個變量(簡單回歸)和兩個以上變量(多元回歸)的情況下,線性回歸擬合因變量和自變量之間的關系`xi`和隨機項`b`。
在本節中,我將創建一個簡單的示例來解釋 TensorFlow 如何工作,假設我們的數據模型對應簡單的線性回歸`y = W * x + b`。為此,我使用一個簡單的 Python 程序在二維空間中創建數據,然后我會要求 TensorFlow 在這些點上尋找最適合的直線。
首先要做的是導入我們將用于生成點的 NumPy 包。我們創建的代碼如下:
```py
import numpy as np
num_points = 1000
vectors_set = []
for i in xrange(num_points):
x1= np.random.normal(0.0, 0.55)
y1= x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)
vectors_set.append([x1, y1])
x_data = [v[0] for v in vectors_set]
y_data = [v[1] for v in vectors_set]
```
從代碼中可以看出,我們根據關系`y = 0.1 * x + 0.3`生成了點,盡管有一些正態分布的變化,因此這些點并不完全對應一條線,讓我們編寫一個更有趣的例子。
在我們的例子中,所得到的點云是:

讀者可以使用以下代碼查看它們(這里,我們需要導入`matplotlib`包的一些函數,運行`pip install matplotlib` [13]):
```py
import matplotlib.pyplot as plt
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.legend()
plt.show()
```
這些點是我們將考慮的模型的訓練數據集的數據。
### 損失函數和梯度下降算法
下一步是訓練我們的學習算法,以便能夠獲得從輸入數據`x_data`估計的輸出值`y`。在這種情況下,正如我們事先所知,它是線性回歸,我們只能用兩個參數表示我們的模型:`W`和`b`。
目標是生成 TensorFlow 代碼,它能夠找到最佳的參數`W`和`b`,它來自輸入數據`x_data`,將其擬合到輸出數據`y_data`,我們這里它是一條直線,由`y_data = W * x_data + b`定義。讀者知道`W`應接近 0.1 且`b`為 0.3,但 TensorFlow 不知道它,必須自己實現。
解決此類問題的一種標準方法是,遍歷數據集的每個值并修改參數`W`和`b`,以便每次都能獲得更精確的答案。為了確定我們是否在這些迭代中有所改進,我們將定義一個損失函數(也稱為“誤差函數”)來衡量某條線有多“好”(實際上是有多“壞”)。
該函數接收參數`W`和`b`,并根據線與數據的擬合程度返回一個誤差值。在我們的例子中,我們可以使用均方誤差 [14] 作為損失函數。利用均方誤差,我們得到“誤差”的平均值,基于實際值與算法每次迭代估計值之間距離。
稍后,我將詳細介紹損失函數及其替代方法,但對于這個介紹性示例,均方誤差有助于我們一步一步向前推進。
現在是時候用 TensorFlow 編寫我 解釋過的所有內容了。為此,首先我們將使用以下語句創建三個變量:
```py
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
```
現在,我們可以繼續前進,只知道方法`Variable`的調用定義了一個變量,駐留在 TensorFlow 的內部圖數據結構中,我在上面已經說過了。 稍后我們將回到方法參數的更多信息,但是現在我認為最好繼續前進來推進第一種方法。
現在,通過定義這些變量,我們可以基于每個點與函數`y = W * x + b`計算的點之間的距離,來表示我們之前討論的損失函數。之后,我們可以計算其平方和的平均值。 在 TensorFlow 中,此損失函數表示如下:
```py
loss = tf.reduce_mean(tf.square(y - y_data))
```
如我們所見,此表達式計算我們知道的`y_data`點與從輸入`x_data`計算的點`y`之間的平方距離的平均值。
此時,讀者可能已經懷疑最適合我們數據的直線是誤差值較小的直線。 因此,如果我們使誤差函數最小,我們將找到我們數據的最佳模型。
目前沒有太多細節,這就是使函數最小的優化算法,稱為梯度下降 [15]。 理論上,梯度下降是一種算法,它接受由一組參數定義的函數,它以一組初始參數值開始,并迭代地移向一組使函數最小的值。 在函數梯度 [16] 的負方向上移動來實現迭代式最小化。 通常計算距離平方來確保它是正的并且使誤差函數可微分以便計算梯度。
算法從一組參數的初始值開始(在我們的例子中為`W`和`b`),然后算法以某種方式迭代地調整這些變量的值,在過程結束時,變量的值使成本函數最小。
要在 TensorFlow 中使用此算法,我們只需執行以下兩個語句:
```py
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
```
現在,這足以讓 TensorFlow 在其內部數據結構中創建相關數據,并且在這個結構中也實現了一個可以由`train`調用的優化器,它是針對定義的成本函數的梯度下降算法。稍后,我們將討論名為學習率的函數參數(在我們的示例中,值為 0.5)。
### 運行算法
正如我們之前所見,在代碼的這個位置上,特定于 TensorFlow 庫的調用,只向其內部圖添加了信息,而 TensorFlow 的運行時尚未運行任何算法。因此,與前一章的示例一樣,我們必須創建會話,調用`run`方法并傳遞`train`作為參數。另外,因為在代碼中我們已經指定了變量,所以我們必須先使用以下調用對它們進行初始化:
```py
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
```
現在我們可以開始迭代過程,這將允許我們找到`W`和`b`的值,它定義最適合輸入點的模型直線。 訓練過程一直持續到模型在訓練數據上達到所需的準確度。 在我們的特定示例中,如果我們假設只有 8 次迭代就足夠了,代碼可能是:
```py
for step in xrange(8):
sess.run(train)
print step, sess.run(W), sess.run(b)
```
運行此代碼的結果表明,`W`和`b`的值接近我們事先知道的值。 在我的例子中,`print`的結果是:
```py
(array([ 0.09150752], dtype=float32), array([ 0.30007562], dtype=float32))
```
并且,如果我們使用以下代碼以圖形方式顯示結果:
```py
plt.plot(x_data, y_data, 'ro')
plt.plot(x_data, sess.run(W) * x_data + sess.run(b))
plt.legend()
plt.show()
```
我們可以用圖形方式,看到參數`W = 0.0854`和`b = 0.299`定義的直線,只需 8 次迭代:

請注意,我們只執行了八次迭代來簡化說明,但如果我們運行更多,參數值會更接近預期值。 我們可以使用以下語句來打印`W`和`b`的值:
```py
print(step, sess.run(W), sess.run(b))
```
在我們的例子中,`print`輸出是:
```py
(0, array([-0.04841119], dtype=float32), array([ 0.29720169], dtype=float32))
(1, array([-0.00449257], dtype=float32), array([ 0.29804006], dtype=float32))
(2, array([ 0.02618564], dtype=float32), array([ 0.29869056], dtype=float32))
(3, array([ 0.04761609], dtype=float32), array([ 0.29914495], dtype=float32))
(4, array([ 0.06258646], dtype=float32), array([ 0.29946238], dtype=float32))
(5, array([ 0.07304412], dtype=float32), array([ 0.29968411], dtype=float32))
(6, array([ 0.08034936], dtype=float32), array([ 0.29983902], dtype=float32))
(7, array([ 0.08545248], dtype=float32), array([ 0.29994723], dtype=float32))
```
你可以觀察到算法以`W = -0.0484`和`b = 0.2972`(在我們的例子中)的初始值開始,然后算法以一種方式迭代調整變量的值使損失函數最小。
你還可以檢查損失函數是否隨之減少
```py
print(step, sess.run(loss))
```
在這種情況下,`print`輸出是:
```py
(0, 0.015878126)
(1, 0.0079048825)
(2, 0.0041520335)
(3, 0.0023856456)
(4, 0.0015542418)
(5, 0.001162916)
(6, 0.00097872759)
(7, 0.00089203351)
```
我建議讀者在每次迭代時繪圖,讓我們可以直觀地觀察算法如何調整參數值。 在我們的例子中,8 個截圖是:

正如讀者可以看到的,在算法的每次迭代中,直線更適合數據。 梯度下降算法如何更接近最小化損失函數的參數值?
由于我們的誤差函數由兩個參數(`W`和`b`)組成,我們可以將它可視化為二維表面。 該二維空間中的每個點代表一條直線。 每個點的函數高度是該直線的誤差值。 在該表面上,一些直線產生的誤差值小于其他直線。 當 TensorFlow 運行梯度下降搜索時,它將從該表面上的某個位置開始(在我們的示例中,點`W = -0.04841119`和`b = 0.29720169`)并向下移動來查找具有最小誤差的直線。
要在此誤差函數上運行梯度下降,TensorFlow 會計算其梯度。 梯度將像指南針一樣,總是引導我們向下走。 為了計算它,TensorFlow 將對誤差函數微分,在我們的情況下意味著它需要計算`W`和`b`的偏導數,它表明每次迭代中要移動的方向。
之前提到的學習率參數控制每次迭代期間 TensorFlow 的每一步的下降程度。 如果我們引入的參數太大,我們可能會越過最小值。 但是,如果我們讓 TensorFlow 采取較小步驟,則需要多次迭代才能達到最小值。 因此,使用良好的學習率至關重要。 有不同的技術來調整學習率參數的值,但它超出了本入門書的范圍。 確保梯度下降算法正常工作的一種好方法,是確保每次迭代中的誤差減小。
請記住,為了便于讀者測試本章所述的代碼,你可以從本書的 Github [17] 下載`regression.py`。 在這里,你將發現所有東西都在一起以便跟蹤:
```py
import numpy as np
num_points = 1000
vectors_set = []
for i in xrange(num_points):
x1= np.random.normal(0.0, 0.55)
y1= x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)
vectors_set.append([x1, y1])
x_data = [v[0] for v in vectors_set]
y_data = [v[1] for v in vectors_set]
import matplotlib.pyplot as plt
#Graphic display
plt.plot(x_data, y_data, 'ro')
plt.legend()
plt.show()
import tensorflow as tf
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for step in xrange(8):
sess.run(train)
print(step, sess.run(W), sess.run(b))
print(step, sess.run(loss))
#Graphic display
plt.plot(x_data, y_data, 'ro')
plt.plot(x_data, sess.run(W) * x_data + sess.run(b))
plt.xlabel('x')
plt.xlim(-2,2)
plt.ylim(0.1,0.6)
plt.ylabel('y')
plt.legend()
plt.show()
```
在本章中,我們已經開始探索 TensorFlow 軟件包的可能性,首先采用直觀方法處理兩個基本組件:損失函數和梯度下降算法,使用基本線性回歸算法來介紹。 在下一章中,我們將詳細介紹 TensorFlow 包使用的數據結構。
- 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
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻