【问题标题】:How do neural networks learn functions instead of memorize them?神经网络如何学习函数而不是记忆函数?
【发布时间】:2018-05-11 05:56:26
【问题描述】:

对于一个课堂项目,我设计了一个神经网络来逼近 sin(x),但最终得到的 NN 只是通过我给它的数据点记住了我的函数。我的神经网络以 200 的批大小接收 x 值。每个 x 值乘以 200 个不同的权重,映射到我的第一层中的 200 个不同的神经元。我的第一个隐藏层包含 200 个神经元,每个神经元都是批次中 x 值的线性组合。我的第二个隐藏层也包含 200 个神经元,我的损失函数是在我的第二层中的 200 个神经元和输入映射到的 200 个 sin(x) 值之间计算的。

问题是,我的神经网络完美地“近似”了 sin(x),损失为 0,但我知道它不会推广到其他数据点。

我在设计这个神经网络时做错了什么,如何避免记忆,而是设计我的神经网络来“学习”我的数据中的模式?

【问题讨论】:

    标签: machine-learning neural-network artificial-intelligence


    【解决方案1】:

    任何机器学习算法都一样。您有一个数据集,您尝试根据该数据集学习“函数”f(x),它实际上生成了数据。在现实生活中的数据集中,不可能从数据中得到原始函数,因此我们使用 g(x) 来近似它。

    任何机器学习算法的主要目标是使用函数g(x) 尽可能最好地预测unseen数据。

    给定一个数据集D,您始终可以训练一个模型,该模型将完美地分类所有数据点(您可以使用哈希图在训练集上获得 0 错误),但这会过度拟合或记忆。

    为避免此类事情,您自己必须确保模型不会记忆并学习功能。有几件事可以做。我正在尝试以一种非正式的方式(带有链接)将它们写下来。

    训练、验证、测试

    如果您有足够大的数据集,请使用训练、验证、测试拆分。将数据集分成三个部分。通常,培训、验证和测试分别占 60%、20% 和 20%。 (这些数字可能会根据需要而变化,同样在数据不平衡的情况下,请检查如何获取 stratified partitions,它会在每次拆分中保留类比率)。接下来,忘记测试分区,将其保存在安全的地方,不要触摸它。您的模型将使用 Training 分区进行训练。训练模型后,使用验证集评估模型的性能。然后为您的模型选择另一组超参数配置(例如隐藏层数、学习算法、其他参数等),然后再次训练模型,并基于验证集进行评估。继续为几个这样的模型这样做。然后选择获得最佳验证分数的模型。

    这里验证集的作用是检查模型学到了什么。如果模型有过拟合,那么验证分数会很差,因此在上述过程中你会丢弃那些过拟合的模型。但请记住,虽然您没有直接使用验证集来训练模型,而是间接使用验证集来选择模型。

    一旦您根据验证集选择了最终模型。现在拿出你的测试集,就好像你刚刚从现实生活中得到了新的数据集,这是没人见过的。该测试集上模型的预测将表明您的模型“学习”得有多好,因为它现在正试图预测它从未见过(直接或间接)的数据点。

    返回并根据测试分数调整模型是关键。这是因为一旦你这样做了,测试集就会开始为你的模式做出贡献。

    交叉验证和引导抽样

    另一方面,如果您的数据集很小。您可以使用bootstrap samplingk-fold cross-validation。这些想法是相似的。例如,对于 k 折交叉验证,如果 k=5,那么您将数据集拆分为 5 部分(还要注意分层抽样)。让我们将这些部分命名为a,b,c,d,e。仅使用分区[a,b,c,d] 训练并获得[e] 的预测分数。接下来,使用分区 [a,b,c,e] 并仅使用 [d] 上的预测分数,并继续 5 次,每次单独保留一个分区并与其他 4 个分区一起训练模型。之后,取这些的平均值分数。这表明您的模型在看到新数据时可能会执行。多次执行此操作并执行平均也是一个好习惯。例如,对于较小的数据集,执行 10 次 10 倍交叉验证,这将给出一个相当稳定的分数(取决于数据集),这将表明预测性能。

    Bootstrap 采样类似,但您需要从数据集中对相同数量的数据点(取决于)进行替换并使用该样本进行训练。这组将重复一些数据点(因为它是一个替换样本)。然后使用训练数据集中缺失的数据点来评估模型。多次执行此操作并平均性能。

    其他

    其他方法是在分类器成本函数本身中加入正则化技术。例如,在Support Vector Machines, the cost function 中,强制执行条件使得决策边界保持“边距”或两个类区域之间的差距。在neural networks one can also do similar things 中(虽然和SVM中的不一样)。

    在神经网络中,您可以使用early stopping 来停止训练。它的作用是在训练数据集上进行训练,但在每个时期,它都会评估验证数据集上的性能。如果模型从特定时期开始过拟合,那么训练数据集的误差会继续减少,但验证数据集的误差会开始增加,表明您的模型过度拟合。基于这一点可以停止训练。

    来自现实世界的大型数据集往往不会过度拟合(需要引用)。此外,如果您的模型中有太多参数(对于许多隐藏单元和层),并且如果模型不必要地复杂,它往往会过拟合。参数较小的模型永远不会过拟合(但如果参数太低,可能会欠拟合)。

    对于sin 函数任务,神经网络必须过拟合,因为它是...sin 函数。这些测试确实有助于调试和试验您的代码。

    另一个重要注意事项,如果您尝试对sin 函数数据集生成的数据进行训练、验证、测试或 k 折交叉验证,那么以“通常”的方式将其拆分 不会 在这种情况下我们正在处理时间序列,对于这些情况,可以使用技术mentioned here

    【讨论】:

      【解决方案2】:

      首先,我认为近似 sin(x) 是一个很棒的项目。如果您可以分享 sn-p 或一些其他详细信息,那就太好了,这样我们就可以查明确切的问题。 但是,我认为问题在于您过度拟合了数据,因此您无法很好地泛化到其他数据点。

      一些可能有效的技巧,

      1. 获得更多训练点
      2. 进行正则化
      3. 添加一个测试集,以便您知道自己是否过拟合。

      请记住,0 损失或 100% 准确率在训练集上大多不好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-11
        • 2017-02-28
        • 1970-01-01
        • 2019-03-15
        • 2011-08-17
        • 2020-10-29
        • 2018-03-14
        相关资源
        最近更新 更多