El ABC de los Transformers Todo lo que necesitas saber

El ABC de los Transformers Todo lo que necesitas saber

Todo lo que necesitas saber sobre los Transformers y cómo implementarlos

Imagen de autor

¿Por qué otro tutorial sobre los Transformers?

Probablemente ya hayas escuchado hablar sobre los Transformers, y todo el mundo habla de ello, ¿entonces por qué hacer un nuevo artículo al respecto?

Bueno, soy investigador, y esto me exige tener un conocimiento muy profundo de las herramientas que utilizo (porque si no las entiendes, ¿cómo puedes identificar dónde están equivocadas y cómo mejorarlas, verdad?).

A medida que me adentraba más en el mundo de los Transformers, me encontré sepultado bajo una montaña de recursos. Y sin embargo, a pesar de toda esa lectura, me quedé con una idea general de la arquitectura y con una serie de preguntas persistentes.

En esta guía, mi objetivo es llenar esa brecha de conocimiento. Una guía que te dará una sólida intuición sobre los Transformers, una inmersión profunda en la arquitectura y la implementación desde cero.

Te recomiendo encarecidamente que sigas el código en Github:

awesome-ai-tutorials/NLP/007 – Transformers From Scratch at main ·…

La mejor colección de tutoriales de IA para convertirte en un experto de la Ciencia de Datos. – awesome-ai-tutorials/NLP/007 – Transformers…

github.com

¡Disfruta! 🤗

Un poco de historia primero:

Muchos atribuyen el concepto del mecanismo de atención al renombrado artículo “Atención es todo lo que necesitas” del equipo de Google Brain. Sin embargo, esto es solo una parte de la historia.

Las raíces del mecanismo de atención se remontan a un artículo anterior titulado “Traducción Neural Automática mediante Alineación y Traducción Conjunta” escrito por Dzmitry Bahdanau, KyungHyun Cho y Yoshua Bengio.

El principal desafío de Bahdanau era abordar las limitaciones de las Redes Neuronales Recurrentes (RNNs). Específicamente, al codificar frases largas en vectores utilizando RNNs, a menudo se perdía información crucial.

Tomando como referencia los ejercicios de traducción, donde uno a menudo vuelve a visitar la oración de origen mientras traduce, Bahdanau buscó asignar pesos a los estados ocultos dentro de la RNN. Este enfoque produjo resultados impresionantes, como se muestra en el siguiente diagrama.

Imagen del artículo 'Traducción Neural Automática mediante Alineación y Traducción Conjunta'

Sin embargo, Bahdanau no fue el único abordando este problema. Inspirándose en su trabajo innovador, el equipo de Google Brain planteó una idea audaz:

“¿Por qué no eliminar todo y centrarse únicamente en el mecanismo de atención?”

Ellos creían que no era la RNN sino el mecanismo de atención el que impulsaba el éxito.

Esta convicción culminó en su artículo, adecuadamente titulado “Atención es todo lo que necesitas”.

¡Fascinante, ¿verdad?

La arquitectura Transformer

1. Lo primero, los Embeddings

Este diagrama representa la arquitectura Transformer. No te preocupes si al principio no entiendes nada, lo cubriremos absolutamente todo.

Incrustaciones, Imagen del artículo modificada por el autor

De texto a vectores: el proceso de incrustación. Imagina que nuestra entrada es una secuencia de palabras, digamos “El gato bebe leche”. Esta secuencia tiene una longitud denominada seq_len. Nuestra tarea inmediata es convertir estas palabras en una forma comprensible para el modelo, específicamente vectores. Ahí es donde entra en juego el incrustador.

Cada palabra sufre una transformación para convertirse en un vector. Este proceso de transformación se denomina ‘incrustación’. Cada uno de estos vectores o ‘incrustaciones’ tiene un tamaño de d_model = 512.

Ahora, ¿qué es exactamente este incrustador? En su núcleo, el incrustador es un mapeo lineal (matriz), denotado por E. Puedes visualizarlo como una matriz de tamaño (d_model, vocab_size), donde vocab_size es el tamaño de nuestro vocabulario.

