接觸機器學習也有至關長的時間了,對各類學習算法都有了必定的瞭解,一直都不肯意寫博客(藉口是沒時間啊),最近準備學習深度學習框架tensorflow,決定仍是應該把本身的學習一步一步的記下來,方便後期的規劃。固然,學習一個新東西,第一步就是搭建一個平臺,這個網上不少相關博客,不過,仍是會遇到不少坑的,坑咋們不怕,趟過就行了。下面就以一個邏輯迴歸擬合二維數據爲例來入門介紹吧。(參考書:深度學習之Tensorflow入門原理與進階實踐)python
學習都是有必定套路的,深度學習通常狀況下:準備數據、搭建模型、迭代訓練及使用模型。固然,Tensorflow開發也是有套路的:算法
(1)定義Tensorflow輸入節點網絡
(2)定義「學習參數」等變量session
(3)定義「運算」(定義正向傳播模型 、定義損失函數)app
(4)優化函數、優化目標(反向傳播)框架
(5)初始化全部變量dom
(6)迭代更新參數直至最優解機器學習
(7)測試模型函數
(8)使用模型學習
在tensorflow中,將中間節點及節點間的運算關係(OPS)定義在內部的一個「圖」上,全經過一個「會話(session)」進行圖中OPS的具體運算。「圖」是靜態的,不管作任何運算,它們只是將關係搭建在一塊兒,並不會作任何運算;而「會話」是動態的,只有啓動會話後纔會將數據流向圖中,並按照圖中的關係進行運算,並將最終的結果從圖中流出。構建一個完整的圖通常須要定義3種變量:輸入結點(網絡的入口)、學習參數(鏈接各個節點的路徑)、模型中的節點。在實際訓練中,經過動態的會話將圖中的各個節點按照靜態的規則運算起來,每一次的迭代都會對圖中的學習參數進行更新調整,經過必定次數的迭代運算以後,最終所造成的圖即是所須要的「模型」。而在會話中,任何一個節點均可以經過會話的run函數進行計算,獲得該節點的真實數據。
模型內部的數據有正向和反向:正向,是數據從輸入開始,依次進行個節點定義的運算,一直運算到輸出,是模型最基本的數據流向,在模型的訓練、測試、使用的場景中都會用到的。反向,只有在訓練場景下才會用到,反項鍊式求導的方法,即先從正向的最後一個節點開始,計算此時結果值與真實值的偏差,造成一個關於學習參數表示偏差的方程,而後,對方程中的每一個參數求導,獲得其梯度修正值,同時反向推出上一層的偏差,這樣就將該層節點的偏差按照正向的相反方向傳到上一層,並接着計算上一層的修正值,如此反覆下去進行傳播,直到傳到正向的第一個節點。
一、準備數據
這裏採用y=2x直線爲主體,加入一些干擾噪聲
"""準備數據""" train_X= np.linspace(-1,1,100) train_Y= 2*train_X + np.random.randn(*train_X.shape)*0.3 plt.plot(train_X,train_Y,'ro',label="Original Data") plt.legend() plt.show()
二、搭建模型
模型的搭建分兩個方向:正向與反向
(1)正向搭建模型
神經網絡大可能是由多個神經元組成的,此處爲了簡單,採用單個神經元的網絡模型。
計算公式爲:z=w*xT + b (其中,w是矩陣,xT是矩陣x的轉置)w={w1,w2,...wi} xT={x1,x2.....xi} i=1,2,....n z表示輸出結果,x爲輸入數據,w爲權重,b爲偏執值。
模型每次的"學習"過程本質上就是調整w,b的值,以得到更適合的值。
"""創建模型"""
#佔位符 X=tf.placeholder("float") Y=tf.placeholder("float") #模型參數 W=tf.Variable(tf.random_normal([1]),name="weight") b=tf.Variable(tf.zeros([1]),name="bias") #前向 z=tf.multiply(X,W)+b
(2)反向搭建模型
在神經網絡的訓練過程當中數據流向是有兩個方向的,即先經過正向生成一個值,而後對比其與實際值的差距,再經過反向過程將裏面的參數進行調整,接着再次正向生成預測值並與真實值進行對比,這樣循環下去,直到將參數調整到合適值爲止。
1 #生成值與真實值的平方差 2 cost= tf.reduce_mean(tf.square(Y-z)) 3 #學習率 4 learning_rate= 0.01 5 #梯度降低 6 optimizer= tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
學習率表明調整參數的速度,這個值越大,代表調整的速度越大,相應的精確度越低,值越小,代表調整的精度越高,但學習速度越慢。GradientDescentOptimizer函數是一個封裝好的梯度降低算法。
三、迭代訓練模型
在tensorflow中,任務是經過Session來進行的,經過sess.run()來進行網絡節點的運算,經過feed機制將真實數據加載到佔位符對應的位置。
"""訓練模型""" init= tf.global_variables_initializer() training_epochs=20 display_step=2 with tf.Session() as sess: sess.run(init) plotdata={"batchsize":[], "loss":[]} def moving_average(a, w=10): if len(a)<w: return a[:] return [val if idx <w else sum(a[(idx-w):idx])/w for idx, val in enumerate(a)] for epoch in range(training_epochs): for (x,y) in zip(train_X, train_Y): sess.run(optimizer, feed_dict={X: x, Y:y }) if epoch % display_step == 0: loss = sess.run(cost, feed_dict={ X: train_X, Y: train_Y }) print ("Epoch:", epoch+1, " cost=", loss, "W=", sess.run(W), " b=",sess.run(b)) if not (loss == "NA"): plotdata["batchsize"].append(epoch) plotdata["loss"].append(loss) print( "Finished.") print( "cost=", sess.run(cost, feed_dict={ X:train_X, Y:train_Y }), "W=", sess.run(W), "b=", sess.run(b)) """訓練模型可視化""" plt.plot(train_X, train_Y, "ro", label="Original Data") plt.plot(train_X, sess.run(W)*train_X +sess.run(b), label="FittedLine") plt.legend() plt.show() plotdata["avgloss"]= moving_average(plotdata["loss"]) plt.figure(1) plt.subplot(211) plt.plot(plotdata["batchsize"], plotdata["avgloss"], "b--") plt.xlabel("Minibatch number") plt.ylabel("Loss") plt.title("Minibatch run vs.Training loss") plt.show()
結果:
Epoch: 1 cost= 0.9754149 W= [0.58673507] b= [0.4007497]
Epoch: 3 cost= 0.15794739 W= [1.648151] b= [0.11324686]
Epoch: 5 cost= 0.09357372 W= [1.9356339] b= [0.00494289]
Epoch: 7 cost= 0.08987887 W= [2.0101867] b= [-0.02363242]
Epoch: 9 cost= 0.08980431 W= [2.029468] b= [-0.03103093]
Epoch: 11 cost= 0.089843966 W= [2.0344524] b= [-0.03294369]
Epoch: 13 cost= 0.08985817 W= [2.0357416] b= [-0.03343845]
Epoch: 15 cost= 0.08986214 W= [2.0360765] b= [-0.03356693]
Epoch: 17 cost= 0.08986315 W= [2.0361621] b= [-0.03359992]
Epoch: 19 cost= 0.08986344 W= [2.0361862] b= [-0.03360903]
Finished.
cost= 0.0898635 W= [2.0361903] b= [-0.03361049]
能夠清楚看到,cost的值在不斷變小,w和b的值也在不斷地調整。最後,趨於獲得一條迴歸直線。
四、使用模型
模型訓練郝紅陽,使用起來就簡單了
如:print("x=2,z=",sess.run(z, feed_dict={X:2 }))便可。
tensorflow中定義輸入節點的方法:
(1)、經過佔位符定義(通常狀況下使用)如:
X=tf.placeholder("float")
Y=tf.placeholder("float")
(2)、經過字典類型定義(通常用於輸入比較多的狀況下)如:
inputdict = {
'x' : tf.placeholder("float),
'y' : tf.placeholder("float")
}
(3)直接定義*(通常不多用):將定義好的變量直接放到OP節點中參與輸入運算進行訓練。
完整代碼:
# -*- coding: utf-8 -*- """ Spyder Editor @Author:wustczx """ import tensorflow as tf import numpy as np import matplotlib.pyplot as plt """準備數據""" train_X= np.linspace(-1,1,100) train_Y= 2*train_X + np.random.randn(*train_X.shape)*0.3 plt.plot(train_X,train_Y,'ro',label="Original Data") plt.legend() plt.show() """創建模型""" X=tf.placeholder("float") Y=tf.placeholder("float") W=tf.Variable(tf.random_normal([1]),name="weight") b=tf.Variable(tf.zeros([1]),name="bias") z=tf.multiply(X,W)+b #生成值與真實值的平方差 cost= tf.reduce_mean(tf.square(Y-z)) #學習率 learning_rate= 0.01 #梯度降低 optimizer= tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) """訓練模型""" init= tf.global_variables_initializer() training_epochs=20 display_step=2 with tf.Session() as sess: sess.run(init) plotdata={"batchsize":[], "loss":[]} def moving_average(a, w=10): if len(a)<w: return a[:] return [val if idx <w else sum(a[(idx-w):idx])/w for idx, val in enumerate(a)] for epoch in range(training_epochs): for (x,y) in zip(train_X, train_Y): sess.run(optimizer, feed_dict={X: x, Y:y }) if epoch % display_step == 0: loss = sess.run(cost, feed_dict={ X: train_X, Y: train_Y }) print ("Epoch:", epoch+1, " cost=", loss, "W=", sess.run(W), " b=",sess.run(b)) if not (loss == "NA"): plotdata["batchsize"].append(epoch) plotdata["loss"].append(loss) print( "Finished.") print( "cost=", sess.run(cost, feed_dict={ X:train_X, Y:train_Y }), "W=", sess.run(W), "b=", sess.run(b)) """訓練模型可視化""" plt.plot(train_X, train_Y, "ro", label="Original Data") plt.plot(train_X, sess.run(W)*train_X +sess.run(b), label="FittedLine") plt.legend() plt.show() plotdata["avgloss"]= moving_average(plotdata["loss"]) plt.figure(1) plt.subplot(211) plt.plot(plotdata["batchsize"], plotdata["avgloss"], "b--") plt.xlabel("Minibatch number") plt.ylabel("Loss") plt.title("Minibatch run vs.Training loss") plt.show()