【问题标题】:How to find if a data set can train a neural network?如何判断一个数据集是否可以训练一个神经网络?
【发布时间】:2017-10-20 22:04:14
【问题描述】:

我是机器学习的新手,这是第一个在现实世界中面临挑战的 ML 任务。

一些实验数据包含512个独立的布尔特征和一个布尔结果。

提供的数据集中大约有1e6条真实实验记录。

在一个经典的 XOR 示例中,需要 4 个可能的状态中的所有 4 个来训练 NN。就我而言,它唯一的2^(10-512) = 2^-505 接近于零。

我没有关于数据性质的更多信息,只有这些(512 + 1) * 1e6 位。

在可用数据上尝试了 1 个隐藏层的 NN。即使是来自训练集的样本上经过训练的 NN 的输出也总是接近于 0,而不是接近于“1”。玩过权重初始化,梯度下降学习率。

我的code 使用 TensorFlow 1.3、Python 3。模型摘录:

with tf.name_scope("Layer1"):
    #W1 = tf.Variable(tf.random_uniform([512, innerN], minval=-2/512, maxval=2/512), name="Weights_1")
    W1 = tf.Variable(tf.zeros([512, innerN]), name="Weights_1")
    b1 = tf.Variable(tf.zeros([1]), name="Bias_1")

    Out1 = tf.sigmoid( tf.matmul(x, W1) + b1)

with tf.name_scope("Layer2"):
    W2 = tf.Variable(tf.random_uniform([innerN, 1], minval=-2/512, maxval=2/512), name="Weights_2")
    #W2 = tf.Variable(tf.zeros([innerN, 1]), name="Weights_2")
    b2 = tf.Variable(tf.zeros([1]), name="Bias_2")

    y = tf.nn.sigmoid( tf.matmul(Out1, W2) + b2)

with tf.name_scope("Training"):
    y_ = tf.placeholder(tf.float32, [None,1])

    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(
            labels = y_, logits = y)
    )

    train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)

with tf.name_scope("Testing"):
    # Test trained model
    correct_prediction = tf.equal( tf.round(y), tf.round(y_))
# ...
# Train
for step in range(500):
    batch_xs, batch_ys = Datasets.train.next_batch(300, shuffle=False)
    _, my_y, summary = sess.run([train_step, y, merged_summaries],
        feed_dict={x: batch_xs, y_: batch_ys})

我怀疑两种情况:

  1. 我的错 - NN 实现错误,架构错误;
  2. 错误数据。与 XOR 示例相比,不完整的训练数据会导致 NN 失败。但是,提供给经过训练的 NN 的训练示例应该能够给出正确的预测,不是吗?

如何评估是否有可能在提供的数据上训练神经网络(2 层感知器)来预测结果?一个可接受集合的例子是 XOR 例子。反对一些随机噪音。

【问题讨论】:

  • 我不会倾向于将神经网络用于仅包含布尔输入的数据。
  • @GordonLinoff 在这种情况下有什么更好的方法?
  • 我会从决策树开始,然后快速切换到随机森林。根据数据的性质,您可能会使用 SVM(取决于数据的结构),但我认为随机森林可能会做得更好。
  • 如果数据完全没有相关性怎么办? IE。实验结果实际上是由功能集之外的其他因素引起的?
  • 我同意 Gordon 的评论,但是,我认为您也可以从头开始使用 xgboost 以节省您的时间

标签: machine-learning tensorflow neural-network


【解决方案1】:

只有特殊的方法可以知道是否可以从数据集中学习具有可微分网络的函数。也就是说,这些临时方法通常确实有效。例如,网络应该能够在没有任何正则化的情况下过度拟合训练集。

衡量这一点的常用技术是仅将网络拟合到完整数据集的子集上。检查网络是否可以过拟合,然后增加子集的大小,并增加网络的大小。不幸的是,决定是添加额外层还是在隐藏层中添加更多单元是您必须做出的任意决定。

但是,查看您的代码,这里可能会出现一些问题:

  1. 您的输出是否平衡?我的意思是,在数据集目标中,1 和 0 的数量是否相同?
  2. 您在第一层的初始化全为零,到此的梯度将为零,因此它无法学习任何东西(尽管您在上面注释掉了一个真正的初始化)。
  3. Sigmoid 非线性比 ReLU 等更简单的非线性更难优化。

我建议在 Tensorflow 中使用 built-in definitions for layers 以不必担心初始化,并在任何隐藏层中切换到 ReLU(您的布尔目标的输出需要 sigmoid)。

最后,深度学习实际上并不能很好地解决大多数“特征包”机器学习问题,因为它们缺乏结构。例如,特征的顺序无关紧要。其他方法通常效果更好,但如果您真的想使用深度学习,那么您可以查看this recent paper,通过使用非常具体的非线性和权重初始化(在上面的代码中更改 4 行)显示改进的性能。

【讨论】:

  • 1.输出是平衡的,经过验证。 2.确定我也尝试过随机正常初始化;现在尝试随机森林方法,需要很长时间。等待第一个结果,此时 CPU 已 100% 加载且风扇在大声旋转。
  • 您可能想尝试朴素贝叶斯,因为您有布尔输入和目标。它将比随机森林运行得更快 (closed form and linear time),并且在条件独立假设下是最优的。
  • 再次感谢!在 CPU 加热约 1 小时后,随机森林最终给出了可怜的 0.5239 准确度。 Tried the Naive Bayes 也是如此,它产生了 0.47 的准确度。要么我做错了,要么数据不适合 ML 算法..
  • 这很奇怪,如果你的类是平衡的,那么你只需要一直猜测一个类就可以得到 0.5 的准确率,所以肯定有问题。这是训练数据的准确性,还是验证数据的准确性?
  • 我得到了 600 000 个样本数据集。随机森林 0.52 的准确度来自训练集的样本。使用所有 6e5 个样本进行训练,首先使用 6e4 个样本进行验证。朴素贝叶斯 0.47 – 验证 100 个样本,与 599900 个训练样本分开。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2017-07-22
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多