基於BP神經網路的函式逼近方法以及python實現(含課程論文)
阿新 • • 發佈:2020-12-28
基於BP神經網路的函式逼近方法(含課程論文)
文章目錄
前言
四個輸入一個輸出,用python實現的程式碼,最終得到誤差圖(不是基於方差,而是純粹的數值差值)
一、神經網路結構
4個輸入一個輸出,進行函式逼近,10個隱藏層節點。
1.程式碼
程式碼如下(示例):
###啟用函式用的是sigmoid
import numpy as np
import math
import matplotlib.pyplot as plt
import math
x1 = np.linspace(0, 2*math.pi, 602)
x2 = np.linspace(0.1, 2*math.pi, 602)
x3 = np.linspace(0.2, 2*math.pi, 602)
x4 = np.linspace(0.3, 2*math.pi, 602)
x5 = np.linspace(0, 2*math.pi, 602) # x5~x8搞測試
x6 = np.linspace(0.1, 2*math.pi, 602)
x7 = np.linspace(0.2, 2*math.pi, 602)
x8 = np.linspace(0.3, 2*math.pi, 602)
c = np.zeros ((601, 1)) # 儲存實際輸出值
C = np.zeros((601, 1)) # 儲存測試輸出值
x_size = 601
y = np.zeros((x_size, 1))
for i in range(x_size):
y[i] = math.sin(x1[i])+math.sin(x2[i])+math.sin(x3[i])+math.sin(x4[i])
for i in range(101):
c[i] = math.sin(x5[i])+math.sin(x6[i])+math.sin(x7[i])+math. sin(x8[i])
hidesize = 10
W11 = np.random.random((hidesize, 1)) # x1輸入層與隱層之間的權重
B1 = np.random.random((hidesize, 1)) # 隱含層神經元的閾值
W2 = np.random.random((1, hidesize)) # 隱含層與輸出層之間的權重
B2 = np.random.random((1, 1)) # 輸出層神經元的閾值
W12 = np.random.random((hidesize, 1)) # x2輸入層與隱層之間的權重
W13 = np.random.random((hidesize, 1)) # x3輸入層與隱層之間的權重
W14 = np.random.random((hidesize, 1)) # x4輸入層與隱層之間的權重
threshold = 0.0001 # 學習率 通過多次試驗得出
max_steps = 1000 # 迭代次數
def sigmoid(x_): # 定義sigmoid啟用函式
y_ = 1 / (1 + math.exp(-x_))
return y_
Y = np.zeros((x_size, 1)) # 模型的輸出結果 x_size行 1列
for k in range(x_size):
for i in range(max_steps):
hide_in = np.dot(x1[k], W11)+np.dot(x2[k], W12)+np.dot(x3[k], W13)+np.dot(x4[k], W14) - B1 # 隱含層輸入資料 x[i]和W11的內積
#print(x1[i])
hide_out = np.zeros((hidesize, 1)) # 隱含層的輸出資料 記住用來之後的引數調整
for j in range(hidesize):
hide_out[j] = sigmoid(hide_in[j]) #sigmoid啟用函式輸出值
y_out = np.dot(W2, hide_out) + B2 # 模型輸出
e = y_out - y[k] # 模型輸出減去實際結果。得出誤差
#print(e)
##網路權重與神經元偏置調整
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)
dW11 = np.zeros((hidesize, 1))
dW12 = np.zeros((hidesize, 1))
dW13 = np.zeros((hidesize, 1))
dW14 = np.zeros((hidesize, 1))
for j in range(hidesize):
dW11[j] = np.dot(np.dot(W2[0][j], sigmoid(hide_in[j])), (1 - sigmoid(hide_in[j])) * x1[k] * e * threshold)
dW12[j] = np.dot(np.dot(W2[0][j], sigmoid(hide_in[j])), (1 - sigmoid(hide_in[j])) * x2[k] * e * threshold)
dW13[j] = np.dot(np.dot(W2[0][j], sigmoid(hide_in[j])), (1 - sigmoid(hide_in[j])) * x3[k] * e * threshold)
dW14[j] = np.dot(np.dot(W2[0][j], sigmoid(hide_in[j])), (1 - sigmoid(hide_in[j])) * x4[k] * e * threshold)
W11 = W11 - dW11
W12 = W12 - dW12
W13 = W13 - dW13
W14 = W14 - dW14
B1 = B1 - dB1
W2 = W2 - dW2
B2 = B2 - dB2
number = 0
#每訓練完一個樣本 測試一次 總共600次
# for q in range(601):
# ceshi_in = np.dot(x1[q], W11) + np.dot(x2[q], W12) + np.dot(x3[q], W13) + np.dot(x4[q],W14) - B1 # 隱含層輸入資料 x[i]和W11的內積 ceshi_out = np.zeros((hidesize, 1)) # 隱含層的輸出資料 記住用來之後的引數調整
# ceshi_out = np.zeros((hidesize, 1)) # 隱含層的輸出資料
# for j in range(hidesize):
# ceshi_out[j] = sigmoid(ceshi_in[j]) # sigmoid啟用函式輸出值
# w = np.dot(W2, ceshi_out) + B2 - c[q]
# w = float(w)
# w = w*w
# #print(w)
# if abs(w)< 0.5:
# number += 1
# C[k] = number/601
# #print(C[k])
Y[k] = y_out
if k % 10 == 0:
print(k)
a = np.linspace(1, x_size, x_size)
plt.figure()
plt.plot(a, abs(y-Y), color='red', linestyle='--') #沒有用方差表示誤差
plt.show()
# plt.figure()
# plt.plot(a, C, color='blue', linestyle='--') #準確率
# plt.show()
總結
之中有些地方可能存在誤差圖波動較大,需要大家根據迭代次數和訓練樣本數量調整學習率。準確率的圖有問題,但是覺得大方向沒有錯,所以也想請大家一起修改一下。