Миграция с нейронных сетей

Леса решений TensorFlow ( TF-DF ) — это набор алгоритмов леса решений ( DF ), доступных в TensorFlow. Леса решений работают иначе, чем нейронные сети ( NN ): DF обычно не обучаются с помощью обратного распространения ошибки или мини-пакетами. Таким образом, конвейеры TF-DF имеют несколько отличий от других конвейеров TensorFlow.

Этот документ представляет собой список этих различий и руководство по обновлению конвейеров TF для использования TF-DF.

Этот документ предполагает знакомство с начинающим колабом .

Набор данных и функции

Набор данных проверки

В отличие от стандартной парадигмы обучения нейронной сети, модели TF-DF не нуждаются в наборе проверочных данных для мониторинга переобучения или досрочного прекращения обучения. Если у вас уже есть разделение обучение/проверка/тест, и вы используете проверку по одной из этих причин, можно безопасно обучать ваш TF-DF на обучении+проверке (если только разделение проверки не используется для чего-то еще, например настройка гиперпараметра).

- model.fit(train_ds, validation_data=val_ds)
+ model.fit(train_ds.concatenate(val_ds))

# Or just don't create a validation dataset

Обоснование: Структура TF-DF состоит из нескольких алгоритмов. Некоторые из них не используют набор данных проверки (например, случайный лес), а некоторые используют (например, деревья с градиентным усилением). Алгоритмы, которые это делают, могут выиграть от использования разных типов и размеров наборов проверочных данных. Поэтому, если необходим набор проверочных данных, он будет автоматически извлечен из набора обучающих данных.

Ввод-вывод набора данных

Тренироваться ровно 1 эпоху

# Number of epochs in Keras
- model.fit(train_ds, num_epochs=5)

# Number of epochs in the dataset
- train_ds = train_ds.repeat(5)
- model.fit(train_ds)
+ model.fit(train_ds)

Обоснование: пользователи нейронных сетей часто обучают модель за N шагов (что может включать в себя цикл по набору данных > 1 раза) из-за природы SGD . TF-DF тренируется, считывая весь набор данных, а затем запуская обучение в конце. Для чтения полного набора данных необходима 1 эпоха, и любые дополнительные шаги приведут к ненужному вводу-выводу данных, а также к замедлению обучения.

Не перемешивайте набор данных

Наборы данных не нужно перемешивать (если только input_fn не читает только образец набора данных).

- train_ds = train_ds.shuffle(5)
- model.fit(train_ds)
+ model.fit(train_ds)

Обоснование: TF-DF перетасовывает доступ к данным внутри после считывания полного набора данных в память. Алгоритмы TF-DF являются детерминированными (если пользователь не меняет случайное начальное число). Включение перетасовки только сделает алгоритм недетерминированным. Перетасовка имеет смысл, если входной набор данных упорядочен и input_fn будет читать только его выборку (выборка должна быть случайной). Однако это сделает процедуру обучения недетерминированной.

Не настраивайте размер партии

Размер партии не повлияет на качество модели.

- train_ds = train_ds.batch(hyper_parameter_batch_size())
- model.fit(train_ds)
# The batch size does not matter.
+ train_ds = train_ds.batch(64)
+ model.fit(train_ds)

Обоснование: поскольку TF-DF всегда обучается на полном наборе данных после его считывания, качество модели не будет зависеть от размера пакета (в отличие от алгоритмов мини-пакетного обучения, таких как SGD, где такие параметры, как скорость обучения, необходимо настраивать совместно). Таким образом, его следует удалить из разверток гиперпараметров. Размер пакета будет влиять только на скорость ввода-вывода набора данных.

Большие наборы данных

В отличие от нейронных сетей, которые могут бесконечно перебирать мини-пакеты большого набора данных, лесам решений требуется конечный набор данных, который помещается в памяти для их процедур обучения. Размер набора данных влияет на производительность и память.

Отдача от увеличения размера набора данных уменьшается, и алгоритмам DF, возможно, требуется меньше примеров для сходимости, чем большим моделям NN. Вместо масштабирования количества шагов обучения (как в нейронной сети) вы можете попробовать масштабировать объем данных, чтобы увидеть, где имеет смысл компромисс в вычислениях. Поэтому рекомендуется сначала попробовать обучение на (небольшом) подмножестве набора данных.