Después del proceso de incrustación, obtenemos una colección de vectores cada uno con un tamaño de d_model. Es crucial entender este formato, ya que es un tema recurrente y lo veremos en diversas etapas como la entrada del codificador, salida del codificador, etc.

Codifiquemos esta parte:

class Embeddings(nn.Module):    def __init__(self, d_model, vocab):        super(Embeddings, self).__init__()        self.lut = nn.Embedding(vocab, d_model)        self.d_model = d_model    def forward(self, x):        return self.lut(x) * math.sqrt(self.d_model)

Nota: multiplicamos por d_model por fines de normalización (explicado posteriormente)

Nota 2: personalmente me pregunté si usamos un incrustador pre-entrenado, o al menos empezamos desde uno pre-entrenado y lo afinamos. Pero no, la incrustación se aprende completamente desde cero y se inicializa aleatoriamente.

Codificación Posicional

¿Por qué necesitamos la codificación posicional?

Dado nuestro arreglo actual, tenemos una lista de vectores que representan palabras. Si los alimentamos así al modelo de transformador, hay un elemento clave que falta: el orden secuencial de las palabras. Las palabras en los lenguajes naturales a menudo obtienen significado a partir de su posición. “Juan ama a María” tiene un sentimiento diferente a “María ama a Juan”. Para asegurar que nuestro modelo capture este orden, introducimos la codificación posicional.

Ahora, te puedes preguntar, “¿Por qué no simplemente agregar un incremento simple como +1 para la primera palabra, +2 para la segunda, y así sucesivamente?” Hay varios desafíos con este enfoque:

  1. Multidimensionalidad: Cada token se representa en 512 dimensiones. Un simple incremento no sería suficiente para capturar este espacio complejo.
  2. Preocupaciones de normalización: Idealmente, queremos que nuestros valores estén entre -1 y 1. Por lo tanto, agregar directamente números grandes (como +2000 para un texto largo) sería problemático.
  3. Dependencia de la longitud de la secuencia: El uso de incrementos directos no es agnóstico a la escala. Para un texto largo, donde la posición puede ser +5000, este número no refleja verdaderamente la posición relativa del token en su oración asociada. Y el significado de una palabra depende más de su posición relativa en una oración que de su posición absoluta en un texto.

Si estudiaste matemáticas, la idea de coordenadas circulares – específicamente funciones seno y coseno – debería resonar con tu intuición. Estas funciones proporcionan una forma única de codificar la posición que cumple nuestras necesidades.

Dado nuestra matriz de tamaño (seq_len, d_model), nuestro objetivo es agregar otra matriz, la Codificación Posicional, del mismo tamaño.

Aquí está el concepto principal:

  1. Para cada token, los autores sugieren proporcionar una coordenada seno a las dimensiones pares (2k) y una coordenada coseno a las dimensiones impares (2k+1).
  2. Si fijamos la posición del token y movemos la dimensión, podemos ver que el seno/coseno disminuye en frecuencia.
  3. Si observamos un token que está más lejos en el texto, este fenómeno ocurre más rápidamente (la frecuencia aumenta).
Imagen del artículo

Todo esto se resume en el siguiente gráfico (pero no te rompas mucho la cabeza con esto). La clave es que la Codificación Posicional es una función matemática que permite al Transformer mantener una idea del orden de los tokens en la oración. Es un área de investigación muy activa.

Incrustación posicional, imagen del autor
class PositionalEncoding(nn.Module):    "Implementa la función PE."    def __init__(self, d_model, dropout, max_len=5000):        super(PositionalEncoding, self).__init__()        self.dropout = nn.Dropout(p=dropout)        # Calcula las codificaciones posicionales una vez en escala logarítmica.        pe = torch.zeros(max_len, d_model)        position = torch.arange(0, max_len).unsqueeze(1)        div_term = torch.exp(            torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model)        )        pe[:, 0::2] = torch.sin(position * div_term)        pe[:, 1::2] = torch.cos(position * div_term)        pe = pe.unsqueeze(0)        self.register_buffer("pe", pe)    def forward(self, x):        x = x + self.pe[:, : x.size(1)].requires_grad_(False)        return self.dropout(x)

