21  Redes neuronales de varias salidas

Una red neuronal simple con varias salidas se forma de dos o más neuronas que comparten la misma entrada y estas a su vez tienen su propia salida. Estas arquitecturas de redes propuestas por B. Widrow y llamadas MADALINE en su tiempo (Widrow y Lehr 2002), se limitan a recibir las señales de entrada redistribuyéndolas a la salida. La figura 13 muestra un diagrama extendido de la red de varias salidas para un ejemplo de tres entradas y dos salidas.

Las redes neuronales de una sola capa con varias salidas, a pesar de su simplicidad estructural, albergan una serie de ventajas que las hacen adecuadas para ciertos contextos y aplicaciones. Estas redes, por su construcción, pueden abordar simultáneamente múltiples tareas de predicción, lo que resulta especialmente útil cuando se requieren varias respuestas a partir de un mismo conjunto de datos de entrada. Imagina, por ejemplo, un sistema que, a partir de datos meteorológicos, predice no solo la probabilidad de lluvia, sino también la temperatura y la humedad; este sería un escenario ideal para implementar una red de este tipo.

Podemos descomponer la red en dos capas: la capa de entrada es la correspondiente al vector de entrada, \(X\), y una capa de salida, \(\hat{Y}\), que calcula las predicciones. Cada nodo de entrada, \(x_i\), se conecta a cada neurona de salida \(\hat{y}_j\) a través de un peso \(w_{i,j}\). A esta configuración se le denomina capa completamente conectada (fully connected) y más tarde la usaremos como bloque de construcción para las redes de varias capas.

Esta red tiene un conjunto de pesos, un conjunto de sesgos y una función de activación. Los pesos ahora los representaremos con matrices de la siguiente forma:

$$

W = \[\begin{bmatrix} w_{1,1} & \dots & w_{1,n} \ \vdots & \ddots & \vdots \ w_{m,1} & \dots & w_{m,n} \ \end{bmatrix}\]

w_{m,1} & & w_{m,n}
\end{bmatrix} $$

donde \(m\) es la cantidad de entradas y \(n\) la cantidad de salidas. Con respecto a los sesgos se requiere uno por cada salida y se especifican como: $$

B = [b_1, , b_n]$$

De esta forma el valor intermedio se especifica como: $$

H = XW + B $$

