Ya hemos visto que, aun cuando nuestro dataset de entrenamiento tenga como variable objetivo números (los representados por cada imagen) la red va a necesitar no ese número, sino un array de tantos valores como neuronas tenga la capa de salida formado por ceros salvo por un 1 que se asignará al valor que represente dicho número (codificación One Hot Encoding). Es decir, si, para una muestra, la variable objetivo toma el valor 3, lo que realmente necesitamos es el array mostrado en la siguiente imagen:
Para esto, en lugar de recurrir a librerías que ya tengan esta funcionalidad implementada (Scikit-Learn, Pandas, Keras...), vamos a implementarla nosotros en una función que llamaremos to_categorical. Esta función recibirá dos parámetros: el número a convertir y el tamaño del array a generar. Por supuesto, podríamos encontrarnos con el caso de que la variable objetivo no fuese numérica, pero vamos a simplificar por ahora el código todo lo posible.
La función sería la siguiente:
def to_categorical(n, size):
""" Convierte un número n en un array de tamaño (size, 1) de ceros salvo el valor
correspondiente a n, que toma el valor 1. Así, -si size toma el valor 4- el número 2
se convertiría en el vector columna formado por los valores [0, 0, 1, 0] """
v = np.zeros(shape = (size, 1)) # Creamos el array vertical con ceros
v[n, 0] = 1 # Modificamos el valor correspondiente a n por 1
return v
Vemos que lo que primero que hacemos es crear el array a devolver rellenándolo con ceros y, a continuación, asignamos a la posición n (el número siendo convertido) el valor 1, devolviendo el array resultante. Éste deberá tener una única columna y tantas filas como se haya especificado en el parámetro size.
Probémosla convirtiendo el número 3 a un array de 10 valores:
to_categorical(3, 10)
array([[0.],
[0.],
[0.],
[1.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.]])