Альтернативное решение — использовать распределенное обучение . Распределенное обучение — отличный способ увеличить размер набора данных, если доступно несколько машин. Хотя все распределенные алгоритмы доступны для распределения вычислений, не все из них способны распределять использование оперативной памяти. Проверьте документацию для получения более подробной информации.

Сколько примеров использовать

Он должен поместиться в памяти на машине, на которой обучается модель :

  • Обратите внимание, что это не то же самое, что размер примеров на диске.

  • Как правило, одно числовое или категориальное значение использует 4 байта памяти. Таким образом, набор данных со 100 функциями и 25 миллионами примеров займет ~10 ГБ (= 100 * 25 * 10^6 * 4 байта) памяти.

  • Функции с категориальным набором (например, токенизированный текст) занимают больше памяти (4 байта на токен + 12 байтов на функцию).

Учитывайте свой бюджет времени на обучение

  • Хотя алгоритмы обучения DF обычно быстрее, чем NN для небольших наборов данных (например, <100 тыс. примеров), алгоритмы обучения DF не масштабируются линейно с размером набора данных; скорее, ~O(features x num_examples x log(num_examples)) в большинстве случаев.

  • Время обучения зависит от гиперпараметров. Наиболее влиятельными параметрами являются: (1) количество деревьев ( num_trees ), (2) примерная частота выборки ( subsample для GBT) и (3) частота выборки атрибутов ( num_candidate_attributes_ratio ).

  • Функции с категориальным набором стоят дороже, чем другие функции. Стоимость контролируется параметром categorical_set_split_greedy_sampling .

  • Разреженные наклонные объекты (по умолчанию отключены) дают хорошие результаты, но их вычисление требует больших затрат.

Практические правила масштабирования данных

Мы предлагаем начать с небольшого фрагмента данных (<10 тыс. примеров), что позволит вам обучить модель TF-DF в большинстве случаев за секунды или несколько минут. Затем вы можете увеличивать данные с фиксированной скоростью (например, на 40 % каждый раз), останавливаясь, когда производительность набора проверки не улучшается или набор данных больше не помещается в памяти.

Нормализация функций/предварительная обработка

Не преобразовывайте данные с помощью столбцов функций.

Модели TF-DF не требуют явного предоставления семантики и преобразований функций. По умолчанию все объекты в наборе данных (кроме метки) будут обнаружены и использованы моделью. Семантика функции будет определена автоматически и при необходимости может быть переопределена вручную.

# Estimator code
- feature_columns = [
-   tf.feature_column.numeric_column(feature_1),
-   tf.feature_column.categorical_column_with_vocabulary_list(feature_2, ['First', 'Second', 'Third'])
-   ]
- model = tf.estimator.LinearClassifier(feature_columns=feature_columnes)
# Use all the available features. Detect the type automatically.
+ model = tfdf.keras.GradientBoostedTreesModel()

Вы также можете указать подмножество входных объектов:

+ features = [
+   tfdf.keras.FeatureUsage(name="feature_1"),
+   tfdf.keras.FeatureUsage(name="feature_2")
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features, exclude_non_specified_features=True)

При необходимости вы можете принудительно изменить семантику функции.

+ forced_features = [
+   tfdf.keras.FeatureUsage(name="feature_1", semantic=tfdf.keras.FeatureSemantic.CATEGORICAL),
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features)

Обоснование: хотя некоторые модели (например, нейронные сети) требуют стандартизированного входного слоя (например, сопоставления различных типов объектов → внедрения), модели TF-DF могут изначально использовать категориальные и числовые функции, а также автоматически определять семантические типы функций. на основе данных.

Не выполнять предварительную обработку функций

Алгоритмы дерева решений не получают преимуществ от некоторых классических функций предварительной обработки, используемых в нейронных сетях. Ниже подробно перечислены некоторые из наиболее распространенных стратегий обработки функций, но безопасной отправной точкой является удаление всей предварительной обработки, которая была разработана для облегчения обучения нейронной сети.

Не нормализуйте числовые характеристики

- def zscore(value):
-   return (value-mean) / sd

- feature_columns = [tf.feature_column.numeric_column("feature_1",normalizer_fn=zscore)]

Рационально: алгоритмы леса решений изначально поддерживают ненормализованные числовые характеристики, поскольку алгоритмы разделения не выполняют никаких числовых преобразований входных данных. Некоторые типы нормализации (например, нормализация zscore) не способствуют численной стабильности процедуры обучения, а некоторые (например, отсечение выбросов) могут ухудшить выразительность окончательной модели.

