TensorFlow初步(3)
TensorFlow初步(3)
大家好我是zyy,本人是機器學習和深度學習的初學愛好者,想跟大家一起分享我的學習經驗,大家一起交流。我寫的東西不一定全對,但肯定是我一步一步走出來的坑,嚼爛了的經驗,可以供大家直接「吸收」
我的文章主要會涉及各種機器學習和深度學習演算法的推導和輪子的實現,以及一些小的應用demo,偶爾還會有一些論文的演算法實現。
文中出現的所有代碼都可以在我的GitHub上找到。
[GitHub](https://github.com/YuyangZhangFTD/zyy_ML-DL)
線性回歸
今天我們來講最簡單的一個模型,一元線性回歸模型。
我會提供普通python版和TensorFlow版供大家對比學習。
假設我們有數據自變數和自變數,其中,,滿足
,其中
其中和是我們需要估計的參數。
我們定義回歸的誤差為,其中,和是我們對參數的估計值。
有人會問,誤差函數為什麼是這個樣子,後面會解釋。
插一句題外話
在此插一句我理解的機器學習的過程(或者框架?筆者此處詞窮...)。最近在看《understanding machine learning: theory algorithms》,等我看完,會給出一個我理解的機器學習的定義。
個人認為,一個機器學習的過程就是:
- 找出一個對現實現象的抽象模型
- 定義一個可以衡量的誤差函數
- 通過各種方法來找出合理的權重(或者函數或者分布)來最小化這個誤差
求解方法
剛才說了,要通過各種方法來最小化這個誤差,我們可以把誤差函數寫為
那麼最小化這個誤差函數我們,我們有什麼辦法?
- 無約束問題,求導,令偏導為0,然後就可以得極值點
- 用數值方法,如各種梯度下降的方法,不斷逼近極值點
採用第二種方法時,我們就可以揭秘一下這個誤差函數這麼設計的秘密。
首先是誤差,我們一般取絕對值或者平方,這樣來使估計值與真實值儘可能接近。
其次前面的則是為了求梯度求導後計算的方便,該誤差函數的導數為:
(數學不好的同學請把求導做3遍...)
然後用梯度下降法,逐步求解最優的參數估計值。通用框架可以寫作:
其中稱為學習率(learning rate)。
Python普通版
import numpy as npnimport matplotlib.pyplot as pltnimport tensorflow as tfnn# initial datanplt.ion()nn_observations = 100nfig, ax = plt.subplots(1, 1)nxs = np.linspace(-3, 3, n_observations)nw = 5nb = 1nys = w*xs + b + np.random.normal(0, 1, n_observations)nax.scatter(xs, ys)nfig.show()nplt.draw()nplt.waitforbuttonpress()n
先生成一些數據。預設的,然後我們生成我們所用的數據xs和ys。
n_epochs = 1000neta = 0.01nnndef error(y, y_hat):n return 1/2*sum((y-y_hat)**2) / (n_observations - 1)nnndef gradient_w(x, y, y_hat):n return sum((y-y_hat) * (-x)) / (n_observations - 1)nnndef gradient_b(x, y, y_hat):n return sum((y-y_hat) * (-1)) / (n_observations - 1)nnw_hat1 = np.random.uniform(0, 10, 1)nb_hat1 = np.random.uniform(0, 10, 1)nnfor i_epoch in range(n_epochs):n y_hat1 = w_hat1 * xs + b_hat1n w_hat1 -= eta * gradient_w(xs, ys, y_hat1)n b_hat1 -= eta * gradient_b(xs, ys, y_hat1)nn if i_epoch % 20 == 0:n print(i_epoch, error(ys, y_hat1))n ax.plot(xs, y_hat1,n k, alpha=i_epoch / n_epochs)n fig.show()n plt.draw()nnprint(w_hat1, b_hat1)nfig.show()nplt.waitforbuttonpress()n
梯度下降迭代次數為1000次,學習率0.1,定義的三個函數依次為誤差函數,的梯度和的梯度。初始化和後,一步一步迭代,求得最優解。
TensorFlow版
寫了這麼長,終於寫到主角了。
說了這麼多,還是為了更好地學習TensorFlow。
n_epochs = 1000neta = 0.01nnX = tf.placeholder(tf.float32)nY = tf.placeholder(tf.float32)nw_hat2 = tf.Variable(tf.random_normal([1]), name=weight)nb_hat2 = tf.Variable(tf.random_normal([1]), name=bias)ny_hat2 = tf.add(tf.mul(X, w_hat2), b_hat2)ncost = tf.reduce_sum(tf.pow(y_hat2 - Y, 2)) / (n_observations - 1)noptimizer = tf.train.GradientDescentOptimizer(eta).minimize(cost)nnwith tf.Session() as sess:n sess.run(tf.global_variables_initializer())n prev_training_cost = 0.0n for i_epoch in range(n_epochs):n for (x, y) in zip(xs, ys):n sess.run(optimizer, feed_dict={X: x, Y: y})nn if i_epoch % 20 == 0:n training_cost = sess.run(cost, feed_dict={X: xs, Y: ys})n print(training_cost)n # ax.plot(xs, y_hat2.eval(feed_dict={x: xs}, session=sess), r, alpha=i_epoch / n_epochs) # something wrong with this function, //TODOn fig.show()n plt.draw()nn print(sess.run(w_hat2), sess.run(b_hat2))nfig.show()nplt.waitforbuttonpress()n
TensorFlow的一個優點就是定義好之後,可以選擇優化器來優化(迭代求最小值)這個目標函數,不用自己來做梯度下降。
之後迭代步驟只是反覆run優化器,來一步一步優化。
小節
說點真的題外話,感覺跟第一篇比較,這篇寫得十分匆忙,表達也十分隨意,一點也不嚴謹,好像失去了去好好寫專欄的動力。對能堅持寫專欄和GitHub的前輩們致敬,他們真的很厲害,很多事只有親身去做了,才覺得無比困難。
最近遇到了一些志同道合的朋友,能和他們一起努力真的十分快樂。希望自己能夠繼續寫下去,努力做一個優秀的人。與大家共勉。
推薦閱讀:
※Python資料庫起航篇|零基礎起步
※Sublime Text 3中怎麼更換python的版本?
※詳解Python元類
※第十六章 API例子:用Python驅動Firefox採集網頁數據
※初學python--認識裝飾器
TAG:TensorFlow | Python | 机器学习 |