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

为什么这种反向传播实现无法正确训练权重?

董庆
2023-03-14

我以这里的代码为例,为神经网络编写了以下反向传播例程。我面临的问题让我感到困惑,并将我的调试技能推向了极限。

我面临的问题相当简单:随着神经网络的训练,它的权重被训练为零,而准确性没有提高。

我已多次尝试修复它,并验证:

  • 训练集正确

一些信息:

  • 训练输入是表示强度的[0,16)值的8x8网格;此网格表示数字数字(转换为列向量)
  • 目标向量是正确数字对应位置为1的输出
  • 原始权重和偏差由高斯分布分配
  • 激活是标准的乙状结肠

我不知道接下来该怎么办。我已经验证了我知道要检查的所有东西都正常运行,但仍然不起作用,所以我在这里询问。以下是我用来反向传播的代码:

def backprop(train_set, wts, bias, eta):
    learning_coef = eta / len(train_set[0])

    for next_set in train_set:
        # These record the sum of the cost gradients in the batch
        sum_del_w = [np.zeros(w.shape) for w in wts]
        sum_del_b = [np.zeros(b.shape) for b in bias]

        for test, sol in next_set:
            del_w = [np.zeros(wt.shape) for wt in wts]
            del_b = [np.zeros(bt.shape) for bt in bias]
            # These two helper functions take training set data and make them useful
            next_input = conv_to_col(test)
            outp = create_tgt_vec(sol)

            # Feedforward step
            pre_sig = []; post_sig = []
            for w, b in zip(wts, bias):
                next_input = np.dot(w, next_input) + b
                pre_sig.append(next_input)
                post_sig.append(sigmoid(next_input))
                next_input = sigmoid(next_input)

            # Backpropagation gradient
            delta = cost_deriv(post_sig[-1], outp) * sigmoid_deriv(pre_sig[-1])
            del_b[-1] = delta
            del_w[-1] = np.dot(delta, post_sig[-2].transpose())

            for i in range(2, len(wts)):
                pre_sig_vec = pre_sig[-i]
                sig_deriv = sigmoid_deriv(pre_sig_vec)
                delta = np.dot(wts[-i+1].transpose(), delta) * sig_deriv
                del_b[-i] = delta
                del_w[-i] = np.dot(delta, post_sig[-i-1].transpose())

            sum_del_w = [dw + sdw for dw, sdw in zip(del_w, sum_del_w)]
            sum_del_b = [db + sdb for db, sdb in zip(del_b, sum_del_b)]

        # Modify weights based on current batch            
        wts = [wt - learning_coef * dw for wt, dw in zip(wts, sum_del_w)]
        bias = [bt - learning_coef * db for bt, db in zip(bias, sum_del_b)]

    return wts, bias

根据Shep的建议,我检查了在训练一个形状为2,1,1的网络始终输出1时发生的情况,事实上,在这种情况下,网络训练是正确的。我在这一点上的最佳猜测是,梯度在0时调整得太强,而在1时调整得太弱,导致净下降,尽管每一步都有所增加,但我不确定。

共有1个答案

沈琛
2023-03-14

我想你的问题在于初始权重的选择和权重算法初始化的选择。Encog的作者Jeff Heaton声称,它通常比其他初始化方法的性能更差。下面是权重初始化算法性能的另一个结果。根据我自己的经验,建议您使用不同的符号值初始化权重。即使在所有正输出的情况下,具有不同符号的权重也比具有相同符号的权重表现得更好。

 类似资料:
  • 我试图实现一个无隐层神经网络来破解MNIST数据集。 我使用sigmoid作为激活函数,交叉熵作为损失函数。 为了简单起见,我的网络没有隐藏层,只有输入和输出。 这是我实现反向传播算法的一部分,但它没有按预期工作。损失函数的下降速度非常慢(我尝试了学习率从0.001到1的变化),准确度永远不会超过0.1。 输出如下:

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

  • 卷积神经网络其实是神经网络特征学习的一个典型例子。传统的机器学习算法其实需要人工的提取特征,比如很厉害的SVM。而卷积神经网络利用模板算子的参数也用以学习这个特点,把特征也学习出来了。其实不同的模板算子本质上就是抽象了图像的不同方面的特征。比如提取边缘,提取梯度的算子。用很多卷积核去提取,那就是 提取了很多的特征。一旦把参数w,b训练出来,意味着特征和目标之间的函数就被确定。今天分享下CNN的关键

  • 训练发散 理想的分类器应当是除了真实标签的概率为1,其余标签概率均为 0,这样计算得到其损失函数为 -ln(1) = 0 损失函数越大,说明该分类器在真实标签上分类概率越小,性能也就越差。一个非常差的分类器,可能在真实标签上的匪类概率接近于0,那么损失函数就接近于正无穷,我们成为训练发散,需要调小学习速率。 6.9 高原反应 在 ImageNet-1000 分类问题中,初始状态为均匀分布,每个类别

  • 问题内容: 对于我的大学项目,我正在创建一个神经网络,可以对信用卡交易是否欺诈的可能性进行分类。我正在用反向传播训练。我用Java编写。我想应用多线程,因为我的计算机是四核i7。花费几个小时进行培训并看到我的大多数核心处于闲置状态,这使我感到烦恼。 但是如何将多线程应用于反向传播?Backprop的工作原理是通过网络向后调整错误。必须先完成一层,然后才能继续进行。有什么方法可以修改程序以执行多核背

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