具有partial_fit()的MLP比监督分类中的fit()表现更差

时间:2017-12-06 01:33:10

标签: machine-learning scikit-learn neural-network classification gradient-descent

我正在使用的学习数据集是flatten的灰度图像,每个像素代表一个单独的样本。在训练前一个Multilayer perceptronMLP)分类器后,第二个图像将按像素逐个分类。

我遇到的问题是MLP在接收训练数据集时(fit())与通过块(partial_fit())训练时相比表现更好。在这两种情况下,我都保留Scikit-learn提供的默认参数。

我问这个问题是因为当训练数据集大约有数百万个样本时,我将不得不使用partial_fit()来训练MLP块。

def batcherator(data, target, chunksize):
    for i in range(0, len(data), chunksize):
        yield data[i:i+chunksize], target[i:i+chunksize]

def classify():
    classifier = MLPClassifier(verbose=True)

    # classifier.fit(training_data, training_target)

    gen = batcherator(training.data, training.target, 1000)
    for chunk_data, chunk_target in gen:
        classifier.partial_fit(chunk_data, chunk_target,
                               classes=np.array([0, 1]))

    predictions = classifier.predict(test_data)

我的问题是,我应该在MLP分类器中调整哪些参数,以便在数据块训练时使其结果更可接受?

我尝试使用hidden_layer_sizes增加隐藏层中的神经元数量,但我没有看到任何改进。如果我使用relu参数将隐藏图层的激活功能从默认logistic更改为activation,则无法改善。

下面是我正在处理的图片(所有图片都是512x512图片),其中包含指向Google Fusion表格的链接,其中CSVnumpy导出数组(将图像保留为float而不是int):

Training_data:

白色区域被掩盖:Google Fusion Table (training_data)

Class0:

enter image description here

的Class1:

enter image description here

Training_target:

Google Fusion Table (training_target)

TEST_DATA:

enter image description here

Google Fusion Table (test_data)

预测(使用partial_fit):

enter image description here

Google Fusion Table (predictions)

2 个答案:

答案 0 :(得分:2)

TL,DR:以较小的学习率和不同的观察顺序对您的数据进行多次循环,并且partial_fit的效果与fit一样好。

partial_fit有很多块的问题是,当你的模型完成最后一个块时,它可能会忘记第一个块。这意味着,由于早期批次而导致的模型权重变化将被后期批次完全覆盖。

然而,这个问题可以通过以下方式轻松解决:

  1. 学习率低。如果模型慢慢学习,那么它也会慢慢忘记,并且早期批次不会被后期批次覆盖。 MLPClassifier中的默认学习率为0.001,但您可以将其更改为3或10的倍数,看看会发生什么。
  2. 多个纪元。如果学习速度很慢,则所有训练样本上的一个循环可能不足以使模型收敛。因此,您可以对训练数据进行多次循环,结果很可能会得到改善。直观的策略是通过降低学习率的相同因素来增加循环次数。
  3. 改组观察。如果狗的图像在您的数据中出现在猫的图像之前,那么最终模型将记住关于猫的更多信息而不是狗。但是,如果您在批处理生成器中以某种方式对观察点进行洗牌,则不会出现问题。最安全的策略是在每个时代之前重新重新调整数据。

答案 1 :(得分:0)

您可以使用adaptive提供的sklearn学习费率功能,而不是手动提供费率。

model = SGDClassifier(loss="hinge", penalty="l2", alpha=0.0001, max_iter=3000, tol=None, shuffle=True, verbose=0, learning_rate='adaptive', eta0=0.01, early_stopping=False)

这在[scikit docs]中描述为:

“自适应”:eta = eta0,只要训练持续减少即可。每次n_iter_no_change个连续的纪元未能将训练损失减少一倍,或者如果Early_stopping为True,则未能增加鉴定分数一次,则当前学习率除以5。