Hike News
Hike News

深度學習-tensorflow基礎-實現簡單線性回歸

線性回歸

定義:權重($w$)與特徵的乘積相加之和

  • 一個樣本有多少特徵就有多少權重
  • 線性回歸是許多演算法的基礎
  • 策略:損失函數
    • 預測值與目標值相減平方的和之平均(均方誤差)
  • 優化:梯度下降API
    • 學習率(參數)

流程

  1. 準備數據(含有特徵值目標值)
  2. 建立線性回歸模型
    • 準備相對應特徵個數的權重變量(w)
    • 建立一個偏置項(bias)變量
    • 注意:權重(w)與偏置是在訓練過程中不斷改變的因此需用tf.Variable()來初始化並儲存
  3. 隨機初始化權重及偏置項
  4. 求損失值(loss):真實值與預測值之誤差(均方誤差)
  5. 優化損失的過程:梯度下降,指定學習率
  • 模型中的參數(權重、偏置需用 變量(variable) 定義)

矩陣運算API

線性回歸最後的目標值(y_predict)應為

  • 矩陣相乘時必須為二維(請注意寫入代碼時注意維度)

tf.matmul(a, b)

用於矩陣相乘

tf.square(x)

求平方值

tf.reduce_mean(input_tensor)

相加求均值

梯度下降API

使用tf.train.GradientDescentOptimizer(learning_rate)完成梯度下降優化

  • learning_rate:須手動指定一般介於0-1之間
  • 返回一個梯度下降的op(於seesion中運行)

梯度下降op可調用的方法

  • minimize(loss):最小化損失
    • loss參數填入要最小化的損失函數

實現一個線性回歸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import tensorflow as tf

def LinearRegression():
# 自實現的線性回歸預測
# 1. 準備數據 如:[100 sample,1 feature];[100 label]
X = tf.random_normal([100,1],mean=1.75,stddev=0.5, name="x_data")
y_true = tf.matmul(X,[[0.7]]) # 矩陣相乘必須為二維的
y_true += 0.8 # bias(偏置項)

# 2. 建立線性回歸模型 1個特徵,1個權重,1個偏置 y = kx + b
# 隨機初始化 權重 及 偏置項 讓模型去計算損失然後優化
weight = tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0),name="w") #必須用變量定義才能優化(改變)
bias = tf.Variable(0.0,name="bias")


y_predict = tf.matmul(X,weight) + bias

# 3. 建立損失函數(均方誤差)
loss = tf.reduce_mean(tf.square(y_true - y_predict))

# 4. 優化損失函數,使用梯度下降 設置參數learning_rate 0 ~ 1之間
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

# 定義一個初始化變量(Variable)的op
init_var_op = tf.global_variables_initializer()

# 通過會話運行程序
with tf.Session() as sess:
#初始化變量
sess.run(init_var_op)

print("起始初始化權重:%f, 初始化偏置:%f"%(weight.eval(),bias.eval()))

#運行優化(優化不可能一次就完成,迭代的過程需不斷的循環訓練)
for i in range(1000):
sess.run(train_op)
if i%50 == 0:
print("優化%d次後 權重:%f, 優化偏置:%f" % (i,weight.eval(), bias.eval()))

Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
起始初始化權重:1.111157, 初始化偏置:0.000000
優化0次後 權重:1.117272, 優化偏置:0.017270
優化50次後 權重:0.926479, 優化偏置:0.370782
優化100次後 權重:0.821177, 優化偏置:0.566434
優化150次後 權重:0.768934, 優化偏置:0.670404
優化200次後 權重:0.739766, 優化偏置:0.729816
優化250次後 權重:0.720606, 優化偏置:0.761604
優化300次後 權重:0.711568, 優化偏置:0.779086
優化350次後 權重:0.706206, 優化偏置:0.788234
優化400次後 權重:0.703404, 優化偏置:0.793436
優化450次後 權重:0.701960, 優化偏置:0.796371
優化500次後 權重:0.701060, 優化偏置:0.797973
優化550次後 權重:0.700607, 優化偏置:0.798889
優化600次後 權重:0.700331, 優化偏置:0.799383
優化650次後 權重:0.700190, 優化偏置:0.799654
優化700次後 權重:0.700104, 優化偏置:0.799809
優化750次後 權重:0.700059, 優化偏置:0.799892
優化800次後 權重:0.700033, 優化偏置:0.799939
優化850次後 權重:0.700018, 優化偏置:0.799966
優化900次後 權重:0.700010, 優化偏置:0.799981
優化950次後 權重:0.700006, 優化偏置:0.799989

學習率與步數的設置

學習率(learning_rate)

  • 要是設置太大,會造成數值overload,跨過最小的loss值使得權重與偏置變得正負無窮大,稱之為梯度爆炸

    • 在極端情況下,權重的值變得非常大,以至於溢出,導致Nan

      解決梯度爆炸(深度神經網路,如RNN當中更容易出現)

      1. 重新設計網路
      2. 調整學習率
      3. 使用梯度截斷(在訓練過程中檢查和限制梯度的大小)
        • 要是在學習的過程中發現速度過快,去抑制進行變化
      4. 使用激活函數
        • 神經網路常用到
  • 要是設置過小,會造成損失函數很慢才會達到最小,使得學習的步數就必須增加