Migrar desde redes neuronales

TensorFlow Decision Forests ( TF-DF ) es una colección de algoritmos de Decision Forest ( DF ) disponibles en TensorFlow. Los bosques de decisión funcionan de manera diferente a las redes neuronales ( NN ): los DF generalmente no se entrenan con retropropagación ni en minilotes. Por lo tanto, las canalizaciones TF-DF tienen algunas diferencias con otras canalizaciones de TensorFlow.

Este documento es una lista de esas diferencias y una guía para actualizar las canalizaciones de TF para usar TF-DF.

Este documento asume familiaridad con la colaboración para principiantes .

Conjunto de datos y características

Conjunto de datos de validación

A diferencia del paradigma de entrenamiento de redes neuronales estándar, los modelos TF-DF no necesitan un conjunto de datos de validación para monitorear el sobreajuste o detener el entrenamiento temprano. Si ya tiene una división de entrenamiento/validación/prueba y está usando la validación por una de esas razones, es seguro entrenar su TF-DF en tren+validación (a menos que la división de validación también se use para otra cosa, como ajuste de hiperparámetros).

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

# Or just don't create a validation dataset

Justificación: El marco TF-DF se compone de múltiples algoritmos. Algunos de ellos no utilizan un conjunto de datos de validación (por ejemplo, el bosque aleatorio), mientras que otros sí lo hacen (por ejemplo, los árboles potenciados por gradiente). Los algoritmos que lo hagan podrían beneficiarse de diferentes tipos y tamaños de conjuntos de datos de validación. Por lo tanto, si se necesita un conjunto de datos de validación, se extraerá automáticamente del conjunto de datos de entrenamiento.

E/S del conjunto de datos

Entrena exactamente durante 1 época.

# 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)

Justificación: los usuarios de redes neuronales a menudo entrenan un modelo para N pasos (lo que puede implicar recorrer el conjunto de datos > 1 vez), debido a la naturaleza de SGD . TF-DF entrena leyendo todo el conjunto de datos y luego ejecutando el entrenamiento al final. Se necesita 1 época para leer el conjunto de datos completo y cualquier paso adicional dará como resultado E/S de datos innecesarias, así como un entrenamiento más lento.

No mezclar el conjunto de datos

No es necesario mezclar los conjuntos de datos (a menos que input_fn esté leyendo solo una muestra del conjunto de datos).

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

Justificación: TF-DF baraja el acceso a los datos internamente después de leer el conjunto de datos completo en la memoria. Los algoritmos TF-DF son deterministas (si el usuario no cambia la semilla aleatoria). Habilitar la mezcla solo hará que el algoritmo no sea determinista. La mezcla tiene sentido si el conjunto de datos de entrada está ordenado y input_fn solo leerá una muestra del mismo (la muestra debe ser aleatoria). Sin embargo, esto hará que el procedimiento de formación no sea determinista.

No ajuste el tamaño del lote

El tamaño del lote no afectará la calidad del modelo.

- 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)

Justificación: dado que TF-DF siempre se entrena en el conjunto de datos completo después de leerlo, la calidad del modelo no variará según el tamaño del lote (a diferencia de los algoritmos de entrenamiento de mini lotes como SGD, donde parámetros como la tasa de aprendizaje deben ajustarse conjuntamente). Por lo tanto, debería eliminarse de los barridos de hiperparámetros. El tamaño del lote solo tendrá un impacto en la velocidad de E/S del conjunto de datos.

Grandes conjuntos de datos

A diferencia de las redes neuronales, que pueden recorrer infinitamente minilotes de un gran conjunto de datos, los bosques de decisión requieren un conjunto de datos finito que quepa en la memoria para sus procedimientos de entrenamiento. El tamaño del conjunto de datos tiene implicaciones de rendimiento y memoria.