Не кодируйте категориальные функции (например, хеширование, горячее или встраивание).

- integerized_column = tf.feature_column.categorical_column_with_hash_bucket("feature_1",hash_bucket_size=100)
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]
- integerized_column = tf.feature_column.categorical_column_with_vocabulary_list('feature_1', ['bob', 'george', 'wanda'])
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]

Обоснование: TF-DF имеет встроенную поддержку категориальных функций и будет рассматривать «преобразованный» элемент словаря как еще один элемент своего внутреннего словаря (который можно настроить с помощью гиперпараметров модели). Некоторые преобразования (например, хеширование) могут быть с потерями. Встраивания не поддерживаются, если они не прошли предварительное обучение, поскольку модели леса решений не дифференцируемы (см. промежуточный colab ). Обратите внимание, что словарные стратегии, специфичные для предметной области (например, удаление стоп-слов, нормализация текста), по-прежнему могут быть полезны.

Как обрабатывать текстовые функции

TF-DF изначально поддерживает функции категориального набора . Таким образом, пакеты токенизированных n-грамм можно использовать в исходном виде.

Альтернативно, текст также можно использовать посредством предварительно обученного внедрения .

Категориальные наборы эффективны для выборки небольших наборов данных, но их обучение на больших наборах данных является дорогостоящим. Сочетание наборов категорий и предварительно обученного внедрения часто может дать лучшие результаты, чем если бы каждый из них использовался отдельно.

Не заменяйте отсутствующие функции магическими значениями.

Обоснование: TF-DF имеет встроенную поддержку пропущенных значений. В отличие от нейронных сетей, которые могут передавать NaN градиентам, если на входе есть NaN, TF-DF будет обучаться оптимально, если алгоритм видит разницу между отсутствующим и сигнальным значением.

- feature_columns = [
- tf.feature_column.numeric_column("feature_1", default_value=0),
- tf.feature_column.numeric_column("feature_1_is_missing"),
- ]

Обработка изображений и временных рядов

В лесах решений не существует стандартного алгоритма для использования функций изображений или временных рядов, поэтому для их использования требуется дополнительная работа.

Обоснование: свертка, LSTM, внимание и другие алгоритмы обработки последовательностей представляют собой архитектуры, специфичные для нейронных сетей.

