TensorFlow從0到1 - 7 - TensorFlow線性回歸的參數(shù)溢出之坑

TensorFlow從0到1系列回顧

stackoverflow

上一篇 6 解鎖梯度下降算法解釋清楚了學習率(learning rate)。本篇基于對梯度下降算法和學習率的理解,去填下之前在線性回歸中發(fā)現(xiàn)的一個坑。

5 TF輕松搞定線性回歸中提到,只要把TF官方Get Started中線性回歸例子中的訓練數(shù)據(jù)換一下,就會出現(xiàn)越訓練“損失”越大,直到模型參數(shù)都stackoverflow的情況。然而更換訓練數(shù)據(jù)是我們學習代碼的過程中再普通不過的行為,從stackoverflow.com上也能搜到很多人做了類似的嘗試而遇到了這個問題。到底為什么這么經(jīng)不住折騰?馬上攤開看。

更換訓練數(shù)據(jù)如下:

  • 參數(shù)初始值a=-1,b=50;
  • 訓練數(shù)據(jù)x_train = [22, 25];
  • 訓練數(shù)據(jù)y_train = [18, 15]。

先亮個底:給出的訓練數(shù)據(jù)只有兩組但足夠了,兩點成一線,要擬合的直線心算下就能得出是y=-x+40,a是-1,b是40。

運行使用新數(shù)據(jù)的代碼:

import tensorflow as tf

# model parameters
a = tf.Variable([-1.], tf.float32)
b = tf.Variable([50.], tf.float32)

# model input and output
x = tf.placeholder(tf.float32)
linear_model = a * x + b
y = tf.placeholder(tf.float32)

# loss
loss = tf.reduce_sum(tf.square(linear_model - y)) / 4   # sum of the squares

# training data
x_train = [22, 25]
y_train = [18, 15]

# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

# training loop
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
for i in range(10):
    sess.run(train, {x: x_train, y: y_train})
    curr_a, curr_b, curr_loss = sess.run([a, b, loss], {x: x_train, y: y_train})
    print("a: %s b: %s loss: %s" % (curr_a, curr_b, curr_loss))

# evaluate training accuracy
curr_a, curr_b, curr_loss = sess.run([a, b, loss], {x: x_train, y: y_train})
print("a: %s b: %s loss: %s" % (curr_a, curr_b, curr_loss))

為了方便觀察,讓程序訓練了10次,輸出是:

a: [-3.3499999] b: [ 49.90000153] loss: 1033.39
a: [ 7.35424948] b: [ 50.35325241] loss: 21436.4
a: [-41.40307999] b: [ 48.28647232] loss: 444752.0
a: [ 180.68467712] b: [ 57.69832993] loss: 9.22756e+06
a: [-830.91589355] b: [ 14.8254509] loss: 1.9145e+08
a: [ 3776.88330078] b: [ 210.10742188] loss: 3.97214e+09
a: [-17211.45703125] b: [-679.39624023] loss: 8.24126e+10
a: [ 78389.59375] b: [ 3372.25512695] loss: 1.70987e+12
a: [-357069.3125] b: [-15082.85644531] loss: 3.54758e+13
a: [ 1626428.5] b: [ 68979.421875] loss: 7.36039e+14
a: [ 1626428.5] b: [ 68979.421875] loss: 7.36039e+14

參數(shù)越練損失越大的趨勢果然重現(xiàn)了。

現(xiàn)在我們已經(jīng)掌握了梯度下降大法,就來看看每次訓練的結(jié)果到底是怎么產(chǎn)生的。



手工計算了兩次迭代,和程序輸出一致。

圖中顯示,訓練樣本(已紅色標出)的值對梯度值的貢獻很大,而此時沿用之前的學習率η=0.01就顯得不夠小了。訓練樣本既然不可調(diào),那么顯然只能調(diào)小學習率了。隨之而來的副作用就是會導致學習緩慢,所以還得增加訓練的次數(shù)。這就是之前的例子中最終調(diào)整為η=0.0028,epoch=70000的原因了。

如此看來,這的確不是TF的bug。再一次體會:訓練是一門藝術。

上一篇 6 解鎖梯度下降算法
下一篇 8 萬能函數(shù)的形態(tài):人工神經(jīng)網(wǎng)絡


共享協(xié)議:署名-非商業(yè)性使用-禁止演繹(CC BY-NC-ND 3.0 CN)
轉(zhuǎn)載請注明:作者黑猿大叔(簡書)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容