El Mecanismo de Atención (Cabeza Única)

Sumerjámonos en el concepto principal del artículo de Google: el Mecanismo de Atención

Intuición de Alto Nivel:

En su esencia, el mecanismo de atención es un mecanismo de comunicación entre vectores/tokens. Permite que un modelo se centre en partes específicas de la entrada al producir una salida. Piénsalo como si pusieras un foco de atención en ciertas partes de tus datos de entrada. Este “foco de atención” puede ser más brillante en partes más relevantes (dándoles más atención) y más tenue en partes menos relevantes.

Para una oración, la atención ayuda a determinar la relación entre las palabras. Algunas palabras están estrechamente relacionadas entre sí en significado o función dentro de una oración, mientras que otras no lo están. El mecanismo de atención cuantifica estas relaciones.

Ejemplo:

Considera la oración: “Ella le dio su libro.”

Si nos enfocamos en la palabra “su”, el mecanismo de atención podría determinar que:

  • Tiene una fuerte conexión con “libro” porque “su” indica posesión del “libro”.
  • Tiene una conexión de igual a igual con “Ella” porque “Ella” y “su” probablemente se refieren a la misma entidad.
  • Tiene una conexión más débil con otras palabras como “dio” o “le”.

Profundización Técnica en el mecanismo de atención

Atención con Producto Escalar, imagen del artículo

Para cada token, generamos tres vectores:

  1. Consulta (Q):

Intuición: Piensa en la consulta como una “pregunta” que un token hace. Representa la palabra actual e intenta descubrir qué partes de la secuencia son relevantes para ella.

2. Clave (K):

Intuición: La clave puede considerarse una “identificación” para cada palabra en la secuencia. Cuando la consulta “hace” su pregunta, la clave ayuda a “responder” al determinar qué tan relevante es cada palabra de la secuencia para la consulta.

3. Valor (V):

Intuición: Una vez determinada la relevancia de cada palabra (a través de su clave) para la consulta, necesitamos información o contenido real de esas palabras para ayudar al token actual. Aquí es donde entra en juego el valor. Representa el contenido de cada palabra.

¿Cómo se generan Q, K, V?

Q, K, V generation, image by author

La similitud entre una consulta y una clave es un producto punto (mide la similitud entre 2 vectores), dividido por la desviación estándar de esta variable aleatoria, para normalizar todo.

Fórmula de atención, Imagen del artículo

Vamos a ilustrar esto con un ejemplo:

Imaginemos que tenemos una consulta y queremos determinar el resultado de la atención con K y V:

Q, K, V, Imagen del autor

Ahora calculemos las similitudes entre q1 y las claves:

Producto punto, Imagen del autor

Aunque los números 3/2 y 1/8 podrían parecer relativamente cercanos, la naturaleza exponencial de la función softmax amplificaría su diferencia.

Pesos de atención, Imagen del autor

Esta diferencia sugiere que q1 tiene una conexión más pronunciada con k1 que con k2.

Ahora veamos el resultado de la atención, que es una combinación ponderada (pesos de atención) de los valores:

Atención, Imagen del autor

¡Genial! Repitiendo esta operación para cada token (q1 a través de qn) obtenemos una colección de n vectores.

En la práctica, esta operación se vectoriza en una multiplicación matricial para mayor eficacia.

Codifiquémoslo:

def attention(query, key, value, mask=None, dropout=None):    "Calcular 'Atención de Producto Punto Escalada'"    d_k = query.size(-1)    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)    if mask is not None:        scores = scores.masked_fill(mask == 0, -1e9)    p_attn = scores.softmax(dim=-1)    if dropout is not None:        p_attn = dropout(p_attn)    return torch.matmul(p_attn, value), p_attn

Atención Multidimensional

¿Cuál es el problema con la atención de un solo cabezal?