Hay rendimientos decrecientes al aumentar el tamaño del conjunto de datos, y podría decirse que los algoritmos DF necesitan menos ejemplos de convergencia que los modelos NN grandes. En lugar de escalar la cantidad de pasos de entrenamiento (como en una NN), puede intentar escalar la cantidad de datos para ver dónde tiene sentido la compensación informática. Por lo tanto, es una buena idea intentar entrenar primero en un subconjunto (pequeño) del conjunto de datos.

La solución alternativa es utilizar la formación distribuida . La capacitación distribuida es una excelente manera de aumentar el tamaño del conjunto de datos si hay varias máquinas disponibles. Si bien todos los algoritmos distribuidos están disponibles para distribuir el cálculo, no todos pueden distribuir el uso de RAM. Consulte la documentación para obtener más detalles.

¿Cuántos ejemplos usar?

Debería caber en la memoria de la máquina en la que se está entrenando el modelo :

  • Tenga en cuenta que este no es el mismo tamaño que los ejemplos en el disco.

  • Como regla general, un valor numérico o categórico utiliza 4 bytes de memoria. Por lo tanto, un conjunto de datos con 100 funciones y 25 millones de ejemplos necesitará ~10 GB (= 100 * 25 *10^6 * 4 bytes) de memoria.

  • Las funciones de conjunto categórico (por ejemplo, texto tokenizado) requieren más memoria (4 bytes por token + 12 bytes por función).

Considere su presupuesto de tiempo de entrenamiento

  • Si bien generalmente son más rápidos que NN para conjuntos de datos más pequeños (por ejemplo, <100 000 ejemplos), los algoritmos de entrenamiento de DF no escalan linealmente con el tamaño del conjunto de datos; más bien, ~O(features x num_examples x log(num_examples)) en la mayoría de los casos.

  • El tiempo de entrenamiento depende de los hiperparámetros. Los parámetros de mayor impacto son: (1) la cantidad de árboles ( num_trees ), (2) la tasa de muestreo del ejemplo ( subsample para GBT) y (3) la tasa de muestreo de atributos ( num_candidate_attributes_ratio )

  • Las funciones de conjunto categórico son más caras que otras funciones. El costo está controlado por el parámetro categorical_set_split_greedy_sampling .

  • Las funciones dispersas oblicuas (deshabilitadas de forma predeterminada) dan buenos resultados pero su cálculo es costoso.

Reglas generales para ampliar los datos

Sugerimos comenzar con una pequeña porción de datos (<10k ejemplos), lo que debería permitirle entrenar un modelo TF-DF en segundos o unos minutos en la mayoría de los casos. Luego, puede aumentar los datos a una velocidad fija (por ejemplo, un 40 % más cada vez), deteniéndose cuando el rendimiento del conjunto de validación no mejora o el conjunto de datos ya no cabe en la memoria.

Normalización de características/preprocesamiento

No transforme datos con columnas de características

Los modelos TF-DF no requieren proporcionar transformaciones y semántica de características explícitamente. De forma predeterminada, el modelo detectará y utilizará todas las características del conjunto de datos (aparte de la etiqueta). La semántica de la característica se detectará automáticamente y se podrá anular manualmente si es necesario.

# 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()

También puede especificar un subconjunto de funciones de entrada:

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

Si es necesario, puedes forzar la semántica de una característica.

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

Justificación: si bien ciertos modelos (como las redes neuronales) requieren una capa de entrada estandarizada (por ejemplo, asignaciones de diferentes tipos de características → incrustaciones), los modelos TF-DF pueden consumir características categóricas y numéricas de forma nativa, así como también detectar automáticamente los tipos semánticos de las características. en base a los datos.

No preprocesar las características

Los algoritmos de árbol de decisión no se benefician de algunos de los preprocesamientos de características clásicos utilizados en las redes neuronales. A continuación, se enumeran explícitamente algunas de las estrategias de procesamiento de características más comunes, pero un punto de partida seguro es eliminar todo el procesamiento previo diseñado para ayudar al entrenamiento de redes neuronales.

No normalizar características numéricas

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

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