donde, \(X\) representa el vector de entradas. Note que la ecuación (#eq:H_mayus) intercambia \(X\) y \(W\) con respecto a la definición de la neurona simple, ecuación (#eq:perceptron_simple). Esto se requiere debido a la nueva definición de los pesos como matriz, delo contrario no es posible la multiplicación matricial.

Diagrama extendido de una red neuronal de varias salidas.

La capa de salida la podemos escribir de forma extendida como:

$$

{j} = f( {i=1}^{m} x_i w_{i,j} + b_j ),$$

donde \(\hat{y}_j\) es la salida de la \(j\)-ésima neurona. O podemos escribir de forma simplificada usando notación matricial:

$$

= f(H) = \[\begin{bmatrix} f(h_1) \ \vdots \ f(h_n) \ \end{bmatrix}\]

f(h_n)
\end{bmatrix}

$$

ahora, la función de activación recibe el vector intermedio, y retorna las activaciones o logits. La función retorna tantas activaciones como entradas haya tenido, este comportamiento se conoce como broadcasting de una función. Es observable de la ecuación anterior que la misma función de activación se aplica a todas las salidas.

Ejemplo

Suponga una red neuronal de una capa con dos nodos de entrada y dos salidas. Cada salida utiliza la función de activación sigmoide. Observe el siguiente diagrama:

image

donde $$

X=[8, 4],\[ \]

W= \[\begin{bmatrix} -0.1 & 0.6 \ -0.8 & 0.3, \ \end{bmatrix}\]


\end{bmatrix}\[ \]

B=[-0.7, 0.3]$$

Calcule la salida de la red.

SOLUCION: Siguiendo la ecuación (#eq:H_mayus) obtenemos: $$

H = [8, 4] \[\begin{bmatrix} -0.1 & 0.6 \ -0.8 & 0.3, \ \end{bmatrix}\]


\end{bmatrix} + [-0.7, 0.3]\[ \]

H = [-7.7, 6.3]$$

a continuación se pasa por la función de activación, ecuación (#eq:salida_multiple), que en este caso se instancia como la función sigmoide, se obtiene: $$

= [4.52^{-4}, 9.81^{-1}]$$

21.1 Parámetros

Con respecto a la cantidad de parámetros esta se incrementará tantas veces como salidas tenga la red. Por lo tanto, para las redes neuronales con varias salidas la cantidad de parámetros se calcula como: $$

|| = (m + 1) n,$$

donde \(m\) es la cantidad de nodos de entrada y \(n\) la de nodos de salida.

21.2 Implementación capa lineal

Para implementar una red simple de varias salidas la implementaremos a través de dos clases, una clase base que nos servirá después para implementar otras redes y una clase Lineal, hemos seleccionado el nombre lineal debido a que así se conoce en muchos frameworks de trabajo.

La clase base está implementada como una clase abstracta llamada Modelo, la cual hereda de ABC. Su función es establecer una estructura común para todos los componentes de la red, definiendo un contador de parámetros inicializado en cero y obligando a cualquier subclase a implementar el método forward(self, X), garantizando así la consistencia en el flujo de datos hacia adelante.

# clase base abstracta para incluir los modelos de redes
class Modelo(ABC):
    def __init__(self):
        self.n_parametros = 0
    @abstractmethod
    def forward(self, X):
        pass

La clase lineal está implementada heredando de Modelo para realizar una transformación afín sobre los datos de entrada. Esta clase gestiona la matriz de pesos \(W\) y el vector de sesgo \(b\), los cuales se inicializan aleatoriamente según las dimensiones de entrada y salida especificadas. En su método forward, la clase ejecuta el producto punto entre la entrada y los pesos, suma el sesgo y aplica una función de activación, encapsulando así la operación completa de una capa totalmente conectada en un solo paso de cómputo.

# Implementacion de una capa lineal
class Lineal(Modelo):
    def __init__(self, W, b, activacion):
        super().__init__()
        self.W = W
        self.b = b
        self.activacion = activacion
        self.n_parametros = W.size + b.size
    def __init__(self, n_inputs, n_outputs, activacion):
        super().__init__()
        self.W = np.random.rand(n_inputs, n_outputs)
        self.b = np.random.rand(n_outputs)
        self.activacion = activacion
        self.n_parametros = self.W.size + self.b.size
    def forward(self, X):
        h = np.dot(X, self.W) + self.b
        return self.activacion(h)

21.3 Ejercicios

Ejercicio

Tomando en cuenta el siguiente diagrama de red neuronal de una capa con tres entradas y dos salidas sin sesgos:

image , donde $$

X = [0, 4, 1],\[ \]

W = \[\begin{bmatrix} 0.5 & 0.6 \ 0.9 & 0.5 \ 0.3 & 0.9 \end{bmatrix}\]


0.3 & 0.9 \end{bmatrix},$$

Calcule el vector de predicciones, \(\hat{Y}\),

  1. usando una función de activación sigmoide

  2. usando una funcion de activación ReLU

Ejercicio

Diseñe una red neuronal de acuerdo a lo que se solicita: A un valor escalar de entrada la red debe obtener como salida \(\hat{Y} = [2x-1, -5x]\).

  1. Dibuje el diagrama.

  2. Especifique los parámetros \(W\), \(B\) junto con la función de activación a utilizar.

  3. Determine analíticamente la cantidad de parámetros en la red.

Widrow, Bernard, y Michael A Lehr. 2002. «30 years of adaptive neural networks: perceptron, madaline, and backpropagation». Proceedings of the IEEE 78 (9): 1415-42.