Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/es-419/addons/tutorials/optimizers_cyclicallearningrate.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

Optimizadores de complementos de TensorFlow: CyclicalLearningRate

Descripción general

En este tutorial se explica el uso del optimizador CyclicalLearningRate del paquete de complementos.

Tasas de aprendizaje cíclicas

Se ha demostrado que es conveniente ajustar la tasa de aprendizaje a medida que avanza el entrenamiento de una red neuronal. Tiene numerosas ventajas, desde la recuperación del punto de inflexión hasta la posibilidad de evitar las inestabilidades numéricas que podrían surgir durante la retropropagación. Pero, ¿cómo saber cuánto ajustar con relación a una marca temporal de entrenamiento concreta? En 2015, Leslie Smith se dio cuenta de que es conveniente aumentar la tasa de aprendizaje para recorrer más rápidamente el panorama de pérdidas, pero también reducir la tasa de aprendizaje cuando nos acercamos a la convergencia. Para materializar esta idea, propuso las tasas de aprendizaje cíclicas (CLR) en las que se ajustaría la tasa de aprendizaje con respecto a los ciclos de una función. Si desea acceder a una demostración visual, consulte este blog. Ahora CLR está disponible como una API de TensorFlow. Más información aquí, en el artículo original.

Preparación

!pip install -q -U tensorflow_addons
from tensorflow.keras import layers import tensorflow_addons as tfa import tensorflow as tf import numpy as np import matplotlib.pyplot as plt tf.random.set_seed(42) np.random.seed(42)

Carga y preparación del conjunto de datos

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data() x_train = np.expand_dims(x_train, -1) x_test = np.expand_dims(x_test, -1)

Definición de hiperparámetros

BATCH_SIZE = 64 EPOCHS = 10 INIT_LR = 1e-4 MAX_LR = 1e-2

Definición de las utilidades de desarrollo y entrenamiento de modelos

def get_training_model(): model = tf.keras.Sequential( [ layers.InputLayer((28, 28, 1)), layers.experimental.preprocessing.Rescaling(scale=1./255), layers.Conv2D(16, (5, 5), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(32, (5, 5), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.SpatialDropout2D(0.2), layers.GlobalAvgPool2D(), layers.Dense(128, activation="relu"), layers.Dense(10, activation="softmax"), ] ) return model def train_model(model, optimizer): model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizer, metrics=["accuracy"]) history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, validation_data=(x_test, y_test), epochs=EPOCHS) return history

Para facilitar la reproducibilidad, hemos serializado los pesos iniciales del modelo que se usarán para realizar los experimentos.

initial_model = get_training_model() initial_model.save("initial_model")

Entrenamiento de un modelo sin CLR

standard_model = tf.keras.models.load_model("initial_model") no_clr_history = train_model(standard_model, optimizer="sgd")

Definición del cronograma de CLR

El módulo tfa.optimizers.CyclicalLearningRate devuelve un cronograma directo que puede pasarse a un optimizador. El cronograma toma un paso como entrada y devuelve un valor calculado con la fórmula CLR que se describe en el documento.

steps_per_epoch = len(x_train) // BATCH_SIZE clr = tfa.optimizers.CyclicalLearningRate(initial_learning_rate=INIT_LR, maximal_learning_rate=MAX_LR, scale_fn=lambda x: 1/(2.**(x-1)), step_size=2 * steps_per_epoch ) optimizer = tf.keras.optimizers.SGD(clr)

Aquí, se especifican los límites inferior y superior de la tasa de aprendizaje y el cronograma oscilará entre ese intervalo ([1e-4, 1e-2] en este caso). scale_fn se utiliza para definir la función que aumentaría y reduciría la tasa de aprendizaje dentro de un determinado ciclo. step_size define la duración de un solo ciclo. Un step_size de 2 indica que se necesitan un total de 4 iteraciones para completar un ciclo. El valor recomendado para step_size es el siguiente:

factor * steps_per_epoch donde el factor se encuentra dentro del intervalo [2,8].

En el mismo documento sobre la CLR, Leslie también presentó un método sencillo e inteligente para elegir los límites de la tasa de aprendizaje. Le recomendamos que también lo consulte. Esta entrada de blog es una buena introducción al método.

A continuación, se ilustra el cronograma clr.

step = np.arange(0, EPOCHS * steps_per_epoch) lr = clr(step) plt.plot(step, lr) plt.xlabel("Steps") plt.ylabel("Learning Rate") plt.show()

Para poder apreciar mejor el efecto de la CLR, puede trazar el cronograma con un mayor número de pasos.

step = np.arange(0, 100 * steps_per_epoch) lr = clr(step) plt.plot(step, lr) plt.xlabel("Steps") plt.ylabel("Learning Rate") plt.show()

La función que no está usando en este tutorial se menciona como el método triangular2 en el documento sobre la CLR. Se exploraron otras dos funciones, concretamente, triangular y exp (abreviatura de exponencial).

Entrenamiento de un modelo con CLR

clr_model = tf.keras.models.load_model("initial_model") clr_history = train_model(clr_model, optimizer=optimizer)

Como era de esperarse, la pérdida comienza en niveles más altos de lo habitual y luego se estabiliza a medida que avanzan los ciclos. Puede comprobarlo visualmente en los siguientes gráficos.

Visualización de pérdidas

(fig, ax) = plt.subplots(2, 1, figsize=(10, 8)) ax[0].plot(no_clr_history.history["loss"], label="train_loss") ax[0].plot(no_clr_history.history["val_loss"], label="val_loss") ax[0].set_title("No CLR") ax[0].set_xlabel("Epochs") ax[0].set_ylabel("Loss") ax[0].set_ylim([0, 2.5]) ax[0].legend() ax[1].plot(clr_history.history["loss"], label="train_loss") ax[1].plot(clr_history.history["val_loss"], label="val_loss") ax[1].set_title("CLR") ax[1].set_xlabel("Epochs") ax[1].set_ylabel("Loss") ax[1].set_ylim([0, 2.5]) ax[1].legend() fig.tight_layout(pad=3.0) fig.show()

Aunque en este ejemplo de laboratorio no se aprecian mucho los efectos de la CLR, hay que tener en cuenta que es uno de los principales ingredientes de la superconvergencia y que puede tener un impacto realmente bueno cuando se entrena en entornos a gran escala.