Racional: los algoritmos de bosque de decisión admiten de forma nativa características numéricas no normalizadas, ya que los algoritmos de división no realizan ninguna transformación numérica de la entrada. Algunos tipos de normalización (por ejemplo, la normalización zscore) no ayudarán a la estabilidad numérica del procedimiento de entrenamiento, y algunos (por ejemplo, el recorte de valores atípicos) pueden perjudicar la expresividad del modelo final.

No codifique características categóricas (por ejemplo, hash, one-hot o incrustación)

- 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)]

Justificación: TF-DF tiene soporte nativo para características categóricas y tratará un elemento de vocabulario "transformado" como un elemento más en su vocabulario interno (que se puede configurar mediante hiperparámetros del modelo). Algunas transformaciones (como el hash) pueden generar pérdidas. Las incorporaciones no son compatibles a menos que estén previamente entrenadas, ya que los modelos de Decision Forest no son diferenciables (ver colab intermedio ). Tenga en cuenta que las estrategias de vocabulario específicas de un dominio (por ejemplo, eliminación de palabras vacías, normalización de texto) aún pueden resultar útiles.

Cómo manejar las características del texto

TF-DF admite funciones de conjuntos categóricos de forma nativa. Por lo tanto, las bolsas de n-gramas tokenizados se pueden consumir de forma nativa.

Alternativamente, el texto también se puede consumir mediante una incrustación previamente entrenada .

Los conjuntos categóricos son eficientes en el muestreo en conjuntos de datos pequeños, pero costosos de entrenar en conjuntos de datos grandes. La combinación de conjuntos categóricos y una incrustación previamente entrenada a menudo puede producir mejores resultados que si se usa cualquiera de ellos por separado.

No reemplace las funciones faltantes con valores mágicos

Justificación: TF-DF tiene soporte nativo para valores faltantes. A diferencia de las redes neuronales, que pueden propagar NaN a los gradientes si hay NaN en la entrada, TF-DF se entrenará de manera óptima si el algoritmo ve la diferencia entre un valor faltante y un valor centinela.

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

Manejo de imágenes y series temporales

No existe un algoritmo estándar para consumir características de imágenes o series de tiempo en Decision Forests, por lo que se requiere algo de trabajo adicional para usarlos.

Justificación: la convolución, LSTM, la atención y otros algoritmos de procesamiento de secuencias son arquitecturas específicas de redes neuronales.

