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 decisiones funcionan de manera diferente a las redes neuronales ( NN ): los DF generalmente no se entrenan con retropropagación o en mini lotes. Por lo tanto, las canalizaciones de TF-DF tienen algunas diferencias con respecto a otras canalizaciones de TensorFlow.

Este documento es una lista de esas diferencias y una guía para actualizar las canalizaciones 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 antes de tiempo. Si ya tiene una división de entrenamiento/validación/prueba y está usando la validación por uno de esos motivos, 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 varios algoritmos. Algunos de ellos no utilizan un conjunto de datos de validación (p. ej., Random Forest), mientras que otros sí (p. ej., Gradient Boosted Trees). Los algoritmos que lo hacen 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 de conjunto de datos

Entrena durante exactamente 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 una E/S de datos innecesaria, 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 lea 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 reproducción aleatoria 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 va a leer una muestra (la muestra debe ser aleatoria). Sin embargo, esto hará que el procedimiento de entrenamiento 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 los parámetros como la tasa de aprendizaje deben ajustarse conjuntamente). Por lo tanto, debe 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 en el rendimiento y la memoria.

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

La solución alternativa es utilizar el entrenamiento distribuido . El entrenamiento distribuido 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.

Cuantos ejemplos usar

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

  • Tenga en cuenta que esto no es lo mismo que el tamaño de 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 ocupará ~10 GB (= 100 * 25 * 10^6 * 4 bytes) de memoria.

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

Considere su presupuesto de tiempo de capacitación

  • Si bien generalmente es más rápido que NN para conjuntos de datos más pequeños (p. ej., <100k 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 más impactantes son: (1) la cantidad de árboles ( num_trees ), (2) la tasa de muestreo del ejemplo ( subsample para GBT) y (3) la tasa de muestreo del atributo ( num_candidate_attributes_ratio )

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

  • Las características de Sparse Oblique (deshabilitadas de forma predeterminada) dan buenos resultados pero son costosas de calcular.

Reglas generales para ampliar los datos

Sugerimos comenzar con una pequeña porción de los 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 tasa 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 que se proporcionen explícitamente semánticas y transformaciones de características. 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 función se detectará automáticamente y se puede 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 entidades 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, puede 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: mientras que ciertos modelos (como las redes neuronales) requieren una capa de entrada estandarizada (p. ej., 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 detectar automáticamente los tipos semánticos de las características. basado en los datos.

No preprocesar las características

Los algoritmos de árboles de decisión no se benefician de algunos de los preprocesamientos de características clásicas que se utilizan para 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 que se diseñó 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 decisiones 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 (p. ej., la normalización de zscore) no ayudarán a la estabilidad numérica del procedimiento de entrenamiento, y algunos (p. ej., el recorte de valores atípicos) pueden dañar la expresividad del modelo final.

No codifique características categóricas (por ejemplo, hashing, 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 funciones categóricas y tratará un elemento de vocabulario "transformado" como un elemento más en su vocabulario interno (que se puede configurar a través de hiperparámetros del modelo). Algunas transformaciones (como hash) pueden tener pérdidas. Las incrustaciones no son compatibles a menos que estén previamente entrenadas, ya que los modelos de Decision Forest no son diferenciables (consulte la colaboración intermedia ). Tenga en cuenta que las estrategias de vocabulario específicas del dominio (p. ej., eliminación de palabras vacías, normalización de texto) aún pueden ser ú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 a través de una incrustación preentrenada .

Los conjuntos categóricos son eficientes como muestra 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 preentrenada a menudo puede generar mejores resultados que si se usa solo.

No reemplace las características que faltan por 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 el valor perdido y el 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 funciones de imágenes o series temporales en Decision Forests, por lo que se requiere algo de trabajo adicional para usarlas.

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

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

  • Ingeniería de características

    • Imágenes: el uso de imágenes con Random Forest fue popular en algún momento (por ejemplo,

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

    • Series de tiempo: [ Estadísticas móviles ] puede funcionar sorprendentemente bien para datos de series de tiempo que tienen relativamente pocos ejemplos (p. ej., signos vitales en el dominio médico).

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

Línea de formación

No use aceleradores de hardware, por ejemplo, GPU, TPU

El entrenamiento TF-DF (todavía) no admite 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 utiliza con bibliotecas Yggdrasil C++) puede ser sorprendentemente rápida (submicrosegundos por ejemplo por núcleo de CPU).

No utilice puntos de control o ganchos de mitad de entrenamiento

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

Los ganchos de Keras que dependen del paso de entrenamiento tampoco funcionarán; debido a la naturaleza del entrenamiento TF-DF, el modelo 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 de TF-DF utilizan una pérdida. Para aquellos que lo hacen, la pérdida se detecta automáticamente desde 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 primeros candidatos razonables para probar. Se garantiza que los valores predeterminados de los hiperparámetros nunca cambiarán. Por este motivo, los nuevos hiperparámetros o las mejoras de algoritmos están deshabilitados de forma predeterminada.

Los usuarios que deseen utilizar los algoritmos más recientes, pero que no deseen optimizar los hiperparámetros por sí 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 las que puede ver/depurar/interpretar el modelo. La colaboración para principiantes contiene un ejemplo completo.

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

Trazar 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 colaboración avanzada )

No use estrategias de distribución de TensorFlow

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

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

Modelos apilables

Los modelos TF-DF no retropropagan gradientes. 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 sonar similar, los árboles potenciados TF-DF y Estimator son algoritmos diferentes. TF-DF implementa los papeles clásicos Random Forest y Gradient Boosted Machine (usando Trees) . El tf.estimator.BoostedTreesEstimator es un algoritmo aproximado de Gradient Boosted Trees 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 diferentes implicaciones de calidad. 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 principal de capacitación e inferencia 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.