Con el enfoque de atención de un solo cabezal, cada token puede formular solo una consulta. Esto suele traducirse en que establece una relación fuerte con solo otro token, dado que softmax tiende a dar mucho peso a un valor mientras que reduce otros cercanos a cero. Sin embargo, al pensar en el lenguaje y las estructuras de las oraciones, una palabra a menudo tiene conexiones con múltiples palabras, no solo una.

Para abordar esta limitación, introducimos atención multi-cabeza. ¿La idea principal? Permitamos que cada token haga varias preguntas (consultas) simultáneamente ejecutando el proceso de atención en paralelo ‘h’ veces. El Transformer original utiliza 8 cabezas.

Atención multi-cabeza, imagen del artículo

Una vez que obtenemos los resultados de las 8 cabezas, los concatenamos en una matriz.

Atención multi-cabeza, imagen del artículo

Esto también es sencillo de codificar, solo debemos tener cuidado con las dimensiones:

class MultiHeadedAttention(nn.Module):    def __init__(self, h, d_model, dropout=0.1):        "Toma el tamaño del modelo y el número de cabezas."        super(MultiHeadedAttention, self).__init__()        assert d_model % h == 0        # Asumimos que d_v siempre es igual a d_k        self.d_k = d_model // h        self.h = h        self.linears = clones(nn.Linear(d_model, d_model), 4)        self.attn = None        self.dropout = nn.Dropout(p=dropout)    def forward(self, query, key, value, mask=None):        "Implementa la Figura 2"        if mask is not None:            # Máscara aplicada a todas las cabezas h.            mask = mask.unsqueeze(1)        nbatches = query.size(0)        # 1) Realiza todas las proyecciones lineales en lote de d_model => h x d_k        query, key, value = [            lin(x).view(nbatches, -1, self.h, self.d_k).transpose(1, 2)            for lin, x in zip(self.linears, (query, key, value))        ]        # 2) Aplica la atención en todos los vectores proyectados en lote.        x, self.attn = attention(query, key, value, mask=mask, dropout=self.dropout)        # 3) "Concatena" utilizando una vista y aplica una proyección lineal final.        x = x.transpose(1, 2).contiguous().view(nbatches, -1, self.h * self.d_k)        del query        del key        del value        return self.linears[-1](x)

Ahora deberías empezar a entender por qué los Transformers son tan poderosos, aprovechan al máximo el paralelismo.

Ensamblaje de las partes del Transformer

En términos generales, un Transformer es la combinación de 3 elementos: un Codificador, un Decodificador y un Generador

Codificador, Decodificador, Generador, Imagen del artículo modificada por el autor

1. El Codificador

  • Propósito: Convertir una secuencia de entrada en una nueva secuencia (por lo general, de menor dimensión) que capture la esencia de los datos originales.
  • Nota: Si has oído hablar del modelo BERT, utiliza solo esta parte de codificación del Transformer.

2. El Decodificador

  • Propósito: Generar una secuencia de salida utilizando la secuencia codificada del Codificador.
  • Nota: El decodificador en el Transformer es diferente del decodificador típico de un autoencoder. En el Transformer, el decodificador no solo considera la salida codificada, sino que también tiene en cuenta los tokens que ha generado hasta ahora.

3. El Generador

  • Propósito: Convertir un vector en un token. Hace esto proyectando el vector al tamaño del vocabulario y luego seleccionando el token más probable con la función softmax.

Vamos a codificar eso:

class EncoderDecoder(nn.Module):    """    Una arquitectura estándar de codificador-decodificador. Base para este y muchos    otros modelos.    """    def __init__(self, encoder, decoder, src_embed, tgt_embed, generator):        super(EncoderDecoder, self).__init__()        self.encoder = encoder        self.decoder = decoder        self.src_embed = src_embed        self.tgt_embed = tgt_embed        self.generator = generator    def forward(self, src, tgt, src_mask, tgt_mask):        "Tomar y procesar secuencias de origen y objetivo enmascaradas."        return self.decode(self.encode(src, src_mask), src_mask, tgt, tgt_mask)    def encode(self, src, src_mask):        return self.encoder(self.src_embed(src), src_mask)    def decode(self, memory, src_mask, tgt, tgt_mask):        return self.decoder(self.tgt_embed(tgt), memory, src_mask, tgt_mask)class Generator(nn.Module):    "Definir el paso de generación estándar lineal + softmax."    def __init__(self, d_model, vocab):        super(Generator, self).__init__()        self.proj = nn.Linear(d_model, vocab)    def forward(self, x):        return log_softmax(self.proj(x), dim=-1)

