Notas de estudio básico de redes neuronales (tres) aprendizaje de redes neuronales

Tabla de contenido

Prefacio:

4.1 Aprendiendo de los datos

4.1.1 Basado en datos

4.1.2 Datos de entrenamiento y datos de prueba

4.2 Función de pérdida

4.2.1 Error cuadrático medio

4.2.2 Error de entropía cruzada

4.2.3 aprendizaje por mini lotes

4.2.5 ¿Por qué debería establecerse una función de pérdida?

4.3 Diferenciación numérica

4.3.1 Derivado

4.3.2 Un ejemplo de diferenciación

4.3.3 Derivada parcial

4.4 Gradiente

4.4.1 Método de gradiente

4.4.2 El gradiente de la red neuronal

4.5 Implementación del algoritmo de aprendizaje

4.5.1 Clase de red neuronal de 2 capas

4.5.2 Implementación de mini lotes

4.5.3 Evaluación basada en datos de prueba

resumen:


Prefacio:

El capítulo anterior habló sobre el contenido de propagación directa de las redes neuronales y este capítulo habla sobre cómo entrenar los parámetros de peso relevantes en función de los datos. Obtuvimos directamente los pesos de los parámetros en el combate real, y luego tenemos que aprender

4.1 Aprendiendo de los datos

Introducir el aprendizaje de la red neuronal, es decir, el método de usar datos para determinar valores de parámetros. Aprenderemos del conjunto de entrenamiento del experimento anterior.

4.1.1 Basado en datos

La cantidad de características de una imagen generalmente se expresa en forma de vector.

Aprendimos previamente el algoritmo de clasificación SVM y KNN, extraemos manualmente el vector de características.

El aprendizaje profundo a veces se denomina aprendizaje automático de un extremo a otro (aprendizaje automático de un extremo a otro). El extremo a extremo mencionado aquí significa de un extremo al otro, lo que significa obtener el resultado objetivo (salida) de los datos originales (entrada).

La ventaja de la red neuronal es que todos los problemas pueden resolverse mediante el mismo proceso.

4.1.2 Datos de entrenamiento y datos de prueba

1. Los datos de entrenamiento y los datos de prueba: los datos de entrenamiento utilizados para entrenar el modelo y los datos de prueba no se incluyen en el modelo de datos de entrenamiento , que se usa para juzgar la calidad del modelo de datos después del entrenamiento .

2. Capacidad de generalización: si los resultados de la prueba son buenos, entonces su capacidad de generalización es buena.

3. Ajuste excesivo: fuerte adaptación a los datos de entrenamiento, pero poca capacidad de generalización.

4.2 Función de pérdida

El propósito del aprendizaje de redes neuronales es utilizar la función de pérdida como punto de referencia para encontrar el parámetro de peso que pueda minimizar su valor.

Error cuadrático medio de juicio de especies y error de entropía cruzada

4.2.1 Error cuadrático medio

Código de implementación:

4.2.2 Error de entropía cruzada

El valor del error de entropía cruzada está determinado por la salida correspondiente a la solución de etiqueta correcta

Código de implementación:

4.2.3 aprendizaje por mini lotes

Para un solo cálculo, el tiempo de procesamiento de datos es demasiado largo y esperamos que la mayor parte del tiempo se dedique al cálculo. Calcule el valor de la función de pérdida promedio de todos los datos (suma / total de los valores de la función de pérdida)

Analizar el paquete de datos del experimento anterior.

10 seleccionados al azar

Para encontrar el lugar donde el valor de la función de pérdida es lo más pequeño posible, es necesario calcular la derivada del parámetro (para ser precisos, el gradiente), y luego usar esta derivada como guía para
actualizar gradualmente el valor del parámetro.

4.2.5 ¿Por qué debería establecerse una función de pérdida?

Debido a que la función de pérdida es derivable y continua, es fácil de depurar.

Tomemos un ejemplo. Por ejemplo, si hay 100 datos de entrenamiento para probar, la precisión es del 32%. Si la precisión del reconocimiento se usa como indicador, la precisión del parámetro de peso solo será del 32% si modifica ligeramente el parámetro de peso. 33%, este es un cambio discreto y discontinuo; y la función de pérdida es diferente. Cuando la relación de peso se cambia ligeramente, el valor de la función de pérdida cambiará inmediatamente (por ejemplo, 0,9524 se convierte en 0,9612). Este valor es continuo debido a la discreta La derivada (pendiente) del cambio de tipo es generalmente 0, y la derivada del cambio continuo generalmente no es 0, por lo que es fácil distinguir la calidad del modelo cuando cambia el parámetro de peso.

