Construyendo una red neuronal desde 0 (1) Del perceptrón a la red neuronal

I. Introducción

Hay muchos marcos de aprendizaje profundo, incluidos Tensorflow, PyTorch, Keras, etc. En el marco se implementan varias redes que se pueden derivar automáticamente, por lo que solo se necesitan una docena de líneas de código para construir una red completa. Debido a que el marco está altamente encapsulado, no podemos conocer los principios subyacentes. Para comprender mejor las redes neuronales, este artículo utiliza numpy para construir una red neuronal completa, implementa algoritmos de retropropagación y descenso de gradiente, y utiliza la red neuronal implementada por mí para entrenar un modelo de clasificación.

2. perceptrón

Antes de comenzar a construir una red neuronal, es necesario comprender algunas teorías sobre las redes neuronales. Lo que implementará este artículo es una red neuronal completamente conectada, y la red neuronal completamente conectada es una evolución de un modelo llamado perceptrón.Echemos un vistazo al perceptrón.

2.1 perceptrón

2.1.1 Principio del perceptrón

El perceptrón es un modelo de dos clasificaciones cuyo propósito es utilizar una línea recta o hiperplano para separar dos tipos de datos. Para simplificar, analizamos aquí el caso bidimensional. Una línea recta en un espacio bidimensional se puede representar mediante la siguiente función:
h = w 1 x 1 + w 2 x 2 + bh = w_1x_1+w_2x_2+bh=w1X1+w2X2+b
Entre ellosx 1, x 2 x_1, x_2X1x2son los datos, w 1, w 2, b w_1, w_2, bw1w2, b son parámetros, que son tres constantes. En este momento, puedes usarX = [ x 1 , x 2 ] TX=[x_1, x_2]^TX=[ x1,X2]T representa la entrada. Si ingresas unX 1 X_1X1, el obtenido h 1 h_1h1Mayor que 0, indica datos X 1 X_1X1por encima de la línea recta, es decir, X 1 X_1X1Pertenece a la categoría 1. Si obtenemos h 1 h_1h1Menos de 0, indica datos X 1 X_1X1Debajo de la recta, que es X 1 X_1X1Categoría de datos 0.
La descripción del texto anterior se puede reemplazar por una función escalonada, es decir:
y = { 1 , w 1 x 1 + w 2 x 2 + b ≥ 0 0 , w 1 x 1 + w 2 x 2 + b < 0 y = \begin{casos} 1, & w_1x_1+w_2x_2+b \geq 0\\ 0,& w_1x_1+w_2x_2+b < 0 \\ \end{casos}y={ 1 ,0 ,w1X1+w2X2+b0w1X1+w2X2+b<0
Ahora solo nos falta determinar w 1, w 2, b w_1, w_2, bw1w2, b , puede utilizar la función anterior para la clasificación.

2.1.2 Circuito lógico

Ahora que conocemos las funciones del perceptrón, podemos usarlo para implementar algunas funciones. Por ejemplo, el circuito AND tiene dos entradas, correspondientes a x 1 y x 2 x_1 y x_2 ​​respectivamente.X1x2, hay una salida correspondiente a y. La característica del circuito AND es que genera 1 cuando ambas entradas son 1; de lo contrario, genera 0. La tabla de verdad del circuito AND es la siguiente:

x1 x2 y
0 0 0
0 1 0
1 0 0
1 1 1
De alguna manera, sabemos que cuando w 1 = 0,5, w 2 = 0,5, b = 0,8 w_1=0,5, w_2=0,5, b=0,8w1=0,5 w2=0,5 segundo=A 0,8 , el perceptrón puede realizar la función del circuito. Ahora, sólo necesitas modificarw 1, w 2, b w_1, w_2, bw1w2, el valor de b , también podemos implementar circuitos OR, NAND. Aquí hay un código Python con el circuito:
import numpy as np

def AND(X):
    # w1、w2
    W = np.array([[0.5], [0.5])
    b = 0.8
    h = np.dot(X, W)
    if h >= b:
        return 1
    else:
        return 0

La implementación del circuito OR y NOT consiste en modificar W y b.

2.2 Limitaciones del perceptrón

Anteriormente usamos el perceptrón para implementar el circuito Y. Los circuitos OR y NAND también se pueden implementar de manera tan simple como el circuito AND. Entonces, ¿se puede implementar cualquier circuito perceptrón? La respuesta es no. El perceptrón es un modelo lineal (dividido por líneas rectas), que solo puede resolver problemas linealmente separables. El circuito XOR no es lineal. Cuando las entradas son iguales, el XOR genera 0, y cuando las entradas son diferentes , genera 1. Por lo tanto, la relación entre la entrada y salida de XOR se puede representar mediante la siguiente figura:
Insertar descripción de la imagen aquí
donde el círculo representa la categoría 0 y el triángulo representa la categoría 1. Lo que tiene que hacer el perceptrón es separar los dos tipos de datos con una línea recta, lo que en realidad es imposible.
Aunque dos tipos de datos no se pueden separar con una línea recta, si se pueden usar dos líneas rectas, se pueden separar los dos tipos de puntos, lo que lleva al concepto de perceptrón multicapa.

2.3 Perceptrón multicapa

Aunque las computadoras actuales son bastante complejas, esencialmente se implementan con circuitos Y, O y NO. Mediante el empalme de varios circuitos se crean computadoras complejas. Siguiendo esta idea, podemos empalmar múltiples perceptrones para obtener un circuito más complejo. Ahora bien, si hemos implementado la puerta AND (AND), la puerta OR (OR) y la puerta NAND (NAND), estas tres puertas están representadas por los siguientes tres diagramas: Entonces, ¿cómo debemos combinarlas para implementar la puerta XOR
Insertar descripción de la imagen aquí
?

Las características de cada puerta son las siguientes:
Puerta AND: las entradas son todas 1, la salida es 1, de lo contrario la salida es 0
Puerta O: la entrada es 1, la salida es 1, de lo contrario la salida es 0
Puerta NAND: la opuesto a la puerta AND

Podemos empalmar el perceptrón (circuito) como se muestra a continuación para implementar la puerta XOR:
Insertar descripción de la imagen aquí
Usemos la tabla de verdad para verificarlo: Pon x 1, x 2 x_1, x_2X1x2Sustituyendo en el perceptrón multicapa anterior podemos obtener los resultados en la siguiente tabla:

x1 x2 s1 s2 y
0 0 0 1 0
0 1 1 1 1
1 0 1 1 1
1 1 0 1 0

La implementación del código de la puerta XOR también es muy simple: el código específico es el siguiente:

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    return AND(s1, s2)  

3. Red neuronal

Ahora que comprendemos un poco los perceptrones multicapa, ¿cuál es la conexión entre las redes neuronales y los perceptrones multicapa? Aquí debemos prestar atención a la función del paso anterior.

3.1 Función de activación

En el paso anterior, la salida del perceptrón pasará por una función de paso, asignando cualquier valor a 0-1. Sin embargo, la función escalonada es incómoda de derivar, así que pensé en usar una función continua para reemplazar la función escalonada. Una de las más utilizadas es la función sigmoidea, cuya función es la siguiente: σ ( x ) = 1 1 + mi − x \sigma(
x ) = \frac{1}{1+e^{-x}}σ ( x )=1+mi−x _1
La imagen de la función es la siguiente:
Insertar descripción de la imagen aquí
la imagen es diferenciable en todas partes. Sigmoide fue muy popular en los primeros días del desarrollo de las redes neuronales, pero ahora es reemplazado por la función ReLU en la mayoría de los escenarios. La función ReLU es más simple, tiene una menor complejidad de derivación y puede aliviar el problema de los gradientes que desaparecen, por lo que se usa con más frecuencia. La expresión de ReLU es la siguiente:
relu (x) = max (x, 0) relu(x) = max(x, 0)leer de nuevo ( x ) _=máximo x ( x ,0 )
Cuando la entrada es menor que 0, se devuelve 0 y cuando la entrada es mayor que 0, se devuelve el valor original. La imagen de la función es la siguiente:
Insertar descripción de la imagen aquí
la función escalonada, la función sigmoidea y la función ReLU mencionadas anteriormente se denominan funciones de activación.

3.2 Del perceptrón multicapa a la red neuronal

Ahora cambie la función de activación del perceptrón de la función de paso a la función ReLU, completando así la transformación del perceptrón multicapa a la red neuronal. Entendamos el perceptrón multicapa desde otra perspectiva. Aquí tomamos la puerta XOR como ejemplo. Hay tres circuitos de puerta lógica en la puerta XOR. Ya sea una puerta AND, una puerta OR o una puerta NAND, en realidad son la misma función con diferentes parámetros. Por lo tanto, la puerta XOR se puede representar mediante el siguiente diagrama:
Insertar descripción de la imagen aquí
Usamos el vector de entrada X = [ x 1 , x 2 ] TX=[x_1, x_2]^TX=[ x1,X2]Se representa T y la salida intermedia se representa medianteS = [ s 1 , s 2 ] TS=[s_1, s_2]^TS=[ s1,s2]T , W para peso de mortero= [w 1, w 2] W=[w_1, w_2]W.=[ w1,w2] significa. Entoncess 1 = WX + b, s 2 = W x + b s_1 = WX+b, s_2 = Wx+bs1=WX _+b s2=Ancho x+B. _ Sin embargo, cabe señalar que s1 es originalmente el resultado de la puerta NAND y s2 es el resultado de la puerta OR, por lo que la W correspondiente a s1 y la W correspondiente a s2 son diferentes. De esto obtenemoss 1 = W 1 X + b , s 2 = W 2 x + b s_1 = W_1X+b, s_2 = W_2x+bs1=W.1X+b s2=W.2X+b , en el queW 1 = [ w 11 , w 12 ], W 2 = [ w 21 , w 22 ] W_1=[w_{11}, w_{12}], W_2=[w_{21}, w_{22 } ]W.1=[ w11,w12] W2=[ w21,w22] .
Además, los vectoresW 1 , W 2 W_1, W_2W.1W2Forme una matriz y obtenga W ( 1 ) = ( w 11 w 12 w 21 w 22 ) W^{(1)}=\begin{pmatrix} w_{11} & w_{12}\\ w_{21} & w_ {22} \end{pmatriz}W.( 1 )=(w11w21w12w22)
那么:
S = W ( 1 ) X + b S=W^{(1)}X+bS=W.( 1 ) X+b
expresa así el cálculo de S mediante una multiplicación de matrices. De manera similar, el cálculo de y también se puede calcular mediante una multiplicación de matrices:
y = W (2) S + by=W^{(2)}S+by=W.( 2 ) S+bPero
la expresión anterior en realidad no tiene una función de activación. Si se agrega una función de activación, se puede calcular con la siguiente expresión:
y = σ ( W ( 2 ) relu ( W ( 1 ) X + b ) + b ) y = \sigma( W^{(2)}relu(W^{(1)}X+b)+b)y=s ( W( 2 ) relu(W( 1 ) X+segundo )+b )
La expresión anterior es una red neuronal.

Supongo que te gusta

Origin blog.csdn.net/ZackSock/article/details/130745255
Recomendado
Clasificación