# Modulo de preprocesamiento [TOC] # Introducción El API Conabio-ML tiene la capacidad de persistir las manipulaciones realizadas en los conjuntos de datos utilizados. Esto se realiza, de manera general, de las siguientes maneras: 1. **Explícitamente** El módulo dataset contiene métodos que permiten las persistencias del dataset de distintas maneras. - **En el sistema de archivos** Por medio de `to_folder(dataset, *args)` - **Como un csv** Por medio de `to_csv(dataset, *args)` 2. **Implícitamente** Realizando el reporte de algún proceso relacionado con la manipulación del dataset. (Véase el [siguiente enlace](https://hackmd.io/y-uuPRJ5S6mAYefn-b9oEQ) para la documentación relacionada al reporte de procesos.) ```python [ . . . ] .add_process(name="process_name", action=Dataset.split, # Dataset manipulation method reportable = True, inputs_from_processes=["process_holds_dataset"], args={ [ . . . ] }) [ . . . ] ``` En ambos casos el dataset a persistir es tabular, y por lo menos contiene las columnas `item` y `label`. Dado sea el caso, se pueden añadir los datos de partición y columnas adicionales. Aún cuando la expresión del conjunto de datos de forma tabular es intuitiva y legible no es compatible con varios escenarios de entrenamiento y evaluación de un modelo de ML. La representación general del dataset se mantiene intacta. Sin embargo, hay procesos específicos que requieren que este conjunto de datos se exprese de manera diferente. Para este propósito el API Conabio-ML expone el modulo de **preprocesamiento**. Toda representación dependiente de un proceso externo al dataset debe realizarse por medio del modulo de preprocesamiento y debe registarse en la propiedad `representations` del dataset con su tipo asociado. # Representaciones disponibles. Actualmente se tienen implementados algunos módulos para la representación/preprocesamiento del dataset para escenarios específicos. Esta implementación está englobada en las clases `Preprocessor` correspondiente, definida como sigue: La siguiente reprentaciones están disponibles ## Preprocesadores para modelos TFKeras Esta implementado en la clase [tfkeras_preprocessing.Preprocessor](https://bitbucket.org/conabio_cmd/conabio_ml/src/CONML-51-reporte-de-procesos/conabio_ml/preprocessing/backends/tfkeras_preprocessing.py) y contiene las reperesentaciones compatibles para el entrenamienton con modelos de [tf.keras](https://www.tensorflow.org/api_docs/python/tf/keras) para tensorflow 2.+. (Puede consultar la documentación para el enlace de estos modelos por medio de API en el [siguiente enlace](https://hackmd.io/h9FjIdt-Sz6dW54pWd6T0w)). ### Como generador de imágenes Sigue la especificación de [ImageDataGenerator](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator) Expresa el dataset como un ImageDataGenerator y lo guarda en la representación ```python representations[tfkeras_preprocessing.IMAGE_GENERATOR] ``` Define los parámetros para aumento de datos y flujo de imágenes con un tamaño definido. Esta definido como: ```python def as_image_generator( dataset: Dataset.DatasetType, preproc_args: dict = { 'use_partitions': True, 'preproc_opts': {}, 'dataset_handling': {} }) -> Dataset.DatasetType: [ . . . ] ``` Donde: - **dataset [Dataset.DatasetType]**: Es el conjunto de datos a representar. - **preproc_args**: Son las opciones de aumento de datos y manejo del dataset. - **use_parttions [bool]**: Si True utiliza las particiones definidas en el dataset. Si False todo el dataset se utiliza como la particion TRAIN. - **preproc_opts [dict]**: Opciones de aumento de datos (No es el mejor nombre que he puesto). Definidas por la siguiente [especificación](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator#expandable-1). - **dataset_handling [dict]**: Opciones de manejo al momento del entrenamiento. Definidas por la siguiente [especificación](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator#flow_from_dataframe). #### Uso Hay 2 métodos disponibles para crear una representación como generador de imágenes de un dataset: implicitamente o por medio de un pipeline. 1. **Implicitamente** ```python # We build the representation will all the partitions available use_partition = True # Augment options preproc_opts = { 'vertical_flip': True, 'rotation_range': 40 } ## Handling dataset_handling = { "target_size": (100, 100), # Target size of the image 'batch_size': 32 # Size of the batch } # Dataset loading dataset = Dataset.from_xx(opts) # Model and trainer model = ModelName({"model_name": { [model_config] } }) trainer_config = TFKerasTrainerConfig.create(config={ [trainer_config] }) train_config = { # We need to set what representation will be used representation: tfkeras_preprocessing.IMAGE_GENERATOR, [ other options ] } # Dataset preprocessing and handling Preprocessor.as_image_generator(dataset=dataset, preproc_args = { "use_partition": use_partition, "preproc_opts": preproc_opts, "dataset_handling": dataset_handling }) model_trained = Trainer.train(dataset, model, trainer_config, train_config) ``` 2. **Usando un pipeline** ```python pipeline = Pipeline()\ .add_process(name="trainer_cfg", [ . . .])\ .add_process(name="dataset_from", [ . . . ])\ # Preprocessing and handling options .add_process(name="preprocess_dataset", action=TFKerasPreprocessor.as_image_generator, inputs_from_processes=["dataset_from"], args={ 'preproc_args': { 'use_partitions': True, 'preproc_opts': { 'vertical_flip': True, 'rotation_range': 40 }, 'dataset_handling': { "target_size": (100, 100), 'batch_size': 32 }} })\ .add_process(name="create_model", [ . . .])\ .add_process(name="train_model", action=TFKerasTrainer.train, inputs_from_processes=["preprocess_dataset", "create_model", "trainer_cfg"], args={ 'train_config': { 'representation': tfkeras_preprocessing.IMAGE_GENERATOR, [ further options ] }) ``` La implementación completa puede consultarse en el [siguiente enlace](https://bitbucket.org/conabio_cmd/conabio_ml/src/CONML-51-reporte-de-procesos/examples/images/classification/generic/inception/inception.ipynb). ### Como dataset Sigue la especificación de [tf.dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset). Expresa el dataset como un objeto tf.Dataset que puede utilizarse para entrenar un modelo de [tf.Keras](https://www.tensorflow.org/api_docs/python/tf/keras) y lo guarda en la representación ```python representations[tfkeras_preprocessing.TENSOR_SLICES] ``` Define los parámetros para aumento de datos y flujo de imágenes con un tamaño definido. Esta definido como: ```python def as_tensor_slices(dataset: Dataset.DatasetType, preproc_args: dict = { 'use_partitions': True, 'dataset_handling': {} }) -> Dataset.DatasetType: [ . . . ] ``` Donde: - **dataset [Dataset.DatasetType]**: Es el conjunto de datos a representar. - **preproc_args**: Son las opciones de aumento de datos y manejo del dataset. - **use_parttions [bool]**: Si True utiliza las particiones definidas en el dataset. Si False todo el dataset se utiliza como la particion TRAIN. - **dataset_handling [dict]**: Define las opciones del manejo del dataset como sigue: - item_field [str] default: item. Campo para datos de entrenamineto - label_field [str] default: label. Campo para datos de etiquetas - item_type [tf.dtypes]: Tipo de dato esperado en campo `item` - label_type [tf.dtypes]: Tipo de dato esperado en campo `label` - labelset [str or list]: Etiquetas disponibles para el campo label (en caso de ser necesarias). #### Uso Hay 2 métodos disponibles para crear una representación como tf.dataset de un dataset: implicitamente o por medio de un pipeline. 1. **Implicitamente** ```python # We build the representation will all the partitions available use_partition = True ## Handling dataset_handling = { "item_type": tf.string, # type of the train field "label_type": tf.int64, # type of the label field "labelset": './labelset' # File where the possible label values are defined } # Dataset loading dataset = Dataset.from_xx(opts) # Model and trainer model = ModelName({"model_name": { [model_config] } }) trainer_config = TFKerasTrainerConfig.create(config={ [trainer_config] }) train_config = { # We need to set what representation will be used representation: tfkeras_preprocessing.TENSOR_SLICES, [ other options ] } # Dataset preprocessing and handling Preprocessor.as_image_generator(dataset=dataset, preproc_args = { "use_partition": use_partition, "dataset_handling": dataset_handling }) model_trained = Trainer.train(dataset, model, trainer_config, train_config) ``` 2. **Usando un pipeline** ```python pipeline = Pipeline()\ .add_process(name="trainer_cfg", [ . . .])\ .add_process(name="dataset_from", [ . . . ])\ .add_process(name="preprocess_dataset", action=TFKerasPreprocessor.as_tensor_slices, inputs_from_processes=["dataset_from"], args={ 'preproc_args': { 'use_partitions': True, 'dataset_handling': { "item_type": tf.string, "label_type": tf.int64, "labelset": './labelset' }} })\ .add_process(name="create_model", [ . . .])\ .add_process(name="train_model", action=TFKerasTrainer.train, inputs_from_processes=["preprocess_dataset", "create_model", "trainer_cfg"], args={ 'train_config': { 'representation': tfkeras_preprocessing.TENSOR_SLICES, [ further options ] }) ``` La implementación completa puede consultarse en el [siguiente enlace](https://bitbucket.org/conabio_cmd/conabio_ml/src/CONML-51-reporte-de-procesos/examples/text/classification/generic/news/news_manual_preprocessing.ipynb).