4.3 Diferenciación numérica

4.3.1 Derivado

 

1. La precisión de 10e-50 tendrá un error . Por ejemplo, la precisión de python float es de 4 dígitos después del punto decimal. Aquí ya es de 50 dígitos, por lo que debe cambiarse a 10e-4  redondeo de error

2. El error de f (x + h) -f (x) / h (diferencia hacia adelante) también es muy grande, porque según el cambio de 1, h no es un número que se aproxime a 0 , por lo que el error se hace mayor y se debe usar el centro Cambie el método af (x + h) -f (xh) / 2h (diferencia central)

El proceso de usar pequeñas diferencias para encontrar derivadas se llama diferenciación numérica (diferenciación numérica)

Diferenciación numérica ( gradiente numérico )

Código mejorado

La sensación del teorema de la mediana

Nota:

Este tipo de proceso de derivada que utiliza pequeñas diferencias es la diferenciación numérica , y la derivación de fórmulas matemáticas como y = x² y la derivada es y = 2x. Este tipo de derivación analítica cruzada se llama derivada verdadera.

4.3.2 Un ejemplo de diferenciación

Como y = 0.01x² + 0.1x realización de derivada

Se puede encontrar que el error de código diferencial mejorado es muy pequeño

Código de diferenciación numérico:

4.3.3 Derivada parcial

Como la derivada parcial

Primero observe la implementación del código y la imagen de esta función:

Realización de la derivada parcial: el principio es en realidad el mismo que la derivada de una variable, que es traer un valor verdadero y eliminar una variable.

La fórmula es difícil de diferenciar numéricamente . Verifique la derivada parcial a simple vista. La primera fórmula es 2 * X0

4.4 Gradiente

En el ejemplo anterior, calculamos las derivadas parciales de x0 y x1 por variables. Ahora, queremos calcular las derivadas parciales de x0 y x1 juntas. como

Por ejemplo, si encontramos una función y = x0² + x1², las variables tienen x0 y x1. Cuando sumamos todas sus variables (solo hay 2 como máximo), la variable se llama gradiente.

Gráfico dirigido por gradiente

En esta figura se puede ver que el valor de la función del punto señalado por el gradiente se hace cada vez más pequeño, y viceversa ¡Esta es una propiedad importante del gradiente!

4.4.1 Método de gradiente

Encuentre el método de gradiente mínimo llamado descenso de gradiente (método de descenso de gradiente), para encontrar el método de gradiente máximo se denomina método de gradiente ascendente (método de ascenso de gradiente ).

En la red neuronal (aprendizaje profundo), el método de gradiente se refiere principalmente al método de descenso de gradiente

A partir del gradiente anterior, podemos saber que el gradiente en realidad está buscando el lugar donde el gradiente es 0 , pero el gradiente de 0 no es necesariamente el valor mínimo (el punto objetivo en el número alto) , puede ser un valor mínimo o un punto de silla (en cierta dirección, es extremo Valor pequeño, la otra dirección es el valor máximo, el punto donde la derivada es 0), por lo que podemos calcular el gradiente una vez y luego calcular el gradiente nuevamente, para que finalmente podamos encontrar el punto mínimo real. Este es el método del gradiente.

La tasa de aprendizaje determina cuánto se debe aprender en una sesión de aprendizaje y en qué medida se deben actualizar los parámetros .

Nota: Encontrar el más pequeño es en realidad lo mismo que encontrar el más grande. Es solo una cuestión de tomar el negativo. No se preocupe demasiado por esto.

(Método de descenso de gradiente) implementación del código:

numerical_gradient (f, x) encontrará el gradiente de la función , utilizará el valor obtenido al multiplicar el gradiente por la tasa de aprendizaje para realizar la operación de actualización, y el número de repeticiones se especifica mediante step_num.

Los valores finales de x obtenidos en este ejemplo son todos números muy pequeños, casi tendiendo a 0. De acuerdo con el método analítico (pruebe con su propio lápiz) sabemos que el valor mínimo es (0,0), que es casi el mismo que el ejemplo anterior ( En ejemplos reales, el valor mínimo no es necesariamente 0).

El proceso después de cada derivada:

Código de implementación:

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
from gradient_2d import numerical_gradient #求梯度,原理与数值微分相同