Es posible manejar estas características utilizando las siguientes estrategias:

  • Ingeniería de características

    • Imágenes: el uso de imágenes con Random Forest fue popular en algún momento (p. ej.

      Microsoft Kinect , pero hoy en día las redes neuronales son la última tecnología.

    • Series temporales: [ Estadísticas móviles ] puede funcionar sorprendentemente bien para datos de series temporales que tienen relativamente pocos ejemplos (por ejemplo, signos vitales en el ámbito médico).

    • Módulos integrados: los módulos integrados de redes neuronales pueden proporcionar funciones ricas para un algoritmo de bosque de decisiones. La colaboración intermedia muestra cómo combinar una integración tf-hub y un modelo TF-DF.

Canal de capacitación

No utilice aceleradores de hardware, por ejemplo, GPU o TPU.

La capacitación TF-DF no admite (todavía) aceleradores de hardware. Todo el entrenamiento y la inferencia se realizan en la CPU (a veces usando SIMD).

Tenga en cuenta que la inferencia TF-DF en la CPU (especialmente cuando se realiza utilizando bibliotecas Yggdrasil C++) puede ser sorprendentemente rápida (menos de un microsegundo por ejemplo por núcleo de CPU).

No utilices puntos de control ni ganchos a mitad del entrenamiento.

TF-DF no admite (actualmente) el control de puntos de modelo, lo que significa que los ganchos que esperan que el modelo sea utilizable antes de que se complete el entrenamiento no son en gran medida compatibles. El modelo solo estará disponible después de que entrene la cantidad solicitada de árboles (o se detenga antes de tiempo).

Los ganchos de Keras que dependen del paso de entrenamiento tampoco funcionarán; debido a la naturaleza del entrenamiento TF-DF, el modelo se entrena al final de la primera época y será constante después de esa época. El paso solo corresponde a la E/S del conjunto de datos.

Determinismo modelo

El algoritmo de entrenamiento TF-DF es determinista, es decir, entrenar dos veces en el mismo conjunto de datos dará exactamente el mismo modelo. Esto es diferente de las redes neuronales entrenadas con TensorFlow. Para preservar este determinismo, los usuarios deben asegurarse de que las lecturas del conjunto de datos también sean deterministas.

Configuración de entrenamiento

Especifique una tarea (por ejemplo, clasificación, clasificación) en lugar de una pérdida (por ejemplo, entropía cruzada binaria)

- 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'])

Justificación: no todos los algoritmos de aprendizaje TF-DF utilizan una pérdida. Para aquellos que lo hacen, la pérdida se detecta automáticamente en la tarea y se imprime en el resumen del modelo. También puede anularlo con el hiperparámetro de pérdida.

Los hiperparámetros son semánticamente estables

Todos los hiperparámetros tienen valores predeterminados. Esos valores son los primeros candidatos razonables a probar. Se garantiza que los valores predeterminados de los hiperparámetros nunca cambiarán. Por este motivo, los nuevos hiperparámetros o mejoras de algoritmos están deshabilitados de forma predeterminada.

Los usuarios que deseen utilizar los algoritmos más recientes, pero que no quieran optimizar los hiperparámetros ellos mismos, pueden utilizar las "plantillas de hiperparámetros" proporcionadas por TF-DF. Se lanzarán nuevas plantillas de hiperparámetros con actualizaciones del paquete.

# 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()

Depuración de modelos

Esta sección presenta algunas formas en que puede mirar/depurar/interpretar el modelo. La colaboración para principiantes contiene un ejemplo de un extremo a otro.

Resumen del modelo simple

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

Registros de entrenamiento y tensorboard

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

O usando TensorBoard:

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

Importancia de la característica

model.make_inspector().variable_importances()

Trazando los árboles

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

Acceder a la estructura de árbol

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

(Ver colab avanzado )

No utilice estrategias de distribución de TensorFlow

TF-DF aún no admite estrategias de distribución de TF. Se ignorarán las configuraciones de varios trabajadores y la capacitación solo se realizará en el gerente.

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

Modelos de apilamiento

Los modelos TF-DF no propagan gradientes hacia atrás. Como resultado, no se pueden componer con modelos NN a menos que los NN ya estén entrenados.

Migrando desde tf.estimator.BoostedTrees {Clasificador/Regresor/Estimador}

A pesar de que suenan similares, los árboles impulsados ​​por TF-DF y Estimator son algoritmos diferentes. TF-DF implementa los documentos clásicos Random Forest y Gradient Boosted Machine (usando árboles) . El tf.estimator.BoostedTreesEstimator es un algoritmo aproximado de árboles potenciados por gradiente con un procedimiento de entrenamiento de mini lotes descrito en este documento.

Algunos hiperparámetros tienen una semántica similar (por ejemplo, num_trees), pero tienen implicaciones de calidad diferentes. Si ajustó los hiperparámetros en su tf.estimator.BoostedTreesEstimator, deberá volver a ajustar sus hiperparámetros dentro de TF-DF para obtener los resultados óptimos.

Para usuarios de Yggdrasil

Yggdrasil Decision Forest es la biblioteca central de inferencia y capacitación utilizada por TF-DF. La configuración y los modelos de entrenamiento son compatibles entre sí (es decir, los modelos entrenados con TF-DF se pueden usar con la inferencia de Yggdrasil).

Sin embargo, algunos de los algoritmos de Yggdrasil no están (todavía) disponibles en TF-DF.

  • Árbol potenciado por gradiente con muestreo fragmentado.