Interpretación del transformador (con código pytorch)
Transformer apareció ya en 2017. No fue hasta que salió BERT que Transformer comenzó a brillar en el campo de la PNL. Actualmente, Transformer-XL (adjunto más adelante) se promociona mejor. Este artículo se centra principalmente en la interpretación de documentos y procedimientos. Si hay puntos que no están claros, corríjalos y comuníquese con ellos. Si necesita conocer más detalles, se recomienda que los escriban académicos de Shangjuechuan Tuo. La dirección de Git del programa en este artículo está aquí. Paralelice la computación para acelerar. Antes de la aparición de Transformer, la familia de redes RNN y la arquitectura de atención seq2seq + formaban básicamente la matriz de barriles de hierro para todas las tareas de PNL. Dado que el modelo de atención en sí puede ver información global, Transformer no depende en absoluto de la arquitectura RNN y solo utiliza el mecanismo de atención, logrando mejores resultados que antes en términos de paralelismo y procesamiento eficiente de información global.
La estructura de Transformer se puede ver en la Figura 1, que tiene tres módulos principales: atención de múltiples cabezales, feedforward y Add& Norm. Para obtener más información sobre cómo funciona, visite el enlace recomendado al principio.
La atención en Transformer utiliza una estructura de autoatención de múltiples cabezales, y en el codificador, dado que diferentes máscaras de entrada tienen partes diferentes, las operaciones de máscara se usan antes de softmax y la decodificación se realiza en el decodificador, porque. no puede ver los datos después del tiempo t. Las operaciones de enmascaramiento también se utilizan en la atención del primer toro, pero son diferentes. Debido a que la parte de enmascaramiento del codificador debe determinarse antes de ingresar al transformador, la primera atención de cabezales múltiples del decodificador comienza a enmascarar desde el momento t = 1 hasta el final de t = seq_len, que corresponde a la Figura 2. En la Figura 2, la abscisa representa la longitud de un lote de secuencias de entrada al decodificador (es decir, t=1), que es la longitud de la secuencia de entrada. En la Figura 2, la abscisa representa la longitud de un lote de secuencias de entrada al decodificador (es decir, t). La parte violeta es la parte enmascarada y la parte amarilla es la parte desenmascarada. Se puede ver que la parte protegida gradualmente. disminuye a medida que t aumenta. La operación de enmascaramiento de la segunda atención de cabezales múltiples en el decodificador es la misma que en el codificador.
El programa máscara + softmax es el siguiente:
La operación de máscara en realidad reemplaza la entrada no válida con un valor infinito negativo, de modo que su valor en softmax es 0 y en atención (La operación de atención se muestra en la siguiente fórmula), el resultado de la operación softmax es en realidad el peso de atención. Es decir, el peso de atención. Cuando el peso de atención es 0, significa que no es necesario prestar atención a la información de posición.
Para la implementación de la atención de múltiples cabezales, no es como el artículo original, que implementa múltiples atenciones una por una, y luego concatena los resultados finales y los genera a través del peso de salida. Los siguientes programas y fórmulas explican el proceso de implementación real. Aquí se supone que tienen la misma fuente, ambos y sus dimensiones son [batch_size, seq_len, input_size]. (Cabe señalar que la entrada del segundo Multi-Head en el decodificador es diferente a la fuente)
Primero, para la entrada, , , obtenemos, , , a través de tres variables de peso, en este En ese momento, las dimensiones de los tres son las mismas, todas son [batch, seq_len, d_model], y luego realizamos la transformación de dimensiones: [batch, seq_len, h, d_model//h] ==> [batch, h, seq_len , d]==>[batch×h, seq_len, d], donde d=d_model//h, entonces se transforma, y se usa directamente como DotProductAttention para lograr la atención de múltiples cabezales. Al final, solo las dimensiones de. la salida de DotProductAttention debe transformarse nuevamente y luego multiplicarse por el peso de salida.
El parámetro valid_length se ha explicado en detalle en el programa, por lo que no entraré en detalles aquí. Tenga en cuenta que la entrada valid_length es para la dimensión del lote y, en operaciones reales, la dimensión del lote X cambia (de lote a lote × h). ), por lo que es necesario copiar la longitud de valid_length.
La implementación de FFN es muy sencilla, de hecho basta con aplicar una primera transformación lineal a la entrada, añadir una función de activación ReLU a su salida y luego aplicar una segunda transformación lineal.
La implementación de Add&norm es utilizar la red residual para conectarse y finalmente conectar los resultados de la conexión a LN. Vale la pena señalar que el programa agregará regularización de abandono a la salida de Y.
La implementación de la codificación posicional es muy simple. En realidad, utiliza sin y cos para codificar posicionalmente la secuencia de entrada dadas posiciones únicas, donde sin maneja posiciones pares y cos maneja posiciones impares. Sin embargo, esta parte del trabajo es realmente muy importante, porque el contenido principal de la secuencia es información de posición, y BERT obviamente no utiliza codificación de posición (aunque hay una entrada de inserción de posición en el documento BERT, obviamente no es la posición información que se describirá en el transformador), por lo que BERT no utilizará codificación posicional.
Las mejoras posteriores a BERT se reflejan en XLNet (adoptando la estructura Transformer-XL), que se presentará en capítulos posteriores.
El codificador y el decodificador en realidad están apilados por los tres módulos básicos anteriores. Para obtener detalles de implementación específicos, consulte la dirección de git al principio. Entre ellos, se debe enfatizar lo siguiente:
<. p> En Los programas que aparecen en git están todos al comienzo del programa. Puede ejecutar el programa ejecutando directamente main.ipynb. De lo contrario, consulte los siguientes puntos. El programa aparece al comienzo de git y puede ejecutarlo ejecutando directamente main.ipynb.