簡單入門機器學習與TensorFlow(1)
0.概念:
機器學習是什麼呢?機器學習就是不用編寫顯性的邏輯代碼就能解決問題。
這裡的「顯性」,很簡單,是指傳統的代碼
def function(param): a=0 b=0 # xxxx各種邏輯xxxx return ret
而不用「顯性的邏輯代碼」則是通過給一個恰當的模型(這個模型有很多參數,也像一個函數),然後讓機器來學習而使得這個模型達到一種穩定的狀態(就是參數「調對了」)也就是達到我們所希望的輸入與輸出。
更簡單點說就是:我們看不清這裡面的邏輯(所以很多人稱機器學習是玄學??)
這樣做有什麼好處呢?
- 簡單(相比傳統的邏輯代碼),可以很好的解決目前人類在邏輯上有缺陷的問題,比如:圖像識別,語音識別,等等諸如此類。想想,如果不用機器學習,就用傳統代碼怎麼才能識別圖像呀!
- 模型泛化能力好,能同時解決同類問題。譬如:AlphaGo Zero在圍棋界已經天下無敵,但它在其他棋類也是無敵的,試想下如果要傳統方式那得寫多少東西。
好處還有很多嗯,不過也有壞處:
- 目前比較火的是深度學習和強化學習,深度學習的一個難點在於數據,要求是「有代表性的數據」和「大量數據」,並且需要人工打標籤。著實是個量很大的工作。強化學習的一個難點是搭建環境和制定規則,很容易漏東西。
- 選擇模型也是個難點,還有超參數的值的設定(不過現在網上有很多訓練的好的樣例,多看看就能很好決解)
最後總結下,機器學習目前解決很多曾經很頭疼的問題,而且這也是個趨勢,它講解決更多問題,反正現在互聯網時代,能解決生活問題才是王道。??還有賺錢
1.快速入門:
我們來用直線來擬合這一系列點:(1, 0)、(2, 2)、(3, 5)、(4, 12)、(5, 22);
如果用傳統方法,則要編寫最小二乘法來解決此類問題。
那麼用機器學習的方法如何做呢?
得到數據後我們要確定模型,我們用一元一次方程:y = w * x + b
在這裡我們模型的參數為w和b
然後確定損失函數(即預測與真實的差),我們用方差:sum[(y真實 - y估計)^2]
最後我們用梯度下降法訓練模型,而我們根據方差確定訓練方向(即參數變化趨勢)
多次訓練後,就能得到一個很好的模型。
在機器學習中,監督式學習(Supervised Learning)通過定義一個模型,並根據訓練集上的數據估計最優參數。梯度下降法(Gradient Descent)是一個廣泛被用來最小化模型誤差的參數優化演算法。梯度下降法通過多次迭代,並在每一步中最小化損失函數(loss function)來估計模型的參數(weights)。
具體代碼:
import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltsess = tf.Session() # tensorflow要求有一個會話,tf的運算步驟要在會話里完成,具體看代碼x_input = [1, 2, 3, 4, 5] # 輸入點的x坐標,在後面「喂」到x裡面y_true = [0, 2, 5, 12, 22] # 輸入點的y坐標steps = []loss_value = []x = tf.placeholder(dtype=tf.float32) # x為輸入佔位,到後面要用feed_dict拿數據「喂」給這個xw1 = tf.Variable([2], dtype=tf.float32) # 用於訓練的參數w,裡面的參數在開始可以隨便設# w2 = tf.Variable([2], dtype=tf.float32) # 二次函數擬合參數b = tf.Variable([3], dtype=tf.float32) # 用於訓練的參數by = x * w1 + b # 模型# y += tf.pow(x, 2) * w2 # 改為二次式target = tf.placeholder(dtype=tf.float32) # 目標,也就是真實的y值loss = tf.reduce_sum(tf.square(y - target)) # 損失函數:方差optimizer = tf.train.AdamOptimizer(0.001) # 優化器,核心演算法梯度下降,參數為學習率train = optimizer.minimize(loss) # 訓練 -> 減小損失函數sess.run(tf.global_variables_initializer()) # 必須寫,tf的初始化所有全局變數print(sess.run(y, {x: x_input}))desplay = 1000for i in range(20000): # 讓它進行20000次下降(越多越好,但是也更慢) # feed_dict就是把佔位的填充。這裡:讓x_input作為x,y_true作為target輸入 sess.run(train, feed_dict={x: x_input, target: y_true}) if i % desplay == 0: # 每1000步查看一次 l_value = sess.run(loss, feed_dict={x: x_input, target: y_true}) steps.append(i) loss_value.append(l_value) print("No." + str(i) + " : ", l_value)print(sess.run(y, feed_dict={x: x_input}))print("step:", steps)print("loss value:", loss_value)# 下面是繪圖,看最終效果plt.figure(num=1)plt.scatter(x_input, y_true, marker=x)x_pt = np.linspace(1, 5)plt.plot(x_pt, sess.run(y, feed_dict={x: x_pt}), linestylex=--, color=r)plt.figure(num=2)plt.plot(steps, loss_value)plt.xlabel(steps)plt.ylabel(loss)plt.show()
順便解釋下:超參數:人為地加入的參數,不可由機器學習而更新。比如學習率
學習率就是每次梯度下降演算法迭代更新參數的步長
學習率不可太高,可以先設為很低,然後慢慢提高。
由上圖可看出擬合效果也還不錯,和傳統方法一樣好了。
當然如果您不太滿意,也可以用二次函數再擬合一次(代碼中注釋的)
把它變成y = w1*x + w2*x^2 + b就可以,改成三四五次的都可以,想怎麼用就怎麼用
(注意,參數多了容易發生過擬合)
最後上二次函數擬合的結果:
果然二次函數擬合效果更好,那麼相比,一次函數不是那麼好,它就是「欠擬合」了。
下一節我們就建立一個單層的神經網路,直接上數字的手寫識別。
文中有不準確的歡迎大佬留言,我非常希望你們能幫上我。??
封面我最愛的Nevada
推薦閱讀:
※Inside TF-Slim(2) arg_scope
※機器學習 | 更進一步,用評估器給花卉分類
※【博客存檔】TensorFlow之深入理解Neural Style
※如何在 TensorFlow 中使用多個 Graph
TAG:機器學習 | TensorFlow | 入門指南 |