#梯度下降法
def gradient_descent(f, init_x, lr=0.01, step_num=100):
    x = init_x
    x_history = []

    for i in range(step_num):
        # 记录前一个x,用于绘图痕迹
        x_history.append( x.copy() )
        # 梯度下降法,为梯度乘以学习率
        grad = numerical_gradient(f, x)
        x -= lr * grad

    return x, np.array(x_history)

# 求偏导,np.sum(x**2)
def function_2(x):
    return x[0]**2 + x[1]**2

init_x = np.array([-3.0, 4.0])    

# 学习率为0.1
lr = 0.1
# 梯度法的重复次数
step_num = 20
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)

plt.plot( [-5, 5], [0,0], '--b')
plt.plot( [0,0], [-5, 5], '--b')
plt.plot(x_history[:,0], x_history[:,1], 'o')

plt.xlim(-3.5, 3.5)
plt.ylim(-4.5, 4.5)
plt.xlabel("X0")
plt.ylabel("X1")
plt.show()

 

A continuación, se muestra un ejemplo en el que la tasa de aprendizaje es demasiado pequeña :

Si es demasiado grande, el resultado divergerá en un número grande, si es demasiado pequeño, el resultado terminará sin actualizar.

Por lo tanto, la tasa de aprendizaje n es demasiado grande o demasiado pequeña, no es buena , la tasa de aprendizaje se denomina hiperparámetro y, en general, se considera que toma un valor razonable después de múltiples configuraciones .

Los parámetros como la tasa de aprendizaje se denominan hiperparámetros.

En relación con los parámetros de peso de las redes neuronales que se obtienen automáticamente a través de datos de entrenamiento y algoritmos de aprendizaje, los hiperparámetros como la tasa de aprendizaje se configuran manualmente.

4.4.2 El gradiente de la red neuronal

El gradiente se refiere al gradiente de la función de pérdida con respecto al parámetro de peso.

Como se muestra en la figura, tenemos 2 * 3 W parámetros de peso, L es la función de pérdida y el gradiente está representado por, como se muestra en la figura:

La clase simpleNet (el código fuente está en ch04 / gradient_simplenet.py

Código:

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录中的文件而进行的设定
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient


class simpleNet:
    def __init__(self):
        # 初始化2*3权重参数
        self.W = np.random.randn(2,3)

    def predict(self, x):
        # 一层 权重乘以变量 == 一层感知机
        return np.dot(x, self.W)

    def loss(self, x, t):
        # 计算交叉熵softmax()函数的损失值
        z = self.predict(x)
        y = softmax(z)
        loss = cross_entropy_error(y, t)

        return loss

x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])

net = simpleNet()

f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)

print(dW)
Fang del excelente estudiante: https://me.csdn.net/qq_37431224
Fang del excelente estudiante: https://me.csdn.net/qq_37431224

4.5 Implementación del algoritmo de aprendizaje


Descenso de gradiente estocástico (descenso de gradiente estocástico). "Aleatorio" significa "seleccionado al azar". Por lo tanto, el método de descenso de gradiente estocástico es "método de descenso de gradiente realizado sobre datos seleccionados al azar". Abreviado como SGD

Código de implementación:

4.5.1 Clase de red neuronal de 2 capas

two_layer_net:

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
from common.functions import *
from common.gradient import numerical_gradient


class TwoLayerNet:
    """
        从第1个参数开始,依次表示:
        输入层的神经元数、隐藏层的神经元数、输出层的神经元数
        输入图像大小784 输出10个数字(0-9)
    """
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 初始化权重,是有要求的但是后面在补上
        self.params = {}
        # params变量中保存了该神经网络所需的全部参数
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)

    def predict(self, x):
        W1, W2 = self.params['W1'], self.params['W2']
        b1, b2 = self.params['b1'], self.params['b2']
    
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = softmax(a2)
        
        return y
        
    # x:输入数据, t:监督数据
    def loss(self, x, t):
        y = self.predict(x)
        return cross_entropy_error(y, t)
    
    def accuracy(self, x, t):
        y = self.predict(x)
        y = np.argmax(y, axis=1)
        t = np.argmax(t, axis=1)
        
        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy
        
    # x:输入数据, t:监督数据
    # numerical_gradient(self, x, t)
    # 基于数值微分计算参数的梯度。
    def numerical_gradient(self, x, t):
        loss_W = lambda W: self.loss(x, t)
        
        grads = {}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
        
        return grads

    # 使用误差反向传播法计算梯度
    def gradient(self, x, t):
        W1, W2 = self.params['W1'], self.params['W2']
        b1, b2 = self.params['b1'], self.params['b2']
        grads = {}
        
        batch_num = x.shape[0]
        
        # forward
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = softmax(a2)
        
        # backward
        dy = (y - t) / batch_num
        grads['W2'] = np.dot(z1.T, dy)
        grads['b2'] = np.sum(dy, axis=0)
        
        da1 = np.dot(dy, W2.T)
        dz1 = sigmoid_grad(a1) * da1
        grads['W1'] = np.dot(x.T, dz1)
        grads['b1'] = np.sum(dz1, axis=0)

        return grads

 

 