С этими функциями можно справиться, используя следующие стратегии:

  • Особенности проектирования

    • Изображения: использование изображения со случайным лесом в какой-то момент было популярно (например,

      Microsoft Kinect , но сегодня нейронные сети — это самое современное достижение.

    • Временные ряды: [ Движущаяся статистика ] может работать на удивление хорошо для данных временных рядов, имеющих относительно мало примеров (например, жизненно важные показатели в медицинской сфере).

    • Модули внедрения. Модули внедрения нейронных сетей могут предоставить богатые возможности для алгоритма леса решений. Промежуточная совместная работа показывает, как объединить встраивание tf-hub и модель TF-DF.

Обучение

Не используйте аппаратные ускорители, например графический процессор, ТПУ.

Обучение TF-DF (пока) не поддерживает аппаратные ускорители. Все обучение и вывод выполняются на ЦП (иногда с использованием SIMD).

Обратите внимание, что вывод TF-DF на ЦП (особенно при использовании библиотек Yggdrasil C++) может быть на удивление быстрым (субмикросекунды на пример на ядро ​​ЦП).

Не используйте контрольные точки или крючки в середине обучения.

TF-DF (в настоящее время) не поддерживает контрольные точки модели, а это означает, что перехватчики, ожидающие, что модель будет пригодна для использования до завершения обучения, в основном не поддерживаются. Модель будет доступна только после того, как она обучит запрошенное количество деревьев (или остановится раньше).

Перехватчики Keras, основанные на этапе обучения, также не будут работать — из-за характера обучения TF-DF модель обучается в конце первой эпохи и будет постоянной после этой эпохи. Этот шаг соответствует только вводу-выводу набора данных.

Модельный детерминизм

Алгоритм обучения TF-DF является детерминированным, т. е. двойное обучение на одном и том же наборе данных даст одну и ту же модель. Это отличается от нейронных сетей, обученных с помощью TensorFlow. Чтобы сохранить этот детерминизм, пользователи должны убедиться, что чтение набора данных также является детерминированным.

Конфигурация обучения

Укажите задачу (например, классификацию, ранжирование) вместо потери (например, двоичной кросс-энтропии).

- model = tf_keras.Sequential()
- model.add(Dense(64, activation=relu))
- model.add(Dense(1)) # One output for binary classification

- model.compile(loss=tf_keras.losses.BinaryCrossentropy(from_logits=True),
-               optimizer='adam',
-               metrics=['accuracy'])
# The loss is automatically determined from the task.
+ model = tfdf.keras.GradientBoostedTreesModel(task=tf_keras.Task.CLASSIFICATION)

# Optional if you want to report the accuracy.
+ model.compile(metrics=['accuracy'])

Обоснование: не все алгоритмы обучения TF-DF используют потери. Для тех, кто это делает, потеря автоматически обнаруживается в задаче и печатается в сводке модели. Вы также можете переопределить его с помощью гиперпараметра потерь.

Гиперпараметры семантически стабильны.

Все гиперпараметры имеют значения по умолчанию. Эти ценности являются разумными первыми кандидатами, которые стоит попробовать. Значения гиперпараметров по умолчанию гарантированно никогда не изменятся. По этой причине новые гиперпараметры или улучшения алгоритмов по умолчанию отключены.

Пользователи, которые хотят использовать новейшие алгоритмы, но не хотят оптимизировать гиперпараметры самостоятельно, могут использовать «шаблоны гиперпараметров», предоставляемые TF-DF. Новые шаблоны гиперпараметров будут выпущены вместе с обновлениями пакета.

# Model with default hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel()

# List the hyper-parameters (with default value) and hyper-parameters templates of the GBT learning algorithm (in colab)
?tfdf.keras.GradientBoostedTreesModel

# Use a hyper-parameter template.
model = tfdf.keras.GradientBoostedTreesModel(hp_template="winner_1")

# Change one of the hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel(num_trees=500)

# List all the learning algorithms available
tfdf.keras.get_all_models()

Отладка модели

В этом разделе представлены некоторые способы просмотра/отладки/интерпретации модели. Колаб для начинающих содержит комплексный пример.

Краткое описание простой модели

# Text description of the model, training logs, feature importances, etc.
model.summary()

Журналы тренировок и тензорная доска

# List of metrics
logs = model.make_inspector().training_logs()
print(logs)

Или используя TensorBoard:

% load_ext
tensorboard
model.make_inspector().export_to_tensorboard("/tmp/tensorboard_logs")
% tensorboard - -logdir
"/tmp/tensorboard_logs"

Важность функции

model.make_inspector().variable_importances()

Рисование деревьев

tfdf.model_plotter.plot_model_in_colab(model, tree_idx=0)

Доступ к древовидной структуре

tree = model.make_inspector().extract_tree(tree_idx=0)
print(tree)

(См. расширенную совместную работу )

Не используйте стратегии распространения TensorFlow.

TF-DF пока не поддерживает стратегии распределения TF. Настройки нескольких рабочих будут игнорироваться, и обучение будет происходить только на менеджере.

- with tf.distribute.MirroredStrategy():
-    model = ...
+ model = ....

Модели штабелирования

Модели TF-DF не поддерживают обратное распространение градиентов. В результате их нельзя составить с помощью моделей нейронных сетей, если нейронные сети уже не обучены.

Миграция с tf.estimator.BoostedTrees {Классификатор/Регрессор/Оценщик}

Несмотря на то, что деревья с усилением TF-DF и Estimator звучат одинаково, это разные алгоритмы. TF-DF реализует классические документы «Случайный лес» и «Машина с усилением градиента» (с использованием деревьев) . tf.estimator.BoostedTreesEstimator — это приблизительный алгоритм градиентных деревьев с процедурой мини-пакетного обучения, описанной в этой статье.

Некоторые гиперпараметры имеют схожую семантику (например, num_trees), но имеют разное качество. Если вы настроили гиперпараметры в своем tf.estimator.BoostedTreesEstimator, вам потребуется перенастроить гиперпараметры в TF-DF, чтобы получить оптимальные результаты.

Для пользователей Иггдрасиля

Yggdrasil Decision Forest — это основная библиотека обучения и вывода, используемая TF-DF. Конфигурация обучения и модели перекрестно совместимы (т. е. модели, обученные с помощью TF-DF, могут использоваться с выводом Иггдрасиля).

Однако некоторые алгоритмы Иггдрасиля (пока) недоступны в TF-DF.

  • Дерево с градиентным усилением и сегментированной выборкой.