1. 程式人生 > >利用BP神經網路逼近函式——Python實現

利用BP神經網路逼近函式——Python實現

  文章主要參考https://blog.csdn.net/john_bian/article/details/79503572,原文是matlab版本的實現。在此基礎上,利用Python實現BP網路對函式y=sinx的逼近。對於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的效果如下:

迭代500次

 可以看到效果不是很好,主要有以下原因:第一是在函式上取得點過少(上面程式碼中取了100個點);第二就是迭代次數還達不到。大家都知道神經網路,需要大量資料以及高額的計算代價。改變引數,選取600個點以及迭代700次,效果如下:

700

可以發現效果比剛才已經好了很多。繼續增加迭代次數,可以得到更好的擬合效果,另外誤差的效果圖這裡就不再展示了,感興趣的可以自己用程式碼實現。