Cómo implementar una red neuronal desde cero

Listo para trabajar

神经元Es 神经网络una parte indispensable. Antes de implementar una red neuronal, necesitamos saber qué es una neurona

  • Neuron es la unidad básica de la red neuronal. La neurona primero obtiene la entrada y luego, después de una determinada operación matemática, produce una salida.

  • Figura 1

  • En esta neurona, hay dos entradas y una salida. Las dos entradas realizan un total de tres operaciones:
    1. Primero, multiplique las dos entradas con pesos:
    x1—> x1 * w1
    x2—> x2 * w2
    2. Sume los resultados obtenidos, más el sesgo (sesgo) b
    y = x1 * w1 + x2 * w2 + b
    3. Finalmente, después del 激活函数procesamiento, la salida
    y = f (x1 * w1 + x2 * w2 + b )

  • El papel de la función de activación es transformar entradas ilimitadas en salidas predecibles. Una función comúnmente utilizada es la función sigmoidea.
    El rango de valores de la función sigmoidea es de 0 a 1, es decir, cualquier entrada de -∞ a + ∞ puede convertirse en un número entre 0-1 después de pasar por la función sigmoidea.

  • Basándonos en la neurona anterior, simplemente podemos implementarla con código

# 定义sigmoid函数:f(x)=1/(1+e^(-x))
def sigmoid(x):
    import numpy as np
    return 1/(1+np.exp(-x))

# 定义一个神经元的类
class Neuron:
    def __init__(self, weights, bias):  #传入权重和偏置
        self.weights = weights
        self.bias = bias
    
    def feedforward(self, inputs):     
        total = np.dot(self.weights, inputs)  #数学运算
        return sigmoid(total)   # 返回经过激活函数之后的结果

prueba

import numpy as np

weights = np.array([1,0]) 
bias = 2

n = Neuron(weights,bias)   #实例化一个类

test = np.array([3,2])    #创建一个输入

print(n.feedforward(test))   #输出为0.9525741268224334

Construye una red neuronal

Una red neuronal conecta neuronas y utiliza la salida de una neurona como entrada de la siguiente. Inserte la descripción de la imagen aquí
Suponemos que los pesos y sesgos de todas las neuronas en esta red neuronal son [0,1], 1, y que las funciones de activación son funciones sigmoides. Usamos código para expresar esta red neuronal.

class NeuronNetwork:
    def __init__(self):
        weights = np.array([0,1])
        bias = 1
        self.h1 = Neuron(weights,bias)   #h1神经元
        self.h2 = Neuron(weights,bias)   #h2神经元
        self.o1 = Neuron(weights,bias)   #o1神经元
        
    def feedforward(self,x):
        h1 = self.h1.feedforward(x)     #h1神经元的输出
        h2 = self.h2.feedforward(x)     #h2神经元的输出
            
        o1 = self.o1.feedforward([h1,h2])  #o1神经元的输出
            
        return o1

network = NeuronNetwork()

x = np.array([2,3])

print(network.feedforward(x))   #结果为:0.7216325609518421

De esta manera, hemos construido con éxito una red neuronal, pero dicha entrada y salida son solo para construir la red y comprender su situación general, que no tiene importancia práctica.

重点

Entrenando una red neuronal

En aplicaciones prácticas, necesitamos una red neuronal que nos haga predicciones razonables, es decir, que nos dé algunos datos y descubra su conexión interna, es decir, que entrene una red neuronal en base a estos datos, y cuando haya nuevos datos, se puedan pasar por la red neuronal. La red predice algo que necesitamos.
Por ejemplo, tenemos un conjunto de datos

Nombre altura peso corporal género
un 185 81 masculino
segundo 160 48 Hembra
C 178 74 masculino
re 158 42 Hembra

Queremos juzgar si una persona es hombre o mujer en función de la altura y el peso de una persona, por lo que no podemos establecer arbitrariamente los pesos (pesos) y el sesgo (bais), por lo que debemos comenzar con los datos que ya conocemos y encontrar Un peso y sesgo adecuados, de modo que podamos predecir el sexo de una persona por altura y peso.

comienzo

Primero, responda brevemente a los datos (altura -170, peso -70, 1 significa hombre, 0 significa mujer)

Nombre altura peso corporal género
un 5 11 1
segundo -10 -22 0
C 8 4 1
re -12 -28 0

Debemos tener un estándar para definir si esta red neuronal es buena o no, para mejorarla. Esta es una perdida.
En general, con 均方误差pérdida definida.

MSE = 1 n {1} \ over {n}norte1 ∑ yo = 1 norte (yt - yp) 2 \ Displaystyle \ sum ^ {n} _ {i = 1} {(y_t - y_p) ^ 2} i = 1n(yt-yp)2