Una observación aquí: “src” se refiere a la secuencia de entrada, y “tgt” se refiere a la secuencia que se está generando. Recuerda que generamos la salida de manera autoregresiva, token por token, por lo que también necesitamos hacer un seguimiento de la secuencia objetivo.

Apilando codificadores

El codificador del Transformer no es solo una capa. En realidad, es una pila de N capas. Específicamente:

  • El codificador en el modelo original del Transformer consta de una pila de N=6 capas idénticas.

Dentro de la capa de codificación, podemos ver que hay dos bloques de subcapas muy similares ((1) y (2)): Una conexión residual seguida de una normalización de capa.

  • Bloque (1): Mecanismo de autoatención: Ayuda al codificador a enfocarse en diferentes palabras de la entrada al generar la representación codificada.
  • Bloque (2): Red neuronal de alimentación directa: Una pequeña red neuronal aplicada de manera independiente a cada posición.
Capa de codificación, conexiones residuales y normalización de capa, imagen del artículo modificada por el autor

Ahora vamos a codificar eso:

Primero, la Conexión de Subcapa:

Seguimos la arquitectura general y podemos cambiar “subcapa” por “autoatención” o “FFN”

class SublayerConnection(nn.Module):    """    Una conexión residual seguida de una normalización de capa.    Nota: para simplificar el código, la normalización se realiza primero en lugar de al final.    """    def __init__(self, size, dropout):        super(SublayerConnection, self).__init__()        self.norm = nn.LayerNorm(size)  # Usar LayerNorm de PyTorch        self.dropout = nn.Dropout(dropout)    def forward(self, x, sublayer):        "Aplicar la conexión residual a cualquier subcapa con el mismo tamaño."        return x + self.dropout(sublayer(self.norm(x)))

Ahora podemos definir la capa completa del codificador:

class EncoderLayer(nn.Module):    "El codificador se compone de autoatención y alimentación directa (definidas a continuación)"    def __init__(self, size, self_attn, feed_forward, dropout):        super(EncoderLayer, self).__init__()        self.self_attn = self_attn        self.feed_forward = feed_forward        self.sublayer = clones(SublayerConnection(size, dropout), 2)        self.size = size    def forward(self, x, mask):        # autoatención, bloque 1        x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))        # alimentación directa, bloque 2        x = self.sublayer[1](x, self.feed_forward)        return x

La capa del codificador está lista, ahora solo tenemos que unirlas para formar el codificador completo:

def clones(module, N):    "Producir N capas idénticas."    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])class Encoder(nn.Module):    "El codificador principal es una pila de N capas"    def __init__(self, layer, N):        super(Encoder, self).__init__()        self.layers = clones(layer, N)        self.norm = nn.LayerNorm(layer.size)    def forward(self, x, mask):        "Pasar la entrada (y máscara) a través de cada capa sucesivamente."        for layer in self.layers:            x = layer(x, mask)        return self.norm(x)

Decodificador

El decodificador, al igual que el codificador, está estructurado con múltiples capas idénticas apiladas una encima de la otra. El número de estas capas es típicamente 6 en el modelo Transformer original.

¿Cómo se diferencia el decodificador del codificador?

Se agrega una tercera subcapa para interactuar con el codificador: esto es Atención Cruzada

  • La subcapa (1) es la misma que la del codificador. Es el mecanismo de Autoatención, lo que significa que generamos todo (Q, K, V) a partir de los tokens dados al decodificador
  • La subcapa (2) es el nuevo mecanismo de comunicación: Atención Cruzada. Se llama así porque usamos la salida de la subcapa (1) para generar las Consultas, y usamos la salida del codificador para generar las Claves y Valores (K, V). En otras palabras, para generar una oración, debemos mirar tanto lo que hemos generado hasta ese momento por el decodificador (autoatención), como lo que preguntamos en primer lugar en el codificador (atención cruzada)
  • La subcapa (3) es idéntica a la del codificador.
