利用BP神經網路逼近函式——Python實現
阿新 • • 發佈:2019-01-09
文章主要參考https://blog.csdn.net/john_bian/article/details/79503572,原文是matlab版本的實現。在此基礎上,利用Python實現BP網路對函式的逼近。對於BP神經網路的基本原理以及推倒,這裡就不再贅述,可以查閱相關文獻。
程式碼如下:
###function approximation f(x)=sin(x) ###2018.08.15 ###啟用函式用的是sigmoid import numpy as np import math #import matplotlib.pyplot as plt x = np.linspace(-3,3,100) x_size = x.size y = np.zeros((x_size,1)) # print(y.size) for i in range(x_size): y[i]= math.sin(x[i]) hidesize = 10 W1 = np.random.random((hidesize,1)) #輸入層與隱層之間的權重 B1 = np.random.random((hidesize,1)) #隱含層神經元的閾值 W2 = np.random.random((1,hidesize)) #隱含層與輸出層之間的權重 B2 = np.random.random((1,1)) #輸出層神經元的閾值 threshold = 0.005 max_steps = 501 def sigmoid(x_): y_ = 1/(1+math.exp(-x_)) return y_ E = np.zeros((max_steps,1))#誤差隨迭代次數的變化 Y = np.zeros((x_size,1)) # 模型的輸出結果 for k in range(max_steps): temp = 0 for i in range(x_size): hide_in = np.dot(x[i],W1)-B1 # 隱含層輸入資料 #print(x[i]) hide_out = np.zeros((hidesize,1)) #隱含層的輸出資料 for j in range(hidesize): #print("第{}個的值是{}".format(j,hide_in[j])) #print(j,sigmoid(j)) hide_out[j] = sigmoid(hide_in[j]) #print("第{}個的值是{}".format(j, hide_out[j])) #print(hide_out[3]) y_out = np.dot(W2,hide_out) - B2 #模型輸出 Y[i] = y_out e = y_out - y[i] # 模型輸出減去實際結果。得出誤差 ##反饋,修改引數 dB2 = -1*threshold*e dW2 = e*threshold*np.transpose(hide_out) dB1 = np.zeros((hidesize,1)) for j in range(hidesize): dB1[j] = np.dot(np.dot(W2[0][j],sigmoid(hide_in[j])),(1-sigmoid(hide_in[j]))*(-1)*e*threshold) dW1 = np.zeros((hidesize,1)) for j in range(hidesize): dW1[j] = np.dot(np.dot(W2[0][j],sigmoid(hide_in[j])),(1-sigmoid(hide_in[j]))*x[i]*e*threshold) W1 = W1 - dW1 B1 = B1 - dB1 W2 = W2 - dW2 B2 = B2 - dB2 temp = temp + abs(e) E[k] = temp if k%100==0: print(k)
上面是實現對正弦函式逼近的程式碼,具體畫圖部分沒有貼。迭代500的效果如下:
可以看到效果不是很好,主要有以下原因:第一是在函式上取得點過少(上面程式碼中取了100個點);第二就是迭代次數還達不到。大家都知道神經網路,需要大量資料以及高額的計算代價。改變引數,選取600個點以及迭代700次,效果如下:
可以發現效果比剛才已經好了很多。繼續增加迭代次數,可以得到更好的擬合效果,另外誤差的效果圖這裡就不再展示了,感興趣的可以自己用程式碼實現。