4.5.2 Implementación de mini lotes

类 : train_neuralnet :

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet

# 读入数据
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

# 超参数
iters_num = 10000  # 适当设定循环的次数
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1

train_loss_list = []
train_acc_list = []
test_acc_list = []

iter_per_epoch = max(train_size / batch_size, 1)

for i in range(iters_num):
    # 获取mini-batch
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    # 计算梯度
    #grad = network.numerical_gradient(x_batch, t_batch)
    # 高速版
    grad = network.gradient(x_batch, t_batch)
    
    # 更新参数
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]

    # 记录学习过程
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)
    
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(x_train, t_train)
        test_acc = network.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))

# 绘制图形
markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()

Se puede encontrar que a medida que avanza el aprendizaje, el valor de la función de pérdida disminuye continuamente . Esta es una señal de que el aprendizaje se está desarrollando con normalidad, lo que indica que los parámetros de peso de la red neuronal se ajustan gradualmente a los datos . En otras palabras, ¡la red neuronal está aprendiendo! Al verterle datos (de entrada) repetidamente , la red neuronal se acerca gradualmente a los parámetros óptimos.

La línea continua representa la precisión del reconocimiento de los datos de entrenamiento y la línea discontinua representa la precisión del reconocimiento de los datos de la prueba.

4.5.3 Evaluación basada en datos de prueba

Este resultado por sí solo no indica que la red neuronal deba poder funcionar en el mismo grado en otros conjuntos de datos.

En el aprendizaje de la red neuronal, es necesario confirmar si puede reconocer correctamente otros datos además de los de entrenamiento, es decir, confirmar si se producirá un sobreajuste.

Para evaluar la capacidad de generalización de una red neuronal, debe utilizar datos que no estén incluidos en los datos de entrenamiento.

 Epoch es una unidad . Un e poch representa el número de actualizaciones cuando todos los datos de entrenamiento se han utilizado una vez en el aprendizaje . Por ejemplo, para 10,000 datos de entrenamiento, cuando se usa un mini-lote con un tamaño de 100 datos para el aprendizaje, el método de descenso de gradiente aleatorio se repite 100 veces y todos los datos de entrenamiento se han "visto" A. En este momento, 100 veces es una época.

El código está arriba:

La razón para calcular la precisión del reconocimiento de cada época es que si la precisión del reconocimiento siempre se calcula en el ciclo de la declaración for, tomará demasiado tiempo.

No es necesario registrar la precisión del reconocimiento con tanta frecuencia ( siempre que comprenda el cambio de la precisión del reconocimiento desde la dirección general )

resumen:

Lo que aprendiste en este capítulo

  • El conjunto de datos utilizado en el aprendizaje automático se divide en datos de entrenamiento y datos de prueba .
  • Aprender datos de entrenamiento de redes neuronales y usar el estudio de datos de prueba para evaluar la generalización del modelo
  • El aprendizaje de la red neuronal utiliza la función de pérdida como indicador y los parámetros de peso se actualizan para reducir el valor de la función de pérdida.
  • El proceso de usar la diferencia de un valor minúsculo dado para encontrar la derivada se llama diferenciación numérica .
  • Utilizando la diferenciación numérica, se puede calcular el gradiente del parámetro de peso .
  • Aunque la diferenciación numérica lleva tiempo, es muy sencilla de implementar.

Cuando necesite prestar atención, encontrará este capítulo con más contenido, se recomienda escribir :
 

nombre función
Diferenciación numérica diferencia_numérica (x)
Derivada parcial

función_2 (x)

Derivada parcial
degradado gradiente_numérico (f, x)
Descenso de gradiente gradiente_descente (f, init_x, lr = 0.01, step_num = 100)

 

El método de retropropagación de errores un poco más complicado que se implementará en el próximo capítulo puede calcular gradientes a alta velocidad.

Supongo que te gusta

Origin blog.csdn.net/qq_37457202/article/details/107486277
Recomendado
Clasificación