Capa del decodificador, autoatención, atención cruzada, imagen del artículo modificada por el autor

Ahora codifiquemos la Capa del Decodificador. Si entendiste el mecanismo en la Capa del Codificador, esto debería ser bastante sencillo.

class DecoderLayer(nn.Module):    "El decodificador está formado por autoatención, atención al origen y retroalimentación (definidos a continuación)"    def __init__(self, size, self_attn, src_attn, feed_forward, dropout):        super(DecoderLayer, self).__init__()        self.size = size        self.self_attn = self_attn        self.src_attn = src_attn        self.feed_forward = feed_forward        self.sublayer = clones(SublayerConnection(size, dropout), 3)    def forward(self, x, memory, src_mask, tgt_mask):        "Sigue la Figura 1 (derecha) para las conexiones."        m = memory        x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, tgt_mask))        # Nueva subcapa (atención cruzada)        x = self.sublayer[1](x, lambda x: self.src_attn(x, m, m, src_mask))        return self.sublayer[2](x, self.feed_forward)

Y ahora podemos encadenar las N=6 Capas del Decodificador para formar el Decodificador:

class Decoder(nn.Module):    "Decodificador de N capas genérico con enmascaramiento."    def __init__(self, layer, N):        super(Decoder, self).__init__()        self.layers = clones(layer, N)        self.norm = nn.LayerNorm(layer.size)    def forward(self, x, memory, src_mask, tgt_mask):        for layer in self.layers:            x = layer(x, memory, src_mask, tgt_mask)        return self.norm(x)

En este punto, has entendido alrededor del 90% de lo que es un Transformer. Aún quedan algunos detalles:

Detalles del Modelo Transformer

Relleno:

  • En un Transformer típico, hay una longitud máxima para las secuencias (por ejemplo, “max_len=5000”). Esto define la secuencia más larga que el modelo puede manejar.
  • Sin embargo, las oraciones del mundo real pueden variar en longitud. Para manejar oraciones más cortas, utilizamos relleno.
  • El relleno es la adición de “tokens de relleno” especiales para que todas las secuencias de un lote tengan la misma longitud.
Relleno, imagen del autor

Enmascaramiento

El enmascaramiento asegura que durante el cálculo de la atención, ciertos tokens sean ignorados.

Dos escenarios para el enmascaramiento:

  • enmascarado de src: Como hemos añadido tokens de relleno a las secuencias, no queremos que el modelo preste atención a estos tokens insignificantes. Por lo tanto, los enmascaramos.
  • enmascarado de tgt o Enmascaramiento progresivo/causal: En el decodificador, al generar tokens secuencialmente, cada token solo debe ser influenciado por los tokens anteriores y no por los futuros. Por ejemplo, al generar la quinta palabra de una oración, no debería conocer la sexta palabra. Esto asegura una generación secuencial de tokens.
Encubrimiento causal/encubrimiento posterior, imagen del autor

Luego usamos esta máscara para agregar menos infinito para que el token correspondiente sea ignorado. Este ejemplo debería aclarar las cosas:

Encubrimiento, un truco en el softmax, imagen del autor

FFN: Red Neuronal de Avance

  • La capa “Avance” en el diagrama del Transformador es un poco engañosa. No es solo una operación, sino una secuencia de ellas.
  • El FFN consta de dos capas lineales. Curiosamente, los datos de entrada, que podrían tener una dimensión d_model=512, primero se transforman en una dimensión más alta d_ff=2048 y luego se mapean nuevamente a su dimensión original (d_model=512).
  • Esto se puede visualizar como si los datos se “expandieran” en medio de la operación antes de ser “comprimidos” nuevamente a su tamaño original.
Imagen del artículo modificada por el autor

Esto es fácil de codificar:

class PositionwiseFeedForward(nn.Module):    "Implementa la ecuación de FFN."    def __init__(self, d_model, d_ff, dropout=0.1):        super(PositionwiseFeedForward, self).__init__()        self.w_1 = nn.Linear(d_model, d_ff)        self.w_2 = nn.Linear(d_ff, d_model)        self.dropout = nn.Dropout(dropout)    def forward(self, x):        return self.w_2(self.dropout(self.w_1(x).relu()))

Conclusión

El éxito incomparable y la popularidad del modelo Transformador se pueden atribuir a varios factores clave:

  1. Flexibilidad. Los Transformers pueden trabajar con cualquier secuencia de vectores. Estos vectores pueden ser incrustaciones de palabras. Es fácil transponer esto a la Visión por Computadora convirtiendo una imagen en diferentes fragmentos y desplegando un fragmento en un vector. Incluso en Audio, podemos dividir un audio en diferentes fragmentos y vectorizarlos.
  2. Generalidad: Con un sesgo inductivo mínimo, el Transformador es libre de capturar patrones intrincados y matizados en los datos, lo que le permite aprender y generalizar mejor.
  3. Rapidez y Eficiencia: Aprovechando el inmenso poder computacional de las GPUs, los Transformers están diseñados para un procesamiento paralelo.

¡Gracias por leer! Antes de que te vayas:

Puedes ejecutar los experimentos con mi Repositorio de Transformadores en Github.

Para obtener más tutoriales increíbles, revisa mi compilación de tutoriales de AI en Github

GitHub — FrancoisPorcher/awesome-ai-tutorials: La mejor colección de tutoriales de IA para convertirte en un…

La mejor colección de tutoriales de IA para convertirte en un jefe de Ciencia de Datos — GitHub …

github.com

Deberías recibir mis artículos en tu bandeja de entrada. Suscríbete aquí.

Si quieres tener acceso a artículos premium en VoAGI, solo necesitas una membresía por $5 al mes. Si te registras con mi enlace, me estarás apoyando con una parte de tu tarifa sin costos adicionales.

Si encontraste este artículo esclarecedor y beneficioso, ¡considera seguirme y dejar una palmada para obtener más contenido en profundidad! Tu apoyo me ayuda a continuar produciendo contenido que contribuye a nuestra comprensión colectiva.

Referencias

Para profundizar más

Incluso con una guía completa, hay muchas otras áreas relacionadas con los Transformers. Aquí hay algunas ideas que quizás quieras explorar:

  • Codificación Posicional: se han realizado mejoras significativas, puedes revisar “Relative positional Encoding” y “Rotary Positional Embedding (RoPE)”
  • Layer Norm, y las diferencias con batch norm, group norm
  • Conexiones Residuales, y su efecto en suavizar el gradiente
  • Mejoras realizadas a BERT (Roberta, ELECTRA, Camembert)
  • Destilación de modelos grandes en modelos más pequeños
  • Aplicaciones de Transformers en otros campos (principalmente visión y audio)
  • El vínculo entre Transformers y Redes Neuronales de Grafos

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

¿De quién es la responsabilidad de hacer que la IA generativa sea correcta?

Las posibilidades ilimitadas de la tecnología que trasciende fronteras.

Ciencia de Datos

La Inteligencia Artificial ayuda a mostrar cómo fluyen los líquidos del cerebro.

Un equipo de científicos creó mediciones de velocimetría basadas en inteligencia artificial para cuantificar el flujo...

Inteligencia Artificial

Meta AI anuncia Purple Llama para ayudar a la comunidad a construir de manera ética con modelos de IA abiertos y generativos.

Gracias al éxito en el aumento de los datos, el tamaño del modelo y la capacidad computacional para la modelización d...

Inteligencia Artificial

Asistentes de correo electrónico AI más valorados (noviembre de 2023)

Translate this html (keep the html code in the result) to Spanish: Los asistentes de correo electrónico de inteligenc...

Inteligencia Artificial

Investigadores de China proponen iTransformer Repensando la arquitectura Transformer para una mejora en la previsión de series temporales

El Transformer se ha convertido en el modelo básico que se adhiere a la regla de escalado después de alcanzar un gran...