神经网络偏差训练

我创建了一个神经网络并尝试对其进行训练,一切顺利,直到我添加了偏差。

据我了解,在训练过程中,偏差会调整以使预期输出向上或向下移动,而权重则倾向于一个有助于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 + b0X1 = relu(Z0)Z1 = X1W1 + b1X2 = relu(Z1)a = YHat-X2#注意第二部分用于正则化loss = ((1/2)*(a^2)) + (lambda*(1/2)*(sum(W1^2) + sum(W2^2))) 

现在是导数

dloss/dW1 = -(YHat-X2)*relu'(X1W1 + b1)X1dloss/dW0 = -(YHat-X2)*relu'(X1W1 + b1)W1*relu'(X0W0 + b0)X0dloss/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)

我得到的输出是:

训练后:shape:  (4, 1)  [[0.        ] [1.99799666] [3.99070622] [5.72358125]] 预期: [[0.] [2.] [4.] [6.]] 

看起来很棒…直到你输入其他数据:

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

然后我得到:

shape:  (4, 1)  [[0.58289512] [2.59967085] [4.31654068] [5.74322541]]预期: [[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,因为我们没有将图向上或向下移动…对吗?

谢谢你读到这里!

编辑:

这是损失图:

enter image description here

编辑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]]

而它应该为:

预期: [[4.] [6.] [8.] [10.]] 

注意偏差的问题仍然存在,你会认为在这种情况下权重应该是2,偏差应该是0。


回答:

从原始问题中移动的回答

原来我从未正确处理我的训练数据。输入向量:

[[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]]

所以现在我很满意。我还将我的激活函数改成了leaky relu,因为它应该更适合线性方程(我认为)。我相信通过更多的测试数据和更多的超参数调整,它会完美适应。谢谢大家的帮助。尝试解释我的问题真的让我有了新的视角。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注