前言
【深度學習的數學】接“2×3×1層帶sigmoid激活函數的神經網絡感知機對三角形平面的分類訓練預測”,輸出層加偏置b
在上↑一次測試中,我們使用了2×3×1層輸出層帶偏置b的神經網絡進行預測,但是發現繪製的分割平面數量不夠,導致沒能達到我們的分割效果
本次測試我們將在第一個隱藏層添加一個神經單元w4
直接上在上一節的基礎上修改的代碼吧!
代碼
修改之前錯誤的代碼
修改代碼的時候,看到這裏我驚呆了,,
是不是之前的,,,弄錯了ll、
改過來看看
之前不能很好擬合,不會就是因爲我把這個寫錯了吧淦,ԾㅂԾ,
試了N次,模型都不能收斂,試到N+1次時,出現了這個情況:
這就很離譜- -
但是看損失值還是很大,是不是繪圖除了問題??
然後發現指數函數有溢出,在這裏解決了:
python計算警告:overflow encountered in exp(指數函數溢出)
然後試了n次,就沒一個收斂的,不知啥情況???
又檢查檢查,發現我這好像也有問題??(覈查了一下,發現就是這樣的,沒啥問題)
我這個地方好像還是有問題!!公式不是這樣的,參見:
【深度學習的數學】2×3×1層帶sigmoid激活函數的神經網絡感知機對三角形平面的分類訓練預測(繪製出模型結果三維圖展示效果)(梯度下降法+最小二乘法+激活函數sigmoid+誤差反向傳播法)
改過來(目標損失對當前神經單元的權重偏導=當前神經單元誤差×上一層輸入神經單元的輸出):
運行程序,奇蹟出現了,可以看到,結果損失一直波動減少到300左右,繪製的三維圖結果跟我們的預期又接近一些了,除了高度Z和三角形平臺右邊的平面沒有擬合到之外,其餘的,看起來都非常漂亮!!
w2=[[ 0.067 2.913 -4.402 -1.848]
[ 7.913 -5.987 8.991 -0.048]]
b2=[ 3.292 2.061 -2.798 0.408]
w3=[10.782 3.335 -8.155 -1.165]
b3=[-6.659]
損失總和C:302.191528
# -*- coding: utf-8 -*-
"""
@File : 接“2×4×1層帶sigmoid激活函數的神經網絡感知機對三角形平面的分類訓練預測”,輸出層加偏置b.py
@Time : 2020/6/4 15:40
@Author : Dontla
@Email : [email protected]
@Software: PyCharm
"""
from matplotlib import pyplot as plt # 用來繪製圖形
from mpl_toolkits.mplot3d import Axes3D
import numpy as np # 用來處理數據
# Dontla:定義sigmoid函數
def sigmoid(x):
x_ravel = x.ravel() # 將numpy數組展平
length = len(x_ravel)
y = []
for index in range(length):
if x_ravel[index] >= 0:
y.append(1.0 / (1 + np.exp(-x_ravel[index])))
else:
y.append(np.exp(x_ravel[index]) / (np.exp(x_ravel[index]) + 1))
return np.array(y).reshape(x.shape)
# Dontla:定義sigmoid的導數函數
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
# 準備訓練數據
# X = np.arange(-10, 10, 0.25)
# X1 = np.arange(-10, 20, 1)
X1 = np.arange(-5, 15, 1)
# Y = np.arange(-10, 10, 0.25)
# X2 = np.arange(-10, 15, 1)
X2 = np.arange(-5, 10, 1)
X1, X2 = np.meshgrid(X1, X2)
# Z = 0 * np.ones((25, 30))
# print(list(Z))
T = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 5., 5., 5., 5., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 5., 5., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.]])
# 【構建神經網絡】
# 初始化神經網絡參數(用正態分佈隨機數)
w2 = np.random.randn(2, 4)
b2 = np.random.randn(4)
w3 = np.random.randn(4)
b3 = np.random.randn(1)
# w2 = np.random.randn(2, 3)
# b2 = np.random.randn(3)
# w3 = np.random.randn(3)
# b3 = np.random.randn(1)
# w2 = np.array([[1.936, -10.246, -16.059], [3.856, 1.978, 2.899]])
# b2 = np.array([2.327, 1.111, -1.26])
# w3 = np.array([0.487, -1.382, -2.505])
# b3 = np.array([0.641])
# 比較好的結果(損失331)
# w2 = np.array([[244.429, -32.861, -120.832], [244.893, 243.652, 245.117]])
# b2 = np.array([0.076, -4.036, -16.428])
# w3 = np.array([13.477, -0.982, -11.57])
# b3 = np.array([-4.353])
# 利用誤差反向傳播法求解各梯度分量
# 學習率
learning_rate = 0.1
# 創建預測值變量
T_Predict = None
# 創建實時繪製損失值的橫縱軸變量
iter_list = []
neural_network_error_list = []
# 創建繪製實時損失的動態窗口
plt.ion()
# 計算z2(首次)
z2_1 = w2[0, 0] * X1 + w2[1, 0] * X2 + b2[0]
z2_2 = w2[0, 1] * X1 + w2[1, 1] * X2 + b2[1]
z2_3 = w2[0, 2] * X1 + w2[1, 2] * X2 + b2[2]
z2_4 = w2[0, 3] * X1 + w2[1, 3] * X2 + b2[3]
# print(z2_1.shape) # (25, 30)
# print(np.around(z2_1, decimals=3))
# 計算a2(首次)
a2_1 = sigmoid(z2_1)
a2_2 = sigmoid(z2_2)
a2_3 = sigmoid(z2_3)
a2_4 = sigmoid(z2_4)
# print(a2_1.shape) # (25, 30)
# 計算z3(首次)
z3_1 = w3[0] * a2_1 + w3[1] * a2_2 + w3[2] * a2_3 + w3[3] * a2_4 + b3
# print(z3_1.shape) # (25, 30)
# 計算a3(首次)
a3_1 = sigmoid(z3_1)
# print(a3_1.shape) # (25, 30)
# 構建神經單元誤差關係式
# 創建計算循環(訓練次數)
for i in range(300):
# 使用誤差反向傳播法計算神經單元損失(Neural unit error —— nue)
nue3_1 = (a3_1 - T) * sigmoid_derivative(z3_1)
nue2_1 = nue3_1 * w3[0] * sigmoid_derivative(z2_1)
nue2_2 = nue3_1 * w3[1] * sigmoid_derivative(z2_2)
nue2_3 = nue3_1 * w3[2] * sigmoid_derivative(z2_3)
nue2_4 = nue3_1 * w3[3] * sigmoid_derivative(z2_4)
# print(nue3_1.shape) # (25, 30)
# print(nue2_1.shape) # (25, 30)
# 計算各權重和偏置參數的梯度
gradientCt_w2_1to1 = np.sum(nue2_1 * X1)
gradientCt_w2_1to2 = np.sum(nue2_2 * X1)
gradientCt_w2_1to3 = np.sum(nue2_3 * X1)
gradientCt_w2_1to4 = np.sum(nue2_4 * X1)
gradientCt_w2_2to1 = np.sum(nue2_1 * X2)
gradientCt_w2_2to2 = np.sum(nue2_2 * X2)
gradientCt_w2_2to3 = np.sum(nue2_3 * X2)
gradientCt_w2_2to4 = np.sum(nue2_4 * X2)
# print(gradientC_w2_1to1.shape) # (25, 30)
gradientCt_b2_1 = np.sum(nue2_1)
gradientCt_b2_2 = np.sum(nue2_2)
gradientCt_b2_3 = np.sum(nue2_3)
gradientCt_b2_4 = np.sum(nue2_4)
# print(gradientC_b2_1.shape) # (25, 30)
gradientCt_w3_1to1 = np.sum(nue3_1 * a2_1)
gradientCt_w3_2to1 = np.sum(nue3_1 * a2_2)
gradientCt_w3_3to1 = np.sum(nue3_1 * a2_3)
gradientCt_w3_4to1 = np.sum(nue3_1 * a2_4)
# print(gradientC_w3_1to1.shape) # (25, 30)
gradientCt_b3_1 = np.sum(nue3_1)
# 更新各權重和偏置參數
w2 += np.array([[gradientCt_w2_1to1, gradientCt_w2_1to2, gradientCt_w2_1to3, gradientCt_w2_1to4],
[gradientCt_w2_2to1, gradientCt_w2_2to2, gradientCt_w2_2to3, gradientCt_w2_2to4]]) * -learning_rate
b2 += np.array([gradientCt_b2_1, gradientCt_b2_2, gradientCt_b2_3, gradientCt_b2_4]) * -learning_rate
w3 += np.array([gradientCt_w3_1to1, gradientCt_w3_2to1, gradientCt_w3_3to1, gradientCt_w3_4to1]) * -learning_rate
b3 += np.array([gradientCt_b3_1]) * -learning_rate
# 計算z2
z2_1 = w2[0, 0] * X1 + w2[1, 0] * X2 + b2[0]
z2_2 = w2[0, 1] * X1 + w2[1, 1] * X2 + b2[1]
z2_3 = w2[0, 2] * X1 + w2[1, 2] * X2 + b2[2]
z2_4 = w2[0, 3] * X1 + w2[1, 3] * X2 + b2[3]
# print(z2_1.shape) # (25, 30)
# print(np.around(z2_1, decimals=3))
# 計算a2
a2_1 = sigmoid(z2_1)
a2_2 = sigmoid(z2_2)
a2_3 = sigmoid(z2_3)
a2_4 = sigmoid(z2_4)
# print(a2_1.shape) # (25, 30)
# 計算z3
z3_1 = w3[0] * a2_1 + w3[1] * a2_2 + w3[2] * a2_3 + w3[3] * a2_4 + b3
# print(z3_1.shape) # (25, 30)
# 計算a3
a3_1 = sigmoid(z3_1)
# print(a3_1.shape) # (25, 30)
T_Predict = a3_1
# 打印參數
print('第{:0>2d}輪'.format(i + 1))
print('w2={}'.format(np.around(w2, decimals=3)))
print('b2={}'.format(np.around(b2, decimals=3)))
print('w3={}'.format(np.around(w3, decimals=3)))
print('b3={}'.format(np.around(b3, decimals=3)))
# 計算損失C
# C = np.sum(1 / 2 * np.power(T_Predict - T, 2))
C = np.around(np.sum(1 / 2 * np.power(T_Predict - T, 2)), decimals=6)
print('損失總和C:{}'.format(C))
# 實時繪製損失值圖表
iter_list.append(i)
neural_network_error_list.append(C)
plt.clf() # 清除之前畫的圖
plt.plot(iter_list, neural_network_error_list * np.array([-1])) # 畫出當前iter_list列表和neural_network_error_list列表中的值的圖形
plt.pause(0.001) # 暫停一段時間,不然畫的太快會卡住顯示不出來
plt.ioff() # 關閉畫圖窗口
# 繪製三維圖
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X1, X2, T_Predict, cmap='rainbow')
plt.show()
知道爲何Z的結果不能擬合到預期的5了
因爲你用a3_1 = sigmoid(z3_1)
作爲最終輸出相當於把輸出的值限定在(0,1)之間了!!!
解決辦法1:取消輸出層神經單元的a和b(直接將z作爲輸出)(這個辦法不行,影響神經單元的完整性,沒法計算出輸出層神經單元誤差,從而使用誤差反向傳播法了)(×)
解決辦法2:將輸出層的z作爲最終三角凸臺的高度Z(這樣是錯誤的,損失函數計算會出問題)(×)
解決辦法3:將預期數據T歸一化,使其符合我們神經網絡的輸出(√)
以0.1爲學習率訓練1000次
效果不是特別理想,可能是學習率太大導致波動太大
以0.01爲學習率訓練1000次
也不是太理想
以0.01爲學習率訓練10000次(奇蹟出現了!)
我們預期的基本輪廓居然出來了,雖然擬合得還不是特別完美,但是結果大體顯現!!
w2=[[-1.505 -3.632 0.371 -0.143]
[ 0.059 6.991 1.435 -5.638]]
b2=[16.158 -1.75 0.442 -2.712]
w3=[ 7.504 -9.317 0.417 -8.363]
b3=[-3.698]
損失總和C:0.852291 學習率learning rate:0.01 訓練次數:9999
我們以本次訓練得到的權重結果作爲預訓練模型,再對模型訓練100000次(結果非常良好!!!)
結果顯示擬合得非常良好
第100000輪
w2=[[-2.17 -4.642 0.566 -0.156]
[ 0.016 9. 1.347 -6.607]]
b2=[22.88 -1.785 0.501 -2.868]
w3=[ 13.89 -12.622 -0.316 -12.369]
b3=[-6.969]
損失總和C:0.008305 學習率learning rate:0.01 訓練次數:100000
最後附上最終成功的2×4×1層代碼
# -*- coding: utf-8 -*-
"""
@File : 接“2×4×1層帶sigmoid激活函數的神經網絡感知機對三角形平面的分類訓練預測”,輸出層加偏置b.py
@Time : 2020/6/4 15:40
@Author : Dontla
@Email : [email protected]
@Software: PyCharm
"""
from matplotlib import pyplot as plt # 用來繪製圖形
from mpl_toolkits.mplot3d import Axes3D
import numpy as np # 用來處理數據
# Dontla:定義sigmoid函數
def sigmoid(x):
x_ravel = x.ravel() # 將numpy數組展平
length = len(x_ravel)
y = []
for index in range(length):
if x_ravel[index] >= 0:
y.append(1.0 / (1 + np.exp(-x_ravel[index])))
else:
y.append(np.exp(x_ravel[index]) / (np.exp(x_ravel[index]) + 1))
return np.array(y).reshape(x.shape)
# Dontla:定義sigmoid的導數函數
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
# 準備訓練數據
# X = np.arange(-10, 10, 0.25)
# X1 = np.arange(-10, 20, 1)
X1 = np.arange(-5, 15, 1)
# Y = np.arange(-10, 10, 0.25)
# X2 = np.arange(-10, 15, 1)
X2 = np.arange(-5, 10, 1)
X1, X2 = np.meshgrid(X1, X2)
# Z = 0 * np.ones((25, 30))
# print(list(Z))
# 預期數據(原始預期輸出值)
T = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 5., 5., 5., 5., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 5., 5., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 5., 5., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 5.,
5., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 5., 5., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 5., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.]])
# 對數據歸一化
T_normalized = T / 5
# 【構建神經網絡】
# 初始化神經網絡參數(用正態分佈隨機數)
# w2 = np.random.randn(2, 4)
# b2 = np.random.randn(4)
# w3 = np.random.randn(4)
# b3 = np.random.randn(1)
w2 = np.array([[-1.505, -3.632, 0.371, -0.143], [0.059, 6.991, 1.435, -5.638]])
b2 = np.array([16.158, -1.75, 0.442, -2.712])
w3 = np.array([7.504, -9.317, 0.417, -8.363])
b3 = np.array([-3.698])
# 利用誤差反向傳播法求解各梯度分量
# 學習率
learning_rate = 0.01
# 創建預測值變量
T_normalized_Predict = None
# 創建實時繪製損失值的橫縱軸變量
iter_list = []
neural_network_error_list = []
# 創建繪製實時損失的動態窗口
plt.ion()
# 計算z2(首次)
z2_1 = w2[0, 0] * X1 + w2[1, 0] * X2 + b2[0]
z2_2 = w2[0, 1] * X1 + w2[1, 1] * X2 + b2[1]
z2_3 = w2[0, 2] * X1 + w2[1, 2] * X2 + b2[2]
z2_4 = w2[0, 3] * X1 + w2[1, 3] * X2 + b2[3]
# print(z2_1.shape) # (25, 30)
# print(np.around(z2_1, decimals=3))
# 計算a2(首次)
a2_1 = sigmoid(z2_1)
a2_2 = sigmoid(z2_2)
a2_3 = sigmoid(z2_3)
a2_4 = sigmoid(z2_4)
# print(a2_1.shape) # (25, 30)
# 計算z3(首次)
z3_1 = w3[0] * a2_1 + w3[1] * a2_2 + w3[2] * a2_3 + w3[3] * a2_4 + b3
# print(z3_1.shape) # (25, 30)
# 計算a3(首次)
a3_1 = sigmoid(z3_1)
# print(a3_1.shape) # (25, 30)
# 構建神經單元誤差關係式
# 創建計算循環(訓練次數)
for i in range(100000):
# 使用誤差反向傳播法計算神經單元損失(Neural unit error —— nue)
nue3_1 = (a3_1 - T_normalized) * sigmoid_derivative(z3_1)
nue2_1 = nue3_1 * w3[0] * sigmoid_derivative(z2_1)
nue2_2 = nue3_1 * w3[1] * sigmoid_derivative(z2_2)
nue2_3 = nue3_1 * w3[2] * sigmoid_derivative(z2_3)
nue2_4 = nue3_1 * w3[3] * sigmoid_derivative(z2_4)
# print(nue3_1.shape) # (25, 30)
# print(nue2_1.shape) # (25, 30)
# 計算各權重和偏置參數的梯度
gradientCt_w2_1to1 = np.sum(nue2_1 * X1)
gradientCt_w2_1to2 = np.sum(nue2_2 * X1)
gradientCt_w2_1to3 = np.sum(nue2_3 * X1)
gradientCt_w2_1to4 = np.sum(nue2_4 * X1)
gradientCt_w2_2to1 = np.sum(nue2_1 * X2)
gradientCt_w2_2to2 = np.sum(nue2_2 * X2)
gradientCt_w2_2to3 = np.sum(nue2_3 * X2)
gradientCt_w2_2to4 = np.sum(nue2_4 * X2)
# print(gradientC_w2_1to1.shape) # (25, 30)
gradientCt_b2_1 = np.sum(nue2_1)
gradientCt_b2_2 = np.sum(nue2_2)
gradientCt_b2_3 = np.sum(nue2_3)
gradientCt_b2_4 = np.sum(nue2_4)
# print(gradientC_b2_1.shape) # (25, 30)
gradientCt_w3_1to1 = np.sum(nue3_1 * a2_1)
gradientCt_w3_2to1 = np.sum(nue3_1 * a2_2)
gradientCt_w3_3to1 = np.sum(nue3_1 * a2_3)
gradientCt_w3_4to1 = np.sum(nue3_1 * a2_4)
# print(gradientC_w3_1to1.shape) # (25, 30)
gradientCt_b3_1 = np.sum(nue3_1)
# 更新各權重和偏置參數
w2 += np.array([[gradientCt_w2_1to1, gradientCt_w2_1to2, gradientCt_w2_1to3, gradientCt_w2_1to4],
[gradientCt_w2_2to1, gradientCt_w2_2to2, gradientCt_w2_2to3, gradientCt_w2_2to4]]) * -learning_rate
b2 += np.array([gradientCt_b2_1, gradientCt_b2_2, gradientCt_b2_3, gradientCt_b2_4]) * -learning_rate
w3 += np.array([gradientCt_w3_1to1, gradientCt_w3_2to1, gradientCt_w3_3to1, gradientCt_w3_4to1]) * -learning_rate
b3 += np.array([gradientCt_b3_1]) * -learning_rate
# 計算z2
z2_1 = w2[0, 0] * X1 + w2[1, 0] * X2 + b2[0]
z2_2 = w2[0, 1] * X1 + w2[1, 1] * X2 + b2[1]
z2_3 = w2[0, 2] * X1 + w2[1, 2] * X2 + b2[2]
z2_4 = w2[0, 3] * X1 + w2[1, 3] * X2 + b2[3]
# print(z2_1.shape) # (25, 30)
# print(np.around(z2_1, decimals=3))
# 計算a2
a2_1 = sigmoid(z2_1)
a2_2 = sigmoid(z2_2)
a2_3 = sigmoid(z2_3)
a2_4 = sigmoid(z2_4)
# print(a2_1.shape) # (25, 30)
# 計算z3
z3_1 = w3[0] * a2_1 + w3[1] * a2_2 + w3[2] * a2_3 + w3[3] * a2_4 + b3
# print(z3_1.shape) # (25, 30)
# 計算a3
a3_1 = sigmoid(z3_1)
# print(a3_1.shape) # (25, 30)
T_normalized_Predict = a3_1
# 打印參數
print('第{:0>2d}輪'.format(i + 1))
print('w2={}'.format(np.around(w2, decimals=3)))
print('b2={}'.format(np.around(b2, decimals=3)))
print('w3={}'.format(np.around(w3, decimals=3)))
print('b3={}'.format(np.around(b3, decimals=3)))
# 計算損失C
# C = np.sum(1 / 2 * np.power(T_Predict - T, 2))
C = np.around(np.sum(1 / 2 * np.power(T_normalized_Predict - T_normalized, 2)), decimals=6)
print('損失總和C:{} 學習率learning rate:{} 訓練次數:{}'.format(C, learning_rate, i + 1))
# 實時繪製損失值圖表
iter_list.append(i)
neural_network_error_list.append(C)
plt.clf() # 清除之前畫的圖
plt.plot(iter_list, neural_network_error_list * np.array([-1])) # 畫出當前iter_list列表和neural_network_error_list列表中的值的圖形
plt.pause(0.001) # 暫停一段時間,不然畫的太快會卡住顯示不出來
plt.ioff() # 關閉畫圖窗口
# 繪製三維圖
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X1, X2, T_normalized_Predict * 5, cmap='rainbow')
plt.show()