为什么梯度下降法不正常工作?

这是我第一次尝试在Python中编码一个多层神经网络(代码附在下面)。我在尝试使用梯度下降的偏导数时遇到了困难,因为似乎权重没有被正确更新。当我尝试预测一个新样本的输出时,我总是得到错误的答案(应该有两个输出值和与它们相关的概率;例如:如果一个新样本属于类别1,其概率应该大于0.5(prob_class1),因此类别2的概率为(1-prob_class1),但代码对于任何样本都只输出[1,1]或[-1,-1])。我已经仔细检查了所有代码行,我几乎可以肯定这是由于使用梯度下降时的一些问题引起的。请问有人能帮我吗?提前感谢您。

import numpy as npimport sklearn from sklearn.linear_model import LogisticRegressionCVfrom sklearn.datasets import make_moonsimport matplotlib.pyplot as pltnp.random.seed(0)x, y = sklearn.datasets.make_moons(200, noise=0.20)plt.scatter(x[:,0], x[:,1], s=40, c=y, cmap=plt.cm.Spectral)y = y.reshape(-1,1)N = x.shape[0]n_input = min(x.shape)n_output = 2n_hidden = max(n_input,n_output) + 20 # 20 is arbitraryn_it = 10000 alpha = 0.01def predict(model,xn):    W1, b1, W2, b2, W3, b3 = model['W1'], model['b1'], model['W2'], model['b2'],model['W3'], model['b3']    z1 = W1.dot(xn) + b1    a1 = np.tanh(z1)    z2 = a1.dot(W2) + b2    a2 = np.tanh(z2)    z3 = a2.dot(W3) + b3    a3 = np.tanh(z3)    return a3model = {}W1 = np.random.randn(n_input,n_input)b1 = np.random.randn(1,n_input)W2 = np.random.randn(n_input,n_hidden)b2 = np.random.randn(1,n_hidden)W3 = np.random.randn(n_hidden,n_output)b3 = np.random.randn(1,n_output)for i in range(n_it):    # Feedforward:    z1 = x.dot(W1) + b1    a1 = np.tanh(z1)    z2 = a1.dot(W2) + b2    a2 = np.tanh(z2)    z3 = a2.dot(W3) + b3    a3 = np.tanh(z3)    # Loss function:    # f(w,b) = (y - (w*x + b)^2)    # df/dw = -2*(1/N)*x*(y - (w*x + b))    # df/db = -2*(1/N)*(y - (w*x + b))    # Backpropagation:    dW3 = -2*(1/N)*(a2.T).dot(y-a3)    db3 = -2*(1/N)*sum(y-a3)    db3 = db3.reshape(-1,1)    db3 = db3.T    dW2 = -2*(1/N)*a1.T.dot(a2)    db2 = -2*(1/N)*sum(a2)    db2 = db2.reshape(-1,1)    db2 = db2.T    dW1 = -2*(1/N)*(x.T).dot(a1)    db1 = -2*(1/N)*sum(dW1)    db1 = db1.reshape(-1,1)    db1 = db1.T    # Updating weights    W3 += alpha*dW3    b3 += alpha*db3    W2 += alpha*dW2    b2 += alpha*db2    W1 += alpha*dW1    b1 += alpha*db1model = { 'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2, 'W3':W3, 'b3':b3}test = np.array([2,0])prediction = predict(model,test)

回答:

看你的代码,我想到了几点:

首先,你没有使用链式法则来计算反向传播。如果你想对这个有直观的理解,你可以观看Andrej Karpathy的精彩课程https://www.youtube.com/watch?v=i94OvYb6noo,但网上也有很多资源。也许你可以先从一个隐藏层开始(你这里有两个),这会使事情变得更简单。

其次,你也应该在反向传播中使用tanh的导数(你在前向传播中使用了它,所以反向也应该这样做)。

最后,为什么你要有两个输出节点?在我看来,在这种情况下,output_1 = 1 – output_2。或者,如果你想分别计算两个输出,你最终需要对它们进行归一化处理,以获得属于类别1或2的概率。

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中创建了一个多类分类项目。该项目可以对…

发表回复

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