Creaci贸n de una red neuronal desde cero en Python: Clasificaci贸n multiclase

    Este es el tercer art铆culo de la serie de art铆culos sobre “Creaci贸n de una red neuronal desde cero en Python”.

    • Creaci贸n de una red neuronal desde cero en Python
    • Crear una red neuronal desde cero en Python: agregar capas ocultas
    • Creaci贸n de una red neuronal desde cero en Python: clasificaci贸n de clases m煤ltiples

    Si no tiene experiencia previa con redes neuronales, le sugiero que lea primero la Parte 1 y la Parte 2 de la serie (enlazadas arriba). Una vez que se sienta c贸modo con los conceptos explicados en esos art铆culos, puede regresar y continuar este art铆culo.

    Introducci贸n

    En el art铆culo anterior, vimos c贸mo podemos crear una red neuronal desde cero, que es capaz de resolver problemas de clasificaci贸n binaria, en Python. Un problema de clasificaci贸n binaria tiene solo dos salidas. Sin embargo, los problemas del mundo real son mucho m谩s complejos.

    Considere el ejemplo del problema de reconocimiento de d铆gitos donde usamos la imagen de un d铆gito como entrada y el clasificador predice el n煤mero de d铆gito correspondiente. Un d铆gito puede ser cualquier n煤mero entre 0 y 9. Este es un ejemplo cl谩sico de un problema de clasificaci贸n de clases m煤ltiples donde la entrada puede pertenecer a cualquiera de las 10 salidas posibles.

    En este art铆culo, veremos c贸mo podemos crear una red neuronal simple desde cero en Python, que es capaz de resolver problemas de clasificaci贸n multiclase.

    Conjunto de datos

    Primero echemos un vistazo brevemente a nuestro conjunto de datos. Nuestro conjunto de datos tendr谩 dos caracter铆sticas de entrada y una de las tres posibles salidas. Crearemos manualmente un conjunto de datos para este art铆culo.

    Para hacerlo, ejecute el siguiente script:

    import numpy as np
    import matplotlib.pyplot as plt
    
    np.random.seed(42)
    
    cat_images = np.random.randn(700, 2) + np.array([0, -3])
    mouse_images = np.random.randn(700, 2) + np.array([3, 3])
    dog_images = np.random.randn(700, 2) + np.array([-3, 3])
    

    En el script anterior, comenzamos importando nuestras bibliotecas y luego creamos tres matrices bidimensionales de tama帽o 700 x 2. Puede pensar en cada elemento en un conjunto de la matriz como una imagen de un animal en particular. Cada elemento de la matriz corresponde a una de las tres clases de salida.

    Un punto importante a tener en cuenta aqu铆 es que, si graficamos los elementos de la cat_imagesmatriz en un plano bidimensional, estar谩n centrados alrededor de x = 0 e y = -3. De manera similar, los elementos de la mouse_imagesmatriz se centrar谩n alrededor de x = 3 e y = 3, y finalmente, los elementos de la matriz dog_imagesse centrar谩n alrededor de x = -3 e y = 3. Ver谩 esto una vez que tracemos nuestro conjunto de datos.

    A continuaci贸n, necesitamos unir verticalmente estas matrices para crear nuestro conjunto de datos final. Ejecute el siguiente script para hacerlo:

    feature_set = np.vstack([cat_images, mouse_images, dog_images])
    

    Creamos nuestro conjunto de caracter铆sticas y ahora necesitamos definir las etiquetas correspondientes para cada registro en nuestro conjunto de caracter铆sticas. El siguiente script hace eso:

    labels = np.array([0]*700 + [1]*700 + [2]*700)
    

    El script anterior crea una matriz unidimensional de 2100 elementos. Los primeros 700 elementos se han etiquetado como 0, los siguientes 700 elementos se han etiquetado como 1 mientras que los 煤ltimos 700 elementos se han etiquetado como 2. Esta es solo nuestra forma de acceso directo para crear r谩pidamente las etiquetas para nuestros datos correspondientes.

    Para problemas de clasificaci贸n de clases m煤ltiples, necesitamos definir la etiqueta de salida como un vector codificado en caliente ya que nuestra capa de salida tendr谩 tres nodes y cada node corresponder谩 a una clase de salida. Queremos que cuando se predice una salida, el valor del node correspondiente debe ser 1 mientras que los nodes restantes deben tener un valor de 0. Para eso, necesitamos tres valores para la etiqueta de salida para cada registro. Es por eso que convertimos nuestro vector de salida en un vector codificado en caliente.

    Ejecute la siguiente secuencia de comandos para crear la matriz de vectores codificada en caliente para nuestro conjunto de datos:

    one_hot_labels = np.zeros((2100, 3))
    
    for i in range(2100):
        one_hot_labels[i, labels[i]] = 1
    

    En el script anterior, creamos la one_hot_labelsmatriz de tama帽o 2100 x 3 donde cada fila contiene un vector codificado en caliente para el registro correspondiente en el conjunto de caracter铆sticas. Luego insertamos 1 en la columna correspondiente.

    Si ejecuta el script anterior, ver谩 que la one_hot_labelsmatriz tendr谩 1 en el 铆ndice 0 para los primeros 700 registros, 1 en el 铆ndice 1 para los pr贸ximos 700 registros y 1 en el 铆ndice 2 para los 煤ltimos 700 registros.

    Ahora tracemos el conjunto de datos que acabamos de crear. Ejecute el siguiente script:

    plt.scatter(feature_set[:,0], feature_set[:,1], c=labels, cmap='plasma', s=100, alpha=0.5)
    plt.show()
    

    Una vez que ejecute el script anterior, deber铆a ver la siguiente figura:

    Puede ver claramente que tenemos elementos que pertenecen a tres clases diferentes. Nuestra tarea ser谩 desarrollar una red neuronal capaz de clasificar los datos en las clases antes mencionadas.

    Red neuronal con varias clases de salida

    La red neuronal que vamos a dise帽ar tiene la siguiente arquitectura:

    Puede ver que nuestra red neuronal es bastante similar a la que desarrollamos en la Parte 2 de la serie. Tiene una capa de entrada con 2 entidades de entrada y una capa oculta con 4 nodes. Sin embargo, en la capa de salida, podemos ver que tenemos tres nodes. Esto significa que nuestra red neuronal es capaz de resolver el problema de clasificaci贸n de clases m煤ltiples donde el n煤mero de salidas posibles es 3.

    Funciones Softmax y Cross-Entropy

    Antes de pasar a la secci贸n de c贸digo, repasemos brevemente las funciones softmax y de entrop铆a cruzada , que son, respectivamente, las funciones de activaci贸n y p茅rdida m谩s com煤nmente utilizadas para crear una red neuronal para la clasificaci贸n de clases m煤ltiples.

    Funci贸n Softmax

    De la arquitectura de nuestra red neuronal, podemos ver que tenemos tres nodes en la capa de salida. Tenemos varias opciones para la funci贸n de activaci贸n en la capa de salida. Una opci贸n es utilizar la funci贸n sigmoidea como hicimos en los art铆culos anteriores.

    Sin embargo, hay una funci贸n de activaci贸n m谩s conveniente en forma de softmax que toma un vector como entrada y produce otro vector de la misma longitud que la salida. Dado que nuestra salida contiene tres nodes, podemos considerar la salida de cada node como un elemento del vector de entrada. La salida ser谩 una longitud del mismo vector donde los valores de todos los elementos suman 1. Matem谩ticamente, la funci贸n softmax se puede representar como:

    $$
    y_i (z_i) = frac {e ^ {z_i}} {sumnolimits_ {k = 1} ^ {k} {e ^ {z_k}}}
    $$

    La funci贸n softmax simplemente divide el exponente de cada elemento de entrada por la suma de exponentes de todos los elementos de entrada. Echemos un vistazo a un ejemplo simple de esto:

    def softmax(A):
        expA = np.exp(A)
        return expA / expA.sum()
    
    nums = np.array([4, 5, 6])
    print(softmax(nums))
    

    En el script anterior creamos una funci贸n softmax que toma un solo vector como entrada, toma exponentes de todos los elementos en el vector y luego divide los n煤meros resultantes individualmente por la suma de exponentes de todos los n煤meros en el vector de entrada.

    Puede ver que el vector de entrada contiene los elementos 4, 5 y 6. En la salida, ver谩 tres n煤meros comprimidos entre 0 y 1 donde la suma de los n煤meros ser谩 igual a 1. La salida se ve as铆:

    [0.09003057 0.24472847 0.66524096]
    

    La funci贸n de activaci贸n Softmax tiene dos ventajas principales sobre las otras funciones de activaci贸n, en particular para problemas de clasificaci贸n de clases m煤ltiples: la primera ventaja es que la funci贸n softmax toma un vector como entrada y la segunda ventaja es que produce una salida entre 0 y 1. Recuerde, En nuestro conjunto de datos, tenemos etiquetas de salida codificadas en caliente, lo que significa que nuestra salida tendr谩 valores entre 0 y 1. Sin embargo, la salida del proceso de alimentaci贸n anticipada puede ser mayor que 1, por lo que la funci贸n softmax es la opci贸n ideal en la capa de salida. ya que aplasta la salida entre 0 y 1.

    Funci贸n de entrop铆a cruzada

    Con la funci贸n de activaci贸n softmax en la capa de salida, la funci贸n de costo de error cuadr谩tico medio se puede utilizar para optimizar el costo como hicimos en los art铆culos anteriores. Sin embargo, para la funci贸n softmax, existe una funci贸n de costo m谩s conveniente que se llama entrop铆a cruzada.

    Matem谩ticamente, la funci贸n de entrop铆a cruzada se ve as铆:

    $$
    H(y,hat{y}) = -sum_i y_i log hat{y_i}
    $$

    La entrop铆a cruzada es simplemente la suma de los productos de todas las probabilidades reales con el logaritmo negativo de las probabilidades predichas. Para problemas de clasificaci贸n de clases m煤ltiples, se sabe que la funci贸n de entrop铆a cruzada supera a la funci贸n decente de gradiente.

    Ahora tenemos el conocimiento suficiente para crear una red neuronal que resuelva problemas de clasificaci贸n de clases m煤ltiples. Veamos c贸mo funcionar谩 nuestra red neuronal.

    Como siempre, una red neuronal se ejecuta en dos pasos: retroalimentaci贸n y retropropagaci贸n.

    Feed Forward

    La fase de feedforward seguir谩 siendo m谩s o menos similar a lo que vimos en el art铆culo anterior. La 煤nica diferencia es que ahora usaremos la funci贸n de activaci贸n softmax en la capa de salida en lugar de la funci贸n sigmoidea.

    Recuerde, para la salida de la capa oculta seguiremos usando la funci贸n sigmoidea como lo hicimos anteriormente. La funci贸n softmax se utilizar谩 solo para las activaciones de la capa de salida.

    Fase 1

    Dado que estamos usando dos funciones de activaci贸n diferentes para la capa oculta y la capa de salida, he dividido la fase de avance en dos subfases.

    En la primera fase, veremos c贸mo calcular la salida de la capa oculta. Para cada registro de entrada, tenemos dos caracter铆sticas “x1” y “x2”. Para calcular los valores de salida para cada node en la capa oculta, tenemos que multiplicar la entrada con los pesos correspondientes del node de la capa oculta para el que estamos calculando el valor. Observe que tambi茅n estamos agregando un t茅rmino de sesgo aqu铆. Luego pasamos el producto escalar a trav茅s de la funci贸n de activaci贸n sigmoidea para obtener el valor final.

    Por ejemplo, para calcular el valor final para el primer node de la capa oculta, que se indica con “ah1”, debe realizar el siguiente c谩lculo:

    $$
    zh1 = x1w1 + x2w2 + b
    $$

    $$
    ah1 = frac {mathrm {1}} {mathrm {1} + e ^ {- zh1}}
    $$

    Este es el valor resultante para el node superior de la capa oculta. De la misma manera, puede calcular los valores para los nodes 2, 3 y 4 de la capa oculta.

    Fase 2

    Para calcular los valores de la capa de salida, los valores de los nodes de la capa oculta se tratan como entradas. Por tanto, para calcular la salida, multiplique los valores de los nodes de la capa oculta con sus correspondientes pesos y pase el resultado por una funci贸n de activaci贸n, que en este caso ser谩 softmax.

    Esta operaci贸n se puede expresar matem谩ticamente mediante la siguiente ecuaci贸n:

    $$
    zo1 = ah1w9 + ah2w10 + ah2w11 + ah4w12
    $$

    $$
    zo2 = ah1w13 + ah2w14 + ah2w15 + ah4w16
    $$

    $$
    zo3 = ah1w17 + ah2w18 + ah2w19 + ah4w20
    $$

    Aqu铆 zo1, zo2 y zo3 formar谩n el vector que usaremos como entrada para la funci贸n sigmoidea. Vamos a nombrar este vector “zo”.

    zo = [zo1, zo2, zo3]
    

    Ahora, para encontrar el valor de salida a01, podemos usar la funci贸n softmax de la siguiente manera:

    $$
    ao1 (zo) = frac {e ^ {zo1}} {sumnolimits_ {k = 1} ^ {k} {e ^ {zok}}}
    $$

    Aqu铆 “a01” es la salida para el node superior en la capa de salida. De la misma forma, puede utilizar la funci贸n softmax para calcular los valores de ao2 y ao3.

    Puede ver que el paso de avance para una red neuronal con salida de clases m煤ltiples es bastante similar al paso de avance de la red neuronal para problemas de clasificaci贸n binaria. La 煤nica diferencia es que aqu铆 estamos usando la funci贸n softmax en la capa de salida en lugar de la funci贸n sigmoidea.

    Propagaci贸n hacia atr谩s

    La idea b谩sica detr谩s de la propagaci贸n hacia atr谩s sigue siendo la misma. Tenemos que definir una funci贸n de costo y luego optimizar esa funci贸n de costo actualizando los pesos de manera que el costo se minimice. Sin embargo, a diferencia de los art铆culos anteriores donde usamos el error cuadr谩tico medio como funci贸n de costo, en este art铆culo usaremos la funci贸n de entrop铆a cruzada.

    La retropropagaci贸n es un problema de optimizaci贸n en el que tenemos que encontrar los m铆nimos de funci贸n para nuestra funci贸n de costo.

    Para encontrar los m铆nimos de una funci贸n, podemos usar el algoritmo de degradado decente . El algoritmo de degradado decente se puede representar matem谩ticamente de la siguiente manera:

    $$
    repetir hasta la convergencia: comenzar {Bmatrix} w_j: = w_j – alpha frac {parcial} {parcial w_j} J (w_0, w_1 ……. w_n) end {Bmatrix} …….. ….. (1)
    $$

    Los detalles sobre c贸mo la funci贸n decente del gradiente minimiza el costo ya se discutieron en el art铆culo anterior. Aqu铆 veremos las operaciones matem谩ticas que necesitamos realizar.

    Nuestra funci贸n de costos es:

    $$
    H(y,hat{y}) = -sum_i y_i log hat{y_i}
    $$

    En nuestra red neuronal, tenemos un vector de salida donde cada elemento del vector corresponde a la salida de un node en la capa de salida. El vector de salida se calcula utilizando la funci贸n softmax. Si “ao” es el vector de las salidas predichas de todos los nodes de salida y “y” es el vector de las salidas reales de los nodes correspondientes en el vector de salida, b谩sicamente tenemos que minimizar esta funci贸n:

    $$
    costo (y, {ao}) = -sum_i y_i log {ao_i}
    $$

    Fase 1

    En la primera fase, necesitamos actualizar los pesos w9 hasta w20. Estos son los pesos de los nodes de la capa de salida.

    Del art铆culo anterior, sabemos que para minimizar la funci贸n de costo, tenemos que actualizar los valores de peso de manera que el costo disminuya. Para hacerlo, necesitamos tomar la derivada de la funci贸n de costo con respecto a cada peso. Matem谩ticamente podemos representarlo como:

    $$
    frac {dcost}{dwo} = frac {dcost}{dao} *, frac {dao}{dzo} * frac {dzo}{dwo} ….. (1)
    $$

    Aqu铆 “wo” se refiere a los pesos en la capa de salida.

    La primera parte de la ecuaci贸n se puede representar como:

    $$
    frac {dcost} {dao} * frac {dao} {dzo} ……. (2)
    $$

    La derivaci贸n detallada de la funci贸n de p茅rdida de entrop铆a cruzada con la funci贸n de activaci贸n softmax se puede encontrar en este enlace .

    La derivada de la ecuaci贸n (2) es:

    $$
    frac {dcost}{dao} * frac {dao}{dzo} = ao – y ……. (3)
    $$

    Donde “ao” es la salida predicha mientras que “y” es la salida real.

    Finalmente, necesitamos encontrar “dzo” con respecto a “dwo” de la Ecuaci贸n 1. La derivada son simplemente las salidas que provienen de la capa oculta como se muestra a continuaci贸n:

    $$
    frac {dzo}{dwo} = ah
    $$

    Para encontrar nuevos valores de peso, los valores devueltos por la Ecuaci贸n 1 pueden simplemente multiplicarse con la tasa de aprendizaje y restarse de los valores de peso actuales.

    Tambi茅n necesitamos actualizar el sesgo “bo” para la capa de salida. Necesitamos diferenciar nuestra funci贸n de costo con respecto al sesgo para obtener un nuevo valor de sesgo como se muestra a continuaci贸n:

    $$
    frac {dcost}{dbo} = frac {dcost}{dao} * frac {dao}{dzo} * frac {dzo}{dbo} ….. (4)
    $$

    La primera parte de la Ecuaci贸n 4 ya se ha calculado en la Ecuaci贸n 3. Aqu铆 solo necesitamos actualizar “dzo” con respecto a “bo” que es simplemente 1. Entonces:

    $$
    frac {dcost}{dbo} = ao – y ……….. (5)
    $$

    Para encontrar nuevos valores de sesgo para la capa de salida, los valores devueltos por la Ecuaci贸n 5 se pueden multiplicar simplemente con la tasa de aprendizaje y restar del valor de sesgo actual.

    Fase 2

    En esta secci贸n, propagaremos nuestro error a la capa anterior y encontraremos los nuevos valores de peso para los pesos de las capas ocultas, es decir, los pesos w1 a w8.

    Denotemos colectivamente los pesos de las capas ocultas como “wh”. B谩sicamente tenemos que diferenciar la funci贸n de coste con respecto a “wh”.

    Matem谩ticamente podemos usar la regla de diferenciaci贸n de la cadena para representarla como:

    $$
    frac {dcost} {dwh} = frac {dcost} {dah} *, frac {dah} {dzh} * frac {dzh} {dwh} …… (6)
    $$

    Aqu铆 nuevamente, dividiremos la Ecuaci贸n 6 en t茅rminos individuales.

    El primer t茅rmino “dcost” se puede diferenciar con respecto a “dah” usando la regla de diferenciaci贸n de la cadena de la siguiente manera:

    $$
    frac {dcost} {dah} = frac {dcost} {dzo} * frac {dzo} {dah} …… (7)
    $$

    Dividamos nuevamente la Ecuaci贸n 7 en t茅rminos individuales. De la Ecuaci贸n 3, sabemos que:

    $$
    frac {dcost}{dao} * frac {dao}{dzo} =frac {dcost}{dzo} = = ao – y …….. (8)
    $$

    Ahora necesitamos encontrar dzo / dah de la Ecuaci贸n 7, que es igual a los pesos de la capa de salida como se muestra a continuaci贸n:

    $$
    frac {dzo} {dah} = wo …… (9)
    $$

    Ahora podemos encontrar el valor de dcost / dah reemplazando los valores de las ecuaciones 8 y 9 en la ecuaci贸n 7.

    Volviendo a la Ecuaci贸n 6, todav铆a tenemos que encontrar dah / dzh y dzh / dwh.

    El primer t茅rmino dah / dzh se puede calcular como:

    $$
    frac {dah} {dzh} = sigmoide (zh) * (1-sigmoide (zh)) …….. (10)
    $$

    Y finalmente, dzh / dwh son simplemente los valores de entrada:

    $$
    frac {dzh} {dwh} = caracter铆sticas de entrada …….. (11)
    $$

    Si reemplazamos los valores de las ecuaciones 7, 10 y 11 en la ecuaci贸n 6, podemos obtener la matriz actualizada para los pesos de las capas ocultas. Para encontrar nuevos valores de peso para los pesos de capa oculta “wh”, los valores devueltos por la Ecuaci贸n 6 pueden simplemente multiplicarse con la tasa de aprendizaje y restarse de los valores actuales de peso de capa oculta.

    De manera similar, la derivada de la funci贸n de costo con respecto al sesgo de capa oculta “bh” se puede calcular simplemente como:

    $$
    frac {dcost} {dbh} = frac {dcost} {dah} *, frac {dah} {dzh} * frac {dzh} {dbh} …… (12)
    $$

    Que es simplemente igual a:

    $$
    frac {dcost} {dbh} = frac {dcost} {dah} *, frac {dah} {dzh} …… (13)
    $$

    porque,

    $$
    frac {dzh} {dbh} = 1
    $$

    Para encontrar nuevos valores de sesgo para la capa oculta, los valores devueltos por la Ecuaci贸n 13 se pueden simplemente multiplicar por la tasa de aprendizaje y restar de los valores de sesgo de la capa oculta actual y eso es todo para la retropropagaci贸n.

    Puede ver que el proceso de retropropagaci贸n y retroalimentaci贸n es bastante similar al que vimos en nuestros 煤ltimos art铆culos. Lo 煤nico que cambiamos es la funci贸n de activaci贸n y la funci贸n de costo.

    C贸digo para redes neuronales para clasificaci贸n de clases m煤ltiples

    Hemos cubierto la teor铆a detr谩s de la red neuronal para la clasificaci贸n de clases m煤ltiples, y ahora es el momento de poner esa teor铆a en pr谩ctica.

    Eche un vistazo al siguiente gui贸n:

    import numpy as np
    import matplotlib.pyplot as plt
    
    np.random.seed(42)
    
    cat_images = np.random.randn(700, 2) + np.array([0, -3])
    mouse_images = np.random.randn(700, 2) + np.array([3, 3])
    dog_images = np.random.randn(700, 2) + np.array([-3, 3])
    
    feature_set = np.vstack([cat_images, mouse_images, dog_images])
    
    labels = np.array([0]*700 + [1]*700 + [2]*700)
    
    one_hot_labels = np.zeros((2100, 3))
    
    for i in range(2100):
        one_hot_labels[i, labels[i]] = 1
    
    plt.figure(figsize=(10,7))
    plt.scatter(feature_set[:,0], feature_set[:,1], c=labels, cmap='plasma', s=100, alpha=0.5)
    plt.show()
    
    def sigmoid(x):
        return 1/(1+np.exp(-x))
    
    def sigmoid_der(x):
        return sigmoid(x) *(1-sigmoid (x))
    
    def softmax(A):
        expA = np.exp(A)
        return expA / expA.sum(axis=1, keepdims=True)
    
    instances = feature_set.shape[0]
    attributes = feature_set.shape[1]
    hidden_nodes = 4
    output_labels = 3
    
    wh = np.random.rand(attributes,hidden_nodes)
    bh = np.random.randn(hidden_nodes)
    
    wo = np.random.rand(hidden_nodes,output_labels)
    bo = np.random.randn(output_labels)
    lr = 10e-4
    
    error_cost = []
    
    for epoch in range(50000):
    ############# feedforward
    
        # Phase 1
        zh = np.dot(feature_set, wh) + bh
        ah = sigmoid(zh)
    
        # Phase 2
        zo = np.dot(ah, wo) + bo
        ao = softmax(zo)
    
    ########## Back Propagation
    
    ########## Phase 1
    
        dcost_dzo = ao - one_hot_labels
        dzo_dwo = ah
    
        dcost_wo = np.dot(dzo_dwo.T, dcost_dzo)
    
        dcost_bo = dcost_dzo
    
    ########## Phases 2
    
        dzo_dah = wo
        dcost_dah = np.dot(dcost_dzo , dzo_dah.T)
        dah_dzh = sigmoid_der(zh)
        dzh_dwh = feature_set
        dcost_wh = np.dot(dzh_dwh.T, dah_dzh * dcost_dah)
    
        dcost_bh = dcost_dah * dah_dzh
    
        # Update Weights ================
    
        wh -= lr * dcost_wh
        bh -= lr * dcost_bh.sum(axis=0)
    
        wo -= lr * dcost_wo
        bo -= lr * dcost_bo.sum(axis=0)
    
        if epoch % 200 == 0:
            loss = np.sum(-one_hot_labels * np.log(ao))
            print('Loss function value: ', loss)
            error_cost.append(loss)
    

    El c贸digo es bastante similar al que creamos en el art铆culo anterior. En la secci贸n de feed-forward, la 煤nica diferencia es que “ao”, que es el resultado final, se calcula utilizando la softmaxfunci贸n.

    De manera similar, en la secci贸n de retropropagaci贸n, para encontrar los nuevos pesos para la capa de salida, la funci贸n de costo se deriva con respecto a la softmaxfunci贸n en lugar de la sigmoidfunci贸n.

    Si ejecuta el script anterior, ver谩 que el costo del error final ser谩 0.5. La siguiente figura muestra c贸mo el costo disminuye con el n煤mero de 茅pocas.

    Como puede ver, no se necesitan muchas 茅pocas para alcanzar nuestro costo de error final.

    Del mismo modo, si ejecuta el mismo script con la funci贸n sigmoidea en la capa de salida, el costo de error m铆nimo que obtendr谩 despu茅s de 50000 茅pocas ser谩 de alrededor de 1,5, que es mayor que 0,5, logrado con softmax.

    Conclusi贸n

    Las redes neuronales del mundo real son capaces de resolver problemas de clasificaci贸n de clases m煤ltiples. En este art铆culo, vimos c贸mo podemos crear una red neuronal muy simple para la clasificaci贸n de clases m煤ltiples, desde cero en Python. Este es el art铆culo final de la serie: “Neural Network from Scratch in Python”. En los pr贸ximos art铆culos, explicar茅 c贸mo podemos crear redes neuronales m谩s especializadas, como redes neuronales recurrentes y redes neuronales convolucionales desde cero en Python.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *