1. 程式人生 > >Python20行程式碼實現多層神經網路的學習

Python20行程式碼實現多層神經網路的學習

轉載自:python小練習(062):python20行程式碼實現多層神經網路的機器學習(一)http://bbs.fishc.com/thread-81849-1-1.html(出處: 魚C論壇)

今天在魚C論壇看到一個很好的入門機器學習的小例子,分享給大家。

現在神經網路、機器學習、深度學習逐漸成為未來計算機發展的大趨勢。今天就通過一個很簡單的小例子,淺談一下如何用python實現多層神經網路的機器學習。神經網路(Neural Networks)屬於 機器學習(Machine Learning)的一種。深層神經網路(Deep Neural Networks)也只是 深層學習(Deep Learning) 的一種。"深度學習"是為了讓層數較多的多層神經網路可以訓練,能夠work而演化出來的一系列的 新的結構和新的方法。好吧,太複雜的概念大家可以google,這裡舉個簡單的例子說明:例如,有一組輸入:X = 1,2,3,4,5,6,7,8,9,10有一組輸出:Y = 10,20,30,40,50,60,70,80,90,100求解:Y = k*X + b 中的 k 和 b 為何值時,函式擬合最好。當然,這是非常簡單的題目,用腳趾頭想都能知道這個函式當然應該是 Y = 10 * X + 0,即 k = 10, b = 0.那麼用神經網路學習應該如何實現呢?賣個關子。我們先看結果吧:當學習次數為100時,程式輸出:k=9.999852648623337 b=0.0007369339496443169當學習次數為10000時,程式輸出:k=9.999866463857986 b=0.0007360277038955244當學習次數為1000000時,程式輸出:k=9.999935468934599 b=0.0003552889884596963可以看到隨著學習次數的增加,輸出值會無限接近標準值(但是永遠也打不到標準值,因為機器學習的特點就是根據偏差值不斷調整自身引數,以不斷減小誤差,但是誤差是永遠存在的。)下面詳細解釋程式程式碼:首先,我們要定義一個函式,這個函式的作用是能夠把輸入值轉化為一個0~1之間的數,並且當輸入值與0的差值越大,輸出越接近1,輸入值越接近0時,輸入值也越接近於0. 這個函式的作用就是用來調整機器本身引數,使結果更加接近於標準值。那麼,我們這個函式F(x)= (e^x -1) / (e^x + 1) 就符合這樣的要求,其中x>=0(取絕對值)。def F(x):    return (math.exp(abs(x))-1)/(math.exp(abs(x))+1)然後當然要把X和Y以列表的形式放入以便機器學習使用。X = list(range(1,11))Y = list(range(10,110,10))由於有k和b 2個未知數,我們設定一個二層的神經網路。把X作為第一層輸入,k*X作為第一層的輸出把k*X作為第二層輸入,k*X+b作為第二層的輸出利用k*X與Y-b計算第一層的偏差值error1,代入F(error1)計算權重,然後把這個權重值*error1作為k值的調整值同樣,利用k*X+b與Y計算第二層的偏差值error2,代入F(error2)計算權重,再把這個權重值*error2作為b值的調整值然後,不斷反覆迭代這個過程,使得k和b不斷接近標準值。這個過程就是這樣。20行原始碼如下:
import math
def F(x):
    return (math.exp(abs(x))-1)/(math.exp(abs(x))+1)

X = list(range(1,11))
Y = list(range(10,110,10))

k,b = 0,0
for repeat in range(1000000):
    for i in range(10):
        c1 = k*X[i]
        e1 = Y[i]-b-c1
        d1 = e1*F(e1)
        k += d1
        c2 = k*X[i]+b
        e2 = Y[i]-c2
        d2 = e2*F(e2)
        b += d2

print (k,b)

既然說到了,神經網路那不提google的開源大作tensorflow就實在說不過去了,所以我決定還是要把這段加上。
同樣20行左右的程式碼(去掉註釋),完成同樣的工作,而且tensorflow是一個非常完善的庫,可以用來做非常多的機器學習的專案。
直接上程式碼,註釋都寫好了:
import tensorflow as tf
import numpy as np

# 使用 NumPy 生成假資料(phony data), 總共 100 個點.
x_data = np.float32(np.random.rand(1, 100))  # 隨機輸入
y_data = np.dot([10], x_data) + 0

# 構造一個線性模型
b = tf.Variable(tf.zeros([1])) + 0.1
W = tf.Variable(tf.random_uniform([1, 1], -1.0, 1.0))
y = tf.matmul(W, x_data) + b

# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

# 初始化變數
init = tf.initialize_all_variables()

# 啟動圖 (graph)
sess = tf.Session()
sess.run(init)

# 擬合平面
for step in range(0, 301):
    sess.run(train)
    if step % 30 == 0:
        print (step, sess.run(W), sess.run(b), sess.run(loss))

輸出:
Step     k                         b                         error
0 [[ 4.0464325]] [ 4.64299202] 5.73681
30 [[ 9.25678635]] [ 0.40823561] 0.0502534
60 [[ 9.91544819]] [ 0.04644302] 0.000650405
90 [[ 9.99038124]] [ 0.00528351] 8.41773e-06
120 [[ 9.99890614]] [ 0.00060082] 1.08852e-07
150 [[ 9.99987507]] [  6.87018037e-05] 1.41737e-09
180 [[ 9.99998474]] [  8.32974911e-06] 2.0752e-11
210 [[ 9.99999619]] [  2.02655792e-06] 1.39467e-12
240 [[ 9.99999619]] [  2.02655792e-06] 1.39467e-12
270 [[ 9.99999619]] [  2.02655792e-06] 1.39467e-12
300 [[ 9.99999619]] [  2.02655792e-06] 1.39467e-12