n es el número de muestras, de lo anterior podemos ver que es 4
y es el valor de salida predicho, es decir, género, hombre es 1, mujer es 0
yt y_tytRepresenta el verdadero género, yp y_pypRepresenta el género predicho
. Obviamente, cuanto menor sea el error cuadrático medio, mejor será el resultado de la predicción. Entonces nuestro objetivo es minimizar el error cuadrático medio. Defínalo como 损失函数.

Optimiza la red neuronal

Usando el 随机梯度下降algoritmo de optimización para entrenar la red neuronal. Es decir,
w 1 w_1w1<- w 1 w_1w1- η ( ∂ L {\ parcial L}L /∂ {\ parcial} w 1 w_1w1)
η es una constante, llamada tasa de aprendizaje, determina qué tan rápido entrenamos la red. Esta fórmula tiene un nuevo peso w 1 w_1w1.
(La derivación de la fórmula se actualiza ...) El
proceso de entrenamiento:
1. Seleccione una muestra del conjunto de datos;
2. Calcule la función derivada de la función de pérdida para todos los pesos y sesgos
3. Use la fórmula de actualización para actualizar cada peso
4. Regrese 1, hasta que todos los conjuntos de datos estén en bucle.
Este paso requiere cierto conocimiento de la búsqueda de derivadas parciales, es decir, la función derivada de la función de pérdida para todos los pesos y sesgos se calcula en el paso 2.

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

def deriv_sigmoid(x):
    fx = sigmoid(x)
    return fx*(1-fx)

def mse_loss(y_true, y_pred):
    return ((y_true - y_pred)**2).mean()

class NeuralNetwork:
    def __init__(self):
        self.w1 = np.random.normal()
        self.w2 = np.random.normal()        
        self.w3 = np.random.normal()        
        self.w4 = np.random.normal()
        self.w5 = np.random.normal()
        self.w6 = np.random.normal()
        
        self.b1 = np.random.normal()
        self.b2 = np.random.normal()
        self.b3 = np.random.normal()
    def feedforward(self,x):
        h1 = sigmoid(self.w1*x[0] + self.w2*x[1] + self.b1)
        h2 = sigmoid(self.w3*x[0] + self.w4*x[1] + self.b2)
        o1 = sigmoid(self.w5*h1 + self.w6*h2 + self.b3)
        
        return o1
    def train(self, data, all_y_trues):
        
        learn_rate = 0.1
        epochs = 500
        for epochs in range(epochs):
            for x, y_true in zip(data,all_y_trues):
                sum_h1 = self.w1*x[0] + self.w2*x[1] + self.b1
                h1 = sigmoid(sum_h1)
            
                sum_h2 = self.w3*x[0] + self.w4*x[1] + self.b2
                h2 = sigmoid(sum_h2)
            
                sum_o1 = self.w4*h1 + self.w5*h2 + self.b3
                o1 = sigmoid(sum_o1)
                y_pred = o1
            
                d_L_d_y_pred = -2 * (y_true - y_pred)
            
                d_ypred_d_w5 = h1*deriv_sigmoid(sum_o1)
                d_ypred_d_w6 = h2*deriv_sigmoid(sum_o1)
                d_ypred_d_b3 = deriv_sigmoid(sum_o1)
            
                d_ypred_d_h1 = self.w5*deriv_sigmoid(sum_o1)
                d_ypred_d_h2 = self.w6*deriv_sigmoid(sum_o1)
            
                d_h1_d_w1 = x[0]*deriv_sigmoid(sum_h1)
                d_h1_d_w2 = x[1]*deriv_sigmoid(sum_h1)
                d_h1_d_b1 = deriv_sigmoid(sum_h1)
            
                d_h2_d_w3 = x[0]*deriv_sigmoid(sum_h2)
                d_h2_d_w4 = x[1]*deriv_sigmoid(sum_h2)
                d_h2_d_b2 = deriv_sigmoid(sum_h2)
            
                self.w1 -= learn_rate*d_L_d_y_pred*d_ypred_d_h1*d_h1_d_w1
                self.w2 -= learn_rate*d_L_d_y_pred*d_ypred_d_h1*d_h1_d_w2
                self.b1 -= learn_rate*d_L_d_y_pred*d_ypred_d_h1*d_h1_d_b1
                
                self.w3 -= learn_rate*d_L_d_y_pred*d_ypred_d_h2*d_h2_d_w3
                self.w4 -= learn_rate*d_L_d_y_pred*d_ypred_d_h2*d_h2_d_w4
                self.b2 -= learn_rate*d_L_d_y_pred*d_ypred_d_h2*d_h2_d_b2
            
                self.w5 -= learn_rate*d_L_d_y_pred*d_ypred_d_w5
                self.w6 -= learn_rate*d_L_d_y_pred*d_ypred_d_w6
                self.b3 -= learn_rate*d_L_d_y_pred*d_ypred_d_b3

El entrenamiento de la red neuronal es demasiado tarde para actualizar debido a problemas de tiempo, se reducirá el tiempo para actualizar

Supongo que te gusta

Origin blog.csdn.net/weixin_43716048/article/details/109564212
Recomendado
Clasificación