当前位置: 首页 > 知识库问答 >
问题:

我的反向传播算法实现有什么问题?

欧阳成弘
2023-03-14

我试图实现一个无隐层神经网络来破解MNIST数据集。

我使用sigmoid作为激活函数,交叉熵作为损失函数。

为了简单起见,我的网络没有隐藏层,只有输入和输出。

X = trainImage
label = trainLabel

w1 = np.random.normal(np.zeros([28 * 28, 10]))
b1 = np.random.normal(np.zeros([10]))

def sigm(x):
    return 1 / (1 + np.exp(-x))

def acc():
    y = sigm(np.matmul(X, w1))
    return sum(np.argmax(label, 1) == np.argmax(y, 1)) / y.shape[0]

def loss():
    y = sigm(np.matmul(X, w1))
    return sum((-label * np.log(y)).flatten())

a = np.matmul(X[0:1], w1)

y = sigm(a)

dy = - label[0:1] / y

ds = dy * y * (1 - y)

dw = np.matmul(X[0:1].transpose(), ds)

db = ds

def bp(lr, i):
    global w1, b1, a, y, dy, ds, dw, db
    a = np.matmul(X[i:i+1], w1)
    y = sigm(a)
    dy = - label[0:1] / y
    ds = dy * y * (1 - y)
    dw = np.matmul(X[i:i+1].transpose(), ds)
    db = ds
    w1 = w1 - lr * dw
    b1 = b1 - lr * db

for i in range(100 * 60000):
    bp(1, i % 60000)
    if i % 60000 == 0:
        print("#", int(i / 60000), "loss:", loss(), "acc:", acc())

这是我实现反向传播算法的一部分,但它没有按预期工作。损失函数的下降速度非常慢(我尝试了学习率从0.001到1的变化),准确度永远不会超过0.1。

输出如下:

# 0 loss: 279788.368245 acc: 0.0903333333333
# 1 loss: 279788.355211 acc: 0.09035
# 2 loss: 279788.350629 acc: 0.09035
# 3 loss: 279788.348228 acc: 0.09035
# 4 loss: 279788.346736 acc: 0.09035
# 5 loss: 279788.345715 acc: 0.09035
# 6 loss: 279788.344969 acc: 0.09035
# 7 loss: 279788.3444 acc: 0.09035
# 8 loss: 279788.343951 acc: 0.09035
# 9 loss: 279788.343587 acc: 0.09035
# 10 loss: 279788.343286 acc: 0.09035
# 11 loss: 279788.343033 acc: 0.09035

共有1个答案

朱兴运
2023-03-14

从我在这里看到的情况来看,有一些可能的因素阻碍了这一点的发挥。

首先,您必须随机初始化您的权重和偏差。据我所知,您正在尝试更改一个还没有有形值的值(例如:w1=0)。

其次,您的优化器不适合MNIST数据集。优化器是基于反向传播更改值的工具,因此选择正确的优化器非常重要。梯度下降更适合这个数据集,从我所看到的,您没有使用梯度下降。如果你试图用你的代码做一个梯度下降优化器,你很可能做错了。梯度下降涉及SSE(平方误差和)的偏导数,我在这段代码中没有看到。

如果您想使用梯度下降优化器,除了实现梯度下降背后的数学,您还必须对代码进行一些更改。您必须使用ReLU激活函数(我建议您无论如何都这样做),而不是sigmoid函数。这将确保不会出现消失梯度问题。此外,你应该使损失函数成为交叉熵的约化平均值。这样优化器将更加有效。

希望这有帮助。

 类似资料:
  • 我正在学习如何编写神经网络,目前我正在研究一种具有一个输入层、一个隐藏层和一个输出层的反向传播算法。算法正在运行,当我抛出一些测试数据时 在我的算法中,使用3个隐藏单元的默认值和10e-4的默认学习率, 我得到了很好的结果: 每次平方误差之和都会像我预期的那样下降一个十进制。然而,当我使用这样的测试数据时 没有什么真正的改变。我检查了我的隐藏单位、梯度和权重矩阵,它们都不同,梯度确实在缩小,就像我

  • 前面几节里我们使用了小批量随机梯度下降的优化算法来训练模型。在实现中,我们只提供了模型的正向传播(forward propagation)的计算,即对输入计算模型输出,然后通过autograd模块来调用系统自动生成的backward函数计算梯度。基于反向传播(back-propagation)算法的自动求梯度极大简化了深度学习模型训练算法的实现。本节我们将使用数学和计算图(computationa

  • 随时间反向传播(BPTT)算法 $$s_t = \tanh (Ux_t+Ws_{t-1})$$ $$\hat y_t=softmax(Vs_t)$$ RNN的损失函数定义为交叉熵损失: $$E_t(y_t,\hat y_t)=-y_t\log\hat y_t $$ $$E(y,\hat y)=\sum_{t}E_t(y_t, \hat y_t)=-\sum_{t}y_t\log\hat y_t$$

  • 我理解反向传播算法有困难。我读了很多书,搜索了很多东西,但我不明白为什么我的神经网络不能工作。我想确认我做的每一部分都是正确的。 下面是我的神经网络,当它初始化时,当第一行输入[1,1]和输出[0]被设置时(如你所见,我正在尝试做异或神经网络): 我有3层:输入,隐藏和输出。第一层(输入层)和隐藏层包含2个神经元,每个神经元有2个突触。最后一层(输出)包含一个有2个突触的神经元。 一个突触包含一个

  • 在RNN模型里,我们讲到了RNN具有如下的结构,每个序列索引位置t都有一个隐藏状态h^{(t)}。 如果我们略去每层都有的$$o{(t)}, L{(t)}, y^{(t)}$$,则RNN的模型可以简化成如下图的形式: 图中可以很清晰看出在隐藏状态$$h{(t)}$$由$$x{(t)}$$和$$h{(t-1)}$$得到。得到$$h{(t)}$$后一方面用于当前层的模型损失计算,另一方面用于计算下一层

  • 我以这里的代码为例,为神经网络编写了以下反向传播例程。我面临的问题让我感到困惑,并将我的调试技能推向了极限。 我面临的问题相当简单:随着神经网络的训练,它的权重被训练为零,而准确性没有提高。 我已多次尝试修复它,并验证: 训练集正确 一些信息: 训练输入是表示强度的[0,16)值的8x8网格;此网格表示数字数字(转换为列向量) 目标向量是正确数字对应位置为1的输出 原始权重和偏差由高斯分布分配 激