Optimizando los hiperparámetros de una red neuronal con TensorBoardEnrique Blanco 24 marzo, 2021 Al crear modelos de Machine Learning se deben investigar múltiples parámetros como el número de nodos de las capas, diferentes optimizadores, valores de tasas de aprendizaje, distintas tasas de dropout, etc. Por lo tanto, un paso importante en el flujo de trabajo del Machine Learning es identificar los mejores hiperparámetros para el problema que se está abordando, lo que a menudo implica un gran número de pruebas. Este proceso se conoce como Optimización de hiperparámetros. Para poder realizarlo, TensorFlow 2.0 proporciona el panel de HParams en TensorBoard, que nos permitirá visualizar el comportamiento de nuestro modelo en función de los valores que definen nuestro modelo en nuestro dashboard. Hace unos meses escribimos un breve post sobre TensorBoard, un kit de herramientas de TensorFlow que permite monitorizar métricas como la precisión y la función de pérdida durante el entrenamiento de modelos profundos. En este anterior artículo investigamos, dentro de las funcionalidades más básicas de TensorBoard, cómo se podía monitorizar las métricas de un modelo de Machine Learning, la evolución de los pesos y sesgos de nuestra arquitectura, visualizar el grafo de nuestro modelo e incluso realizar un sencillo análisis de matriz de confusión de nuestro modelo una vez estuviera entrenado. En el presente post vamos a probar a encontrar los hiperparámetros de una red neuronal recurrente dedicada a multivariate time series forecasting. Para más detalles sobre cómo abordar un problema de este tipo, puede leer el siguiente enlace. Figura 1. Grafo del modelo recurrente usado para la predicción de time series en el dashboard de TensorBoard. Definiendo los valores de los hiperparámetros a probar Con TensorBoard, se puede realizar un seguimiento de la precisión y la pérdida del modelo en cada época; y también con diferentes valores de hiperparámetros. La precisión de seguimiento para diferentes los diferentes valores nos ayudará a ajustar el modelo más rápido. A continuación, se muestra un ejemplo de cómo listar los intervalos de valores para cada hiperparámetro. # ## Create hyperparameters HP_INPUT_WIDTH = hp.HParam('num_input_width', hp.Discrete([12, 24, 48, 96])) HP_OUTPUT_WIDTH = hp.HParam('num_output_width', hp.Discrete([6, 12, 24, 48])) HP_RNN_UNITS = hp.HParam('num_rnn_units', hp.Discrete([30, 40, 60, 80, 100])) HP_DROPOUT = hp.HParam('dropout', hp.Discrete([0.05, 0.1, 0.2])) HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam'])) HP_LEARNING_RATE = hp.HParam('learning_rate', hp.Discrete([0.001])) METRIC_ACCURACY = 'accuracy' Creando, compilando y ajustando el modelo Suponiendo que ya tenemos realizada la partición de nuestro dataset de time series en train, test y/o validación y que ese dataset está convenientemente preprocesado, definimos la arquitectura del modelo (haciendo uso de Keras) junto con algunos callbacks como EarlyStopping o el propio callback de TensorBoard que nos permitirá loguear el desempeño de nuestra red para cada combinación posible de hiperparámetros. def create_model(hparams): # Define model architecture input_shape = (hparams[HP_INPUT_WIDTH], num_features) inp = tf.keras.layers.Input(input_shape) x = tf.keras.layers.LSTM(hparams[HP_RNN_UNITS], return_sequences=False)(inp) x = tf.keras.layers.Flatten()(x) x = get_dropout(x, p=hparams[HP_DROPOUT], mc=True) # Shape => [batch, 1, out_steps*features] x = tf.keras.layers.Dense(hparams[HP_OUTPUT_WIDTH]*num_features, kernel_initializer=tf.keras.initializers.VarianceScaling())(x) out = tf.keras.layers.Reshape([hparams[HP_OUTPUT_WIDTH], num_features])(x) # Build model model = tf.keras.models.Model(inputs=inp, outputs=out) # Setting the optimizer and learning rate optimizer = hparams[HP_OPTIMIZER] learning_rate = hparams[HP_LEARNING_RATE] if optimizer == 'adam': optimizer = tf.optimizers.Adam(learning_rate=learning_rate) else: raise ValueError("Unexpected optimizer name: %r" % (optimizer_name,)) # Define Early Stopping early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, mode='min') # Define path where TensorBoard logs will be stored log_dir = os.path.join(tensorboard_path, 'lstm_verbose', datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) with tf.summary.create_file_writer(log_dir).as_default(): hp.hparams_config( hparams= [ HP_INPUT_WIDTH, HP_OUTPUT_WIDTH, HP_RNN_UNITS, HP_DROPOUT, HP_OPTIMIZER, HP_LEARNING_RATE ], metrics=[hp.Metric(METRIC_ACCURACY, display_name='accuracy')], ) # We compile the model model.compile(loss=tf.losses.MeanSquaredError(), optimizer=optimizer, metrics=[ tf.metrics.MeanAbsoluteError(), tf.keras.metrics.MeanSquaredError(), 'accuracy' ]) # Define a Window Generator to feed the neural network multi_window = WindowGenerator(input_width=hparams[HP_INPUT_WIDTH], label_width=hparams[HP_OUTPUT_WIDTH], shift=hparams[HP_OUTPUT_WIDTH]) # Fitting the model history = model.fit(multi_window.train, epochs=max_epochs, validation_data=multi_window.val, callbacks=[early_stopping,\ tf.keras.callbacks.TensorBoard(log_dir), hp.KerasCallback(log_dir, hparams)]) return history.history['val_accuracy'][-1] Para cada ejecución del modelo, necesitamos registrar el resumen de hparams con el hiperparámetro y la precisión de las épocas finales. Necesitamos convertir la precisión de validación de la última época en un valor escalar. def run(run_dir, hparams): with tf.summary.create_file_writer(run_dir).as_default(): hp.hparams(hparams) # record the values used in this trial accuracy = create_model(hparams) # converting to tf scalar accuracy = tf.reshape(tf.convert_to_tensor(accuracy), []).numpy() tf.summary.scalar(METRIC_ACCURACY, accuracy, step=1) Ejecutando el modelo con diferentes valores de hiperparámetros En este paso se usa Grid Search para probar todas las combinaciones posibles. session_num = 0 for num_input_units in HP_INPUT_WIDTH.domain.values: for num_output_units in HP_OUTPUT_WIDTH.domain.values: for num_rnn_units in HP_RNN_UNITS.domain.values: for dropout_rate in HP_DROPOUT.domain.values: for optimizer in HP_OPTIMIZER.domain.values: for learning_rate in HP_LEARNING_RATE.domain.values: hparams = { HP_INPUT_WIDTH: num_input_units, HP_OUTPUT_WIDTH: num_output_units, HP_RNN_UNITS: num_rnn_units, HP_DROPOUT: dropout_rate, HP_OPTIMIZER: optimizer, HP_LEARNING_RATE: learning_rate, } run_name = "run-%d" % session_num print('--- Starting trial: %s' % run_name) print({h.name: hparams[h] for h in hparams}) run(os.path.join(tensorboard_path, 'lstm_mc_hgs_verbose', datetime.datetime.now().strftime("%Y%m%d-%H%M%S")), hparams) session_num += 1 Visualizando los resultados de la búsqueda Ejecutamos en un terminal (tras haber activado nuestro entorno virtual de Python) y ejecutamos el siguiente comando: tensorboard --logdir "/logs/lstm_verbose/" --port 6006 Si nos vamos a http://localhost:6006/ podremos acceder al dashboard de TensorBoard. Si se ha logueado todo correctamente, en el dashboard se tendrá disponible una pestaña llamada HParams, que muestra las ejecuciones individuales para cada combinación de hiperparámetros ordenadas de acuerdo a los valores de METRIC_ACCURACY especificada arriba. Figura 2. Resumen de experimentos realizados con estrategia de Grid Search en HParams con TensorBoard. Figura 3. Parallel Coordinates View de HParams en el dashboard de TensorBoard. Figura 4. Scatter Plot Matrix View de HParams en el dashboard de TensorBoard. Como se ve en la figura anterior, el panel izquierdo del panel proporciona capacidades de filtrado que están activas en todas las vistas en el panel de HParams: Filtrar qué hiperparámetros/métricas se muestran en el panel;Filtrar qué valores de hiperparámetros/métricas se muestran en el panel;Filtrar por estado de ejecución (en ejecución o terminadas);Ordenar por hiperparámetro/métrica en la vista de tabla;Número de grupos de sesiones para mostrar (útil para el rendimiento cuando hay muchos experimentos). El panel de HParams tiene tres vistas diferentes, con diversa información útil: La vista de tabla (Figura 2) enumera las ejecuciones, sus hiperparámetros y sus métricas.La pestaña de coordenadas paralelas (Figura 3) muestra cada tramo como una línea que pasa por un eje para cada hiperparámetro y métrica. La vista de gráfico de dispersión (Figura 4) muestra gráficos que comparan cada hiperparámetro/métrica con cada métrica. Esto puede ayudar a identificar correlaciones. Conclusión Os invitamos a intentar realizar un experimento similar al expuesto en este post con la red convolucional que construimos en Supervisa tu entrenamiento de redes neuronales con TensorBoard para Fashion MNIST, probando a modificar el número de filtros, el tamaño de kernel, el número de unidades en las capas densas finales y/o distintos optimizadores distintos de Adam. Para más detalle sobre Hyperparameter Tuning, puede consultar el tutorial de TensorFlow. Para mantenerte al día con LUCA visita nuestra página web, suscríbete a LUCA Data Speaks o síguenos en Twitter, LinkedIn y YouTube. Gobierno del dato: el caos, un orden por descifrarVideo Post #25: ¿Cómo hacer las preguntas adecuadas en Ciencia de Datos?
Telefónica Tech Boletín semanal de Ciberseguridad, 21 – 27 de enero Killnet apunta contra objetivos en España Esta semana el grupo hacktivista Killnet anunció una campaña de ataques contra Alemania, dando lugar a la realización de ataques de Denegación de Servicio...
AI of Things Alumbrado público inteligente: oportunidades de negocio y beneficios para municipios y ciudadanos El alumbrado público inteligente es uno de los pilares de las ciudades inteligentes. De hecho, es uno de los mejores ejemplos de lo que significa el término Smart City:...
Gonzalo Fernández Rodríguez ¿Qué significa que mi aplicación sea Cloud Native? El término Cloud Native es algo que va más allá de mover las aplicaciones alojadas en un data center a una infraestructura proporcionada por un proveedor Cloud, sea Cloud...
Nacho Palou Humanidad aumentada, el concepto que popularizó un ex-CEO de Google y que está más vigente que nunca Hace algunos años el entonces CEO de Google, Eric Schmidt, popularizó el concepto “humanidad aumentada”. Este término se refiere a la capacidad que tiene la tecnología de “mejorar las...
Telefónica Tech Boletín semanal de Ciberseguridad, 14 – 20 de enero Vulnerabilidades críticas en los router Netcomm y TP-Link Se han descubierto una serie de vulnerabilidades en los routers Netcomm y TP-Link. Por un lado, los fallos, identificados como CVE-2022-4873 y CVE-2022-4874, se tratan de un...
Nacho Palou Empieza ya a programar Inteligencia Artificial: lenguajes, herramientas y recomendaciones Existe una relación muy estrecha en Big Data e Inteligencia Artificial (IA): Big Data consiste en capturar, procesar y analizar grandes cantidades de datos. Cuando estos datos se...