Hola, me llamo Miguel y en esta ocasión les traigo otro artículo.
Aplicación de Transfer Learning en el campo del procesamiento del lenguaje natural
El mes pasado, comencé el fastai MOOC (2019) – Aprendizaje profundo para codificadores. Cubre varios temas como Visión por Computador, Procesamiento del Lenguaje Natural, Filtrado Colaborativo, etc. La parte más fascinante que encontré fue la aplicación del Aprendizaje por Transferencia en el campo del Procesamiento del Lenguaje Natural. El abordado utilizado por fastai es Ajuste fino del modelo de lenguaje universal (ULMFiT), que es una metodología de aprendizaje por transferencia aplicada en el campo del procesamiento del lenguaje natural.
De acuerdo a Wikipedia, el aprendizaje por transferencia (TL) es un problema de investigación en aprendizaje automático (ML) que se centra en almacenar el conocimiento adquirido al resolver un problema y aplicarlo a un problema diferente pero relacionado. Por ejemplo, el conocimiento adquirido al aprender a reconocer automóviles podría aplicarse al intentar reconocer camiones.
Para mostrar el caso de uso de ULMFiT, Aplicaré lo mismo en el ¿Real o no? PNL con tweets de desastres competencia en Kaggle. Para darle una descripción general de los datos, el conjunto de datos contiene dos CSV archivos train.csv
y test.csv
que representan el conjunto de datos de entrenamiento y el conjunto de datos de prueba respectivamente. El conjunto de entrenamiento contiene los datos del tweet en text
columna y valor objetivo en target
columna, cuyo valor es 1
si es un desastre real o 0
si no es un verdadero desastre. El conjunto de prueba contiene solo datos de tweets y no valores objetivo. La tarea es predecir si un tweet representa un desastre real o no.
Consulte este documento escrito por Jeremy Howard y Sebastian Ruder si quieres leer más sobre ULMFiT.
En los problemas de visión artificial, el aprendizaje por transferencia se usa para ayudar en la clasificación directamente, pero en el caso de la PNL, primero construimos un modelo de lenguaje que básicamente predice la siguiente palabra de una oración (el modelo tiene que entender el idioma en el que está escrito el texto (por ejemplo, inglés, etc.)) y luego construya nuestro modelo de clasificación usando el codificador y el vocabulario del modelo de lenguaje.
Como se menciona en el documento, estaremos usando la Arquitectura AWD-LSTM previamente entrenada en Wikipedia. Podríamos usar directamente este modelo de lenguaje previamente entrenado para construir nuestro clasificador de tweets de desastres, pero lo esencial aquí es que el idioma inglés de Wikipedia sería diferente del idioma inglés de los tweets. Así que afinamos nuestro modelo de lenguaje previamente entrenado usando los datos del tweet y luego construiremos nuestro clasificador sobre eso. Como se explica en el Aprendizaje profundo para programadores con Fastai y PyTorch libro donde utilizaron la misma arquitectura previamente entrenada en el conjunto de datos de Reseñas de IMDb para clasificar si la reseña es positiva o negativa. Explican que el inglés de reseñas de IMDb es más informal, contiene nombres de películas, directores, actores, etc. que el inglés regular de Wikipedia en el que se ha entrenado previamente la arquitectura.
¡¡Empecemos!!
Importamos nuestro test.csv
y train.csv
para obtener nuestro conjunto de datos de entrenamiento y conjunto de datos de prueba. No puedo compartir el conjunto de datos ya que es de un concurso de Kaggle , puede descargarlo usted mismo iniciando sesión en su cuenta y cumpliendo con las reglas del concurso.
# Importing Pandas import pandas as pd# Importing fastai libraries for text and callbacks from fastai.text import * from fastai.callbacks import *train = pd.read_csv('train.csv') test = pd.read_csv('test.csv')
No entraré en detalles sobre cómo se construye el modelo de lenguaje y realmente deberías revisar el MOOC y también el Aprendizaje profundo para programadores con Fastai y PyTorch libro para lectura adicional. La idea básica es que los datos de texto no se pueden enviar directamente al modelo y es necesario convertirlos en números para que podamos aplicarle nuestras funciones matemáticas. Esto se hace usando Tokenización y Numericalización. En Tokenización, convertimos el texto en una lista de tokens y en Numericalización los convertimos en números según su índice. Debería consultar el libro si quieres sumergirte más profundo.
Usaremos el API de bloque de datos que hace lo anterior por nosotros bajo el capó y luego alimentaremos el grupo de datos creado según nuestro modelo de lenguaje.
data_lm = (TextList.from_df(pd.concat([train[['text']], test[['text']]], ignore_index=True, axis=0)) .split_by_rand_pct(0.15) .label_for_lm() .databunch(bs=128)) data_lm.show_batch()
La columna de texto muestra los datos numerados y tokenizados.
Ignoramos las etiquetas y tomamos el corpus de texto de los datos de entrenamiento y de prueba. Recuerde que estamos haciendo un modelo de lenguaje y no un modelo de clasificación en este momento. Solo incluimos datos de texto tanto como podamos para que nuestro modelo de lenguaje prediga la siguiente palabra de una oración. A continuación, usamos nuestro data_lm
databunch para hacer nuestro modelo de lenguaje.
learn = language_model_learner(data_lm, AWD_LSTM, drop_mult = 0.5) learn.lr_find() learn.recorder.plot(suggestion = True)
learn.fit_one_cycle(1, 1e-2, moms=(0.8,0.7))
Descongelaremos el modelo y ajustaremos más. Usaremos devoluciones de llamada para seleccionar el mejor modelo.
Better model found at epoch 0 with accuracy value: 0.4097544550895691. Better model found at epoch 1 with accuracy value: 0.4404464364051819. Better model found at epoch 2 with accuracy value: 0.4609375. Better model found at epoch 3 with accuracy value: 0.47495537996292114. Better model found at epoch 4 with accuracy value: 0.48810267448425293. Better model found at epoch 5 with accuracy value: 0.49515628814697266. Better model found at epoch 6 with accuracy value: 0.4975222945213318. Better model found at epoch 9 with accuracy value: 0.49756699800491333.
Seleccionaremos la mejor precisión que está en la época número 9. Luego guardaremos el modelo de idioma y el codificador.
learn.save('fine_tuned') learn.save_encoder('fine_tuned_enc')
A continuación, crearemos nuestro clasificador. Para eso, necesitaremos crear un nuevo conjunto de datos. Tomaremos el conjunto de validación como 10% y mantendremos nuestro vocabulario igual que el vocabulario del conjunto de datos del idioma. También agregaremos nuestros datos de prueba en el add_test
parámetro.
data_clas = (TextList.from_df(df, vocab=data_lm.vocab) .split_by_rand_pct(0.1) .label_from_df('target') .add_test(TextList.from_df(test['text'], vocab=data_lm.vocab)) .databunch(bs=128))
Construiremos el clasificador usando el mismo codificador que nuestro modelo de lenguaje.
learn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5, metrics=[accuracy, FBeta(beta=1)]) learn.load_encoder('fine_tuned_enc')
Haremos un lr_find()
verifique y luego trace para ver el gráfico.
Encajemos un ciclo. Vemos que obtenemos una precisión de 77,66%.
learn.fit_one_cycle(1, 1e-3, moms=(0.8,0.7))
Descongelemos las últimas 2 capas y entrenemos durante un ciclo. Nuestra precisión aumenta a 79,5%.
learn.freeze_to(-2) learn.fit_one_cycle(1, slice(1e-3/(2.6**4),1e-2), moms=(0.8,0.7))
Descongelaremos las últimas 3 capas ahora y entrenaremos nuevamente para un ciclo más. Nuestra precisión aumenta a 81,73%!
learn.freeze_to(-3) learn.fit_one_cycle(1, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))
Lo que usamos aquí fueron las tasas de aprendizaje discriminativas que se introdujeron en ULMFiT. Como se explica en el artículo 10 cosas nuevas que aprendí de fast.ai v3:
Tasas de aprendizaje discriminativas para modelos previamente entrenados
Entrene capas anteriores con una tasa de aprendizaje muy baja y entrene capas posteriores con una tasa de aprendizaje más alta. La idea es no alterar drásticamente los pesos pre-entrenados casi perfectos, excepto en cantidades minúsculas, y ser más agresivo al enseñar las capas cerca de las salidas. La tasa de aprendizaje discriminativa se introdujo en ULMFiT.
Descongelaremos todas las capas, entrenaremos y usaremos devoluciones de llamada para seleccionar nuestro mejor modelo.
callbacks = SaveModelCallback(learn,monitor="accuracy", mode="max", name="best_classification_model")
Better model found at epoch 0 with accuracy value: 0.8160315155982971. Better model found at epoch 1 with accuracy value: 0.8173456192016602. Better model found at epoch 2 with accuracy value: 0.822601854801178. Better model found at epoch 9 with accuracy value: 0.8239158987998962.
Obtenemos una precisión de 82,39%!!
Conclusión
En Transfer Learning usamos el conocimiento de una fuente y lo aplicamos a nuestro objetivo. La implementación del mismo en el campo del Procesamiento del Lenguaje Natural ha proporcionado resultados extraordinarios de vanguardia con una formación mínima ya que utilizamos una red pre-entrenada. Puede consultar mi cuaderno en Kaggle si desea ver el código en acción: PNL – Predicción de desastres ULMFiT.
Gracias por leer.
Añadir comentario