Sería ideal si el mundo de las redes neuronales representara una relación uno a uno: cada neurona se activa en una y sólo una característica. En un mundo así, interpretar el modelo sería sencillo: esta neurona se activa para la característica de la oreja de perro y esa neurona se activa para la rueda de los automóviles. Lamentablemente, ese no es el caso. En realidad, un modelo con dimensión. d a menudo necesita representar metro características, donde re < m. Es entonces cuando observamos el fenómeno de la superposición.
En el contexto del aprendizaje automático, la superposición se refiere a un fenómeno específico en el que una neurona en un modelo representa múltiples características superpuestas en lugar de una única y distinta. Por ejemplo, InceptionV1 contiene una neurona que responde a las caras de los gatos, los frentes de los automóviles y las patas de los gatos. [1]. Esto lleva a que podamos superponer diferentes características de activación en una misma neurona o circuito.
La existencia de superposición hace que la explicabilidad del modelo sea un desafío, especialmente en los modelos de aprendizaje profundo, donde las neuronas en capas ocultas representan combinaciones complejas de patrones en lugar de estar asociadas con características simples y directas.
En esta publicación de blog, presentaremos un ejemplo simple de superposición, con implementaciones detalladas de Python en este computadora portátil.
Comenzamos esta sección analizando el término «característica».
En los datos tabulares, hay poca ambigüedad al definir qué es una característica. Por ejemplo, al predecir la calidad del vino utilizando un conjunto de datos tabulares, las características pueden ser el porcentaje de alcohol, el año de producción, etc.
Sin embargo, definir características puede volverse complejo cuando se trata de datos no tabulares, como imágenes o datos textuales. En estos casos, no existe una definición universalmente aceptada de característica. En términos generales, una característica puede considerarse cualquier propiedad de la entrada que sea reconocible para la mayoría de los humanos. Por ejemplo, una característica en un modelo de lenguaje grande (LLM) podría ser si una palabra está en francés.
La superposición ocurre cuando el número de características es mayor que las dimensiones del modelo. Afirmamos que deben cumplirse dos condiciones necesarias para que se produzca la superposición:
- No linealidad: Las redes neuronales suelen incluir funciones de activación no lineales, como sigmoide o ReLU, al final de cada capa oculta. Estas funciones de activación brindan a la red posibilidades de asignar entradas a salidas de forma no lineal, de modo que pueda capturar relaciones más complejas entre características. Podemos imaginar que sin no linealidad, el modelo se comportaría como una simple transformación lineal, donde las características permanecen linealmente separables, sin ninguna posibilidad de compresión de dimensiones mediante superposición.
- Escasez de funciones: La escasez de características significa el hecho de que solo un pequeño subconjunto de características es distinto de cero. Por ejemplo, en los modelos de idiomas, muchas características no están presentes al mismo tiempo: por ejemplo, una misma palabra no puede ser es_francés y es_otros_idiomas. Si todas las características fueran densas, podemos imaginar una interferencia importante debido a la superposición de representaciones, lo que haría muy difícil para el modelo decodificar características.
Conjunto de datos sintéticos
Consideremos un ejemplo de juguete de 40 características con una importancia de característica decreciente linealmente: la primera característica tiene una importancia de 1, la última característica tiene una importancia de 0,1 y la importancia de las características restantes está espaciada uniformemente entre estos dos valores.
Luego generamos un conjunto de datos sintéticos con el siguiente código:
def generate_sythentic_dataset(dim_sample, num_sapmple, sparsity):
"""Generate synthetic dataset according to sparsity"""
dataset=[]
for _ in range(num_sapmple):
x = np.random.uniform(0, 1, n)
mask = np.random.choice([0, 1], size=n, p=[sparsity, 1 - sparsity])
x = x * mask # Apply sparsity
dataset.append(x)
return np.array(dataset)
Esta función crea un conjunto de datos sintéticos con el número dado de dimensiones, que es 40 en nuestro caso. Para cada dimensión, se genera un valor aleatorio a partir de una distribución uniforme en [0, 1]. El parámetro de dispersión, que varía entre 0 y 1, controla el porcentaje de funciones activas en cada muestra. Por ejemplo, cuando la escasez es 0,8, las características de cada muestra tienen un 80% de posibilidades de ser cero. La función aplica una matriz de máscara para realizar la configuración de escasez.
Modelos lineales y Relu
Ahora nos gustaría explorar cómo los modelos neuronales basados en ReLU conducen a la formación de superposiciones y cómo los valores de escasez cambiarían sus comportamientos.
Configuramos nuestro experimento de la siguiente manera: comprimimos las características con 40 dimensiones en el espacio de 5 dimensiones, luego reconstruimos el vector invirtiendo el proceso. Al observar el comportamiento de estas transformaciones, esperamos ver cómo se forma la superposición en cada caso.
Para ello consideramos dos modelos muy similares:
- Modelo lineal: Un modelo lineal simple con solo 5 coeficientes. Recuerde que queremos trabajar con 40 características, muchas más que las dimensiones del modelo.
- Modelo ReLU: Un modelo casi igual al lineal, pero con una función de activación ReLU adicional al final, introduciendo un nivel de no linealidad.
Ambos modelos se construyen con PyTorch. Por ejemplo, construimos el modelo ReLU con el siguiente código:
class ReLUModel(nn.Module):
def __init__(self, n, m):
super().__init__()
self.W = nn.Parameter(torch.randn(m, n) * np.sqrt(1 / n))
self.b = nn.Parameter(torch.zeros(n))def forward(self, x):
h = torch.relu(torch.matmul(x, self.W.T)) # Add ReLU activation: x (batch, n) * W.T (n, m) -> h (batch, m)
x_reconstructed = torch.relu(torch.matmul(h, self.W) + self.b) # Reconstruction with ReLU
return x_reconstructed
Según el código, el vector de entrada x de n dimensiones se proyecta en un espacio de dimensiones inferiores multiplicándolo por una matriz de peso m×n. Luego reconstruimos el vector original mapeándolo nuevamente al espacio de características original mediante una transformación ReLU, ajustada por un vector de sesgo. El modelo lineal viene dado por una estructura similar, con la única diferencia de que la reconstrucción se realiza utilizando solo la transformación lineal en lugar de ReLU. Entrenamos el modelo minimizando el error cuadrático medio entre las muestras de características originales y las reconstruidas, ponderando la importancia de la característica.
Entrenamos ambos modelos con diferentes valores de dispersión: 0,1, 0,5 y 0,9, desde menos dispersos hasta más dispersos. Hemos observado varios resultados importantes.
Primero, cualquiera que sea el nivel de escasez, los modelos ReLU «comprimen» las características mucho mejor que los modelos lineales: mientras que los modelos lineales capturan principalmente las características con mayor importancia, Los modelos ReLU podrían centrarse en características menos importantes mediante la formación de superposición– donde una única dimensión del modelo representa múltiples características. Tengamos una visión de este fenómeno en las siguientes visualizaciones: para los modelos lineales, los sesgos son más pequeños para las cinco características principales (en caso de que no lo recuerde: la importancia de la característica se define como una función linealmente decreciente basada en el orden de las características). ). Por el contrario, los sesgos del modelo ReLU no muestran este orden y generalmente se reducen más.
Otro resultado importante e interesante es que: es mucho más probable que se observe superposición cuando el nivel de escasez es alto en las características. Para tener una idea de este fenómeno, podemos visualizar la matriz W^T@W, donde W es la matriz de pesos m×n en los modelos. Se podría interpretar la matriz W^T@W como una cantidad de cómo se proyectan las características de entrada en el espacio dimensional inferior:
En particular:
- La diagonal de W^T@W representa la «auto-semejanza» de cada característica dentro del espacio transformado de baja dimensión.
- La fuera de la diagonal de la matriz representa cómo las diferentes características se correlacionan entre sí.
Ahora visualizamos los valores de W^T@W a continuación para los modelos Lineal y ReLU que hemos construido antes con dos niveles de dispersión diferentes: 0,1 y 0,9. Puede ver que cuando el valor de escasez es alto como 0,9, los elementos fuera de la diagonal se vuelven mucho más grandes en comparación con el caso en el que la escasez es 0,1 (en realidad, no se ve mucha diferencia entre los resultados de los dos modelos). Esta observación indica que las correlaciones entre diferentes características son más fáciles de aprender cuando la escasez es alta.
En esta publicación de blog, hice un experimento simple para introducir la formación de superposición en redes neuronales comparando modelos lineales y ReLU con menos dimensiones que características para representar. Observamos que la no linealidad introducida por la activación de ReLU, combinada con un cierto nivel de escasez, puede ayudar a que el modelo forme superposición.
En aplicaciones del mundo real, que son mucho más complejas que mi ejemplo navie, la superposición es un mecanismo importante para representar relaciones complejas en modelos neuronales, especialmente en modelos de visión o LLM.
[1] Acercar: una introducción a los circuitos. https://distill.pub/2020/circuits/zoom-in/
[2] Modelos de juguetes con superposición. https://transformer-circuits.pub/2022/toy_model/index.html