簡體   English   中英

神經網絡偏差訓練

[英]Neural network bias training

我創建了一個神經網絡並嘗試對其進行訓練,直到加入偏見,一切都很好。

根據我在訓練時收集到的信息,偏差會調整以向上或向下移動預期的輸出,權重趨向於一個有助於YHat模擬某些功能的值,因此對於兩層網絡:

output = tanh(tanh(X0W0 + b0)W1 + b1)

在實踐中,我發現W將所有權重設置為接近0,b幾乎回顯了Y的訓練后的輸出。這實質上使輸出對於訓練后的數據完全有效,但是當您提供不同種類的數據時,它將始終給出相同的輸出。

這引起了一些混亂。 我知道偏見的作用是向上或向下移動激活圖,但是當涉及訓練時,似乎使神經網絡的整個目的無關緊要。 這是我訓練方法中的代碼:

def train(self, X, Y, loss, epoch=10000):
    for i in range(epoch):
        YHat = self.forward(X)
        loss.append(sum(Y - YHat))
        err = -(Y - YHat)
        for l in self.__layers[::-1]:
            werr = np.sum(np.dot(l.localWGrad, err.T), axis=1)
            werr.shape = (l.height, 1)
            l.adjustWeights(werr)
            err = np.sum(err, axis=1)
            err.shape = (X.shape[0], 1)
            l.adjustBiases(err)
            err = np.multiply(err, l.localXGrad)

以及用於調整重量和偏差的代碼。 (注意:epsilon是我的訓練率,lambda是正則化率)

def adjustWeights(self, err):
    self.__weights = self.__weights - (err * self.__epsilon + self.__lambda * self.__weights)

def adjustBiases(self, err):
    a = np.sum(np.multiply(err, self.localPartialGrad), axis=1) * self.__epsilon
    a.shape = (err.shape[0], 1)
    self.__biases = self.__biases - a

這是我為此網絡所做的數學運算。

Z0 = X0W0 + b0
X1 = relu(Z0)

Z1 = X1W1 + b1
X2 = relu(Z1)

a = YHat-X2

#Note the second part is for regularisation
loss = ((1/2)*(a^2)) + (lambda*(1/2)*(sum(W1^2) + sum(W2^2))) 

現在衍生品

dloss/dW1 = -(YHat-X2)*relu'(X1W1 + b1)X1
dloss/dW0 = -(YHat-X2)*relu'(X1W1 + b1)W1*relu'(X0W0 + b0)X0

dloss/db1 = -(YHat-X2)*relu'(X1W1 + b1)
dloss/db0 = -(YHat-X2)*relu'(X1W1 + b1)W1*relu'(X0W0 + b0)

我猜我做錯了什么,但我不知道這是什么。 我嘗試在以下輸入上訓練此網絡

X = np.array([[0.0], [1.0], [2.0], [3.0]])
Xnorm = X / np.amax(X)

Y = np.array([[0.0], [2.0], [4.0], [6.0]])
Ynorm = Y / np.amax(Y)

我將其作為輸出:

post training:
shape:  (4, 1) 
 [[0.        ]
 [1.99799666]
 [3.99070622]
 [5.72358125]] 

Expected:
 [[0.]
 [2.]
 [4.]
 [6.]] 

在您轉發其他內容之前,這似乎很棒。

shape:  (4, 1) 
 [[2.]
 [3.]
 [4.]
 [5.]]

然后我得到:

shape:  (4, 1) 
 [[0.58289512]
 [2.59967085]
 [4.31654068]
 [5.74322541]]

Expected:
 [[4.]
 [6.]
 [8.]
 [10.]] 

我以為“這可能是我聽說過的邪惡的'過度擬合',並決定添加一些正則化,但是即使那樣也不能真正解決問題,為什么從邏輯上講它會更快,為什么呢?還有更理想的方法是將偏差設置為等於輸出並使權重為零...有人可以解釋我的想法出了什么問題嗎?

這是訓練后的網絡結構,(請注意,如果將輸出乘以訓練Y的最大值,將獲得預期的輸出:)

===========================NeuralNetwork===========================

Layers:

===============Layer  0 :===============

 Weights: (1, 3)

[[0.05539559 0.05539442 0.05539159]]

Biases: (4, 1)

[[0.        ]
 [0.22897166]
 [0.56300199]
 [1.30167665]]


==============\Layer  0 :===============


===============Layer  1 :===============

 Weights: (3, 1)

[[0.29443245]
 [0.29442639]
 [0.29440642]]

Biases: (4, 1)

[[0.        ]
 [0.13199981]
 [0.32762199]
 [1.10023446]]


==============\Layer  1 :===============


==========================\NeuralNetwork===========================

圖y = 2x在x = 0處有y截距,因此所有的偏見'為0都是有意義的,因為我們沒有上下移動圖...是嗎?

感謝您閱讀本文!

編輯:

這是損耗圖:

在此處輸入圖片說明

編輯2:

我只是嘗試使用單個權重和輸出來執行此操作,這是我得到的輸出結構:

===========================NeuralNetwork===========================

Layers:

===============Layer  0 :===============

 Weights: (1, 1)

[[0.47149317]]

Biases: (4, 1)

[[0.        ]
 [0.18813419]
 [0.48377987]
 [1.33644038]]


==============\Layer  0 :===============


==========================\NeuralNetwork===========================

對於此輸入:

shape:  (4, 1) 
 [[2.]
 [3.]
 [4.]
 [5.]]

我得到以下輸出:

shape:  (4, 1) 
 [[4.41954787]
 [5.53236625]
 [5.89599366]
 [5.99257962]]

再次應該是:

Expected:
 [[4.]
 [6.]
 [8.]
 [10.]] 

請注意,偏差仍然存在,您會認為在這種情況下權重為2,偏差為0。

將答案從OP的問題移至

原來我從來沒有正確處理過我的訓練數據。 輸入向量:

[[0.0], [1.0], [2.0], [3.0]]

歸一化后,我將此向量除以輸入中的最大值3,因此得到

[[0.0], [0.3333], [0.6666], [1.0]]

對於輸入的Y訓練向量,我有

[[0.0], [2.0], [4.0], [6.0]]

我愚蠢地決定對這個向量做同樣的事情,但是最大為Y 6:

[[0.0], [0.333], [0.666], [1.0]]

所以基本上我說的是“嘿,網絡,模仿我的輸入”。 這是我的第一個錯誤。 第二個錯誤來自對縮放的更多誤解。

盡管1是0.333,並且0.333 * 2 = 0.666,然后我乘以y的最大值(6)6 * 0.666 = 2,如果我使用另一組數據再次嘗試說:

[[2.0], [3.0], [4.0], [5.0]]

2將是2/5 = 0.4和0.4 * 2 = 0.8,乘以5將是2,但是在現實世界中,我們將無法知道5是數據集的最大輸出,因此我想也許是本來是Y訓練的最大值,所以是6,所以不是2/5 = 0.4、0.4 * 2 = 0.8 * 5,而是2/5 = 0.4、0.4 * 2 = 0.8 * 6 = 4.8。

因此,我得到了一些偏見和權重的奇怪行為。 因此,在基本擺脫了歸一化之后,我可以自由調整超參數,現在可以作為基礎訓練數據的輸出:

輸入:

X:
 [[0.]
 [1.]
 [2.]
 [3.]] 

我得到以下輸出:

shape:  (4, 1) 
 [[0.30926124]
 [2.1030826 ]
 [3.89690395]
 [5.6907253 ]]

對於額外的測試數據(未經培訓):

shape:  (4, 1) 
 [[2.]
 [3.]
 [4.]
 [5.]]

我得到以下輸出:

shape:  (4, 1) 
 [[3.89690395]
 [5.6907253 ]
 [7.48454666]
 [9.27836801]]

所以現在我很高興。 我也將激活更改為泄漏的relu,因為它應該更好地擬合線性方程式(我認為)。 我敢肯定,更多的測試數據和更多的超參數調整將是一個完美的選擇。 感謝大家的幫助。 試圖解釋我的問題確實使事情變得透視。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM