MLP с частичной_прибором () работает хуже, чем с подгонкой () в контролируемой классификации

Набор данных обучения, который я использую, представляет собой изображение в градациях серого, которое было flatten чтобы каждый пиксель представлял отдельный образец. Второе изображение будет классифицировано попиксельно после тренировки Multilayer perceptron (MLP) классификатор по прежнему.

У меня проблема в том, что 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 таблица, куда они были экспортированы как CSV от numpy массивы (чтобы оставить изображение как float вместо int):

Training_data:

Белые области маскируются: Google Fusion Table (training_data)

class0:

Class1:

Training_target:

Google Fusion Table (training_target)

Test_data:

Google Fusion Table (test_data)

Прогноз (с частичным соответствием):

Google Fusion Table (прогнозы)

1 ответ

Решение

TL,DR: сделайте несколько циклов над вашими данными с небольшой скоростью обучения и разным порядком наблюдений, и ваши partial_fit будет работать так же хорошо, как fit,

Проблема с partial_fit Что касается многих блоков, то, когда ваша модель завершает последний блок, она может забыть первый. Это означает, что изменения в весах модели из-за ранних партий будут полностью перезаписаны поздними партиями.

Эта проблема, однако, может быть решена достаточно легко с помощью комбинации:

  1. Низкая скорость обучения. Если модель учится медленно, то она также забывает медленно, и ранние партии не будут перезаписаны поздними партиями. Скорость обучения по умолчанию в MLPClassifier 0,001, но вы можете изменить его на кратные 3 или 10 и посмотреть, что произойдет.
  2. Несколько эпох. Если скорость обучения медленная, то одного цикла по всей обучающей выборке может быть недостаточно для сходимости модели. Таким образом, вы можете сделать несколько циклов по тренировочным данным, и результат, скорее всего, улучшится. Интуитивно понятная стратегия - увеличить количество циклов на тот же коэффициент, что и скорость обучения.
  3. Шаркающие наблюдения. Если изображения собак идут перед изображениями кошек в ваших данных, то в конечном итоге модель будет помнить больше о кошках, чем о собаках. Однако, если вы каким-то образом перетасуете свои наблюдения в генераторе пакетов, это не будет проблемой. Самая безопасная стратегия - перетасовывать данные заново перед каждой эпохой.

Вместо того, чтобы указывать ставку вручную, вы можете использовать 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 последовательных эпох не может уменьшить потери на обучение на tol или не может увеличить оценку валидации на tol, если Early_stopping имеет значение True, текущая скорость обучения делится на 5.

Другие вопросы по тегам