Aprendizaje profundo 02-Red neuronal (perceptrón multicapa MLP)

Redes neuronales

Introducción

La red neuronal es un modelo de red neuronal artificial diseñado en base a las características estructurales y funcionales del sistema nervioso biológico, que tiene una gran adaptabilidad y capacidades de mapeo no lineal. Una red neuronal se compone de múltiples neuronas (o nodos), que están conectadas entre sí mediante pesos de conexión para formar una estructura de red de múltiples capas. Cada neurona recibe señales de otras neuronas, pesa y combina linealmente estas señales y realiza una transformación no lineal a través de la función de activación, y finalmente las envía a la siguiente capa de neuronas o capa de salida.

Después de aprender el aprendizaje automático, aprender redes neuronales puede ayudarlo a obtener una comprensión más profunda de los conceptos básicos del reconocimiento de patrones y la inteligencia artificial. Las redes neuronales se utilizan ampliamente en muchos campos, como la visión por computadora, el procesamiento del lenguaje natural, el reconocimiento de voz, etc. Aprender redes neuronales permite dominar las tecnologías más punteras en estos campos y poder aplicar estas tecnologías para resolver problemas específicos. Al mismo tiempo, los métodos y algoritmos de aprendizaje de las redes neuronales también son una parte importante del aprendizaje automático. El aprendizaje de redes neuronales puede ayudarlo a comprender mejor los principios y técnicas del aprendizaje automático y, por lo tanto, aplicar mejor el aprendizaje automático para resolver problemas prácticos.

ruta de aprendizaje

Si ya aprendió el aprendizaje automático y comienza a aprender redes neuronales, puede comenzar con la red neuronal Perceptrón multicapa (MLP). MLP es uno de los modelos de redes neuronales más básicos. Su estructura es relativamente simple, fácil de entender e implementar, tiene buena escalabilidad y versatilidad y se puede aplicar a diversas tareas, como clasificación y regresión. Después de aprender MLP, puede aprender más sobre redes neuronales convolucionales (CNN para abreviar) y redes neuronales recurrentes (RNN para abreviar), que se utilizan respectivamente para problemas en campos específicos como la visión por computadora y el procesamiento del lenguaje natural. En definitiva, se recomienda empezar con MLP y poco a poco ir aprendiendo en profundidad otros tipos de redes neuronales.

Clasificación

Las redes neuronales se pueden dividir en muchos tipos diferentes. A continuación se muestran algunos tipos de redes neuronales comunes:

  1. Red neuronal feedforward: la red neuronal feedforward es el tipo más básico de red neuronal y el tipo de red neuronal más común en el aprendizaje profundo. Consta de varias neuronas según una determinada estructura jerárquica, cada neurona recibe la salida de la capa anterior y genera la salida de esta capa, realizando así la transmisión y procesamiento de información.

  2. Red neuronal convolucional: la red neuronal convolucional es un tipo de red neuronal que se utiliza específicamente para tareas de procesamiento de imágenes y visión por computadora. Puede extraer características de imágenes mediante operaciones como convolución y agrupación, logrando así tareas como clasificación de imágenes, detección de objetivos y segmentación de imágenes.

  3. Red neuronal recurrente: la red neuronal recurrente es un tipo de red neuronal que puede procesar datos de secuencia. Puede procesar datos de secuencia de cualquier longitud a través de unidades de memoria y mecanismos de activación, logrando así tareas como el procesamiento del lenguaje natural y el reconocimiento de voz.

  4. Codificador automático: un codificador automático es un tipo de red neuronal de aprendizaje no supervisado. Su objetivo es comprimir y descomprimir datos de entrada para lograr tareas como la extracción de características y la reducción de dimensionalidad.

  5. Deep Belief Network: Deep Belief Network es un tipo de red neuronal compuesta por múltiples máquinas Boltzmann restringidas. Puede lograr tareas eficientes de clasificación y aprendizaje de características mediante un preentrenamiento y ajuste fino codiciosos capa por capa.

Además de los tipos de redes neuronales enumerados anteriormente, existen muchos otros tipos de redes neuronales, como la red neuronal de retropropagación, la red de Hopfield, la máquina de Boltzmann, etc. Los diferentes tipos de redes neuronales son adecuados para diferentes tareas y tipos de datos, y es necesario seleccionar el tipo de red neuronal apropiado de acuerdo con problemas específicos.

Perceptrón multicapa (MLP)

La red neuronal MLP es un tipo de red neuronal feedforward (red neuronal feedforward). Durante el proceso de entrenamiento de la red, el gradiente debe calcularse mediante el algoritmo de retropropagación y el error se propaga desde la capa de salida a la capa de entrada para actualizar los parámetros de la red. Este proceso requiere el uso del algoritmo de retropropagación para calcular el gradiente, y en algunos tipos de redes neuronales, como las redes neuronales recurrentes (RNN), también hay bucles de retroalimentación. Además de MLP, otras redes neuronales de avance comunes incluyen redes neuronales convolucionales (CNN) y redes neuronales recurrentes (RNN).

Comprensión de la red neuronal

Echemos un vistazo a las redes neuronales con un ejemplo sencillo sólo para comprender algunos de los conceptos.
Conocemos cuatro puntos de datos (1,1)(-1,1)(-1,-1)(1,-1). Estos cuatro puntos corresponden a los cuadrantes I~IV (es decir, las categorías a las que pertenecen los datos). pertenece). , si nos dan un nuevo punto de coordenadas (como (2,2)) en este momento, ¿a qué cuadrante debería pertenecer? (Sí, por supuesto que es el Cuadrante I, pero nuestra tarea es hacerle saber a la máquina que no sabe que existe un cuadrante. Solo puede inferir basándose en la experiencia de datos históricos)
Insertar descripción de la imagen aquí

red neuronal de dos capas

Aquí construimos una red neuronal de dos capas. En teoría, una red neuronal de dos capas puede adaptarse a cualquier función. La estructura de esta red neuronal es la siguiente:
Insertar descripción de la imagen aquí
Primero, eliminamos las cosas difíciles en el camino.
Insertar descripción de la imagen aquí

capa de entrada

En nuestro caso, la capa de entrada es el valor de coordenadas, como (1,1), que es una matriz que contiene dos elementos, que también puede considerarse como una matriz de 1 2. La dimensión del elemento de la capa de entrada está estrechamente relacionada con las características de la cantidad de entrada. Si la entrada es una imagen en escala de grises de 32 × 32 píxeles, entonces la dimensión de la capa de entrada es 32 * 32.
Debido a que el propósito de toda la red neuronal es entrenar un modelo, la entrada son datos históricos. Los datos históricos tienen una determinada etiqueta de salida. Una vez que sale el modelo, la salida de los datos de entrada se puede clasificar directamente utilizando el modelo. Los datos de entrada aquí
son:

[
[1,1],
[-1,1],
[-1,-1],
[1,-1]
]

De la capa de entrada a la capa oculta

Lo que conecta la capa de entrada y la capa oculta son W1 y b1. Calculando H
a partir deh=wX+b
Si ha estudiado álgebra lineal, debe estar familiarizado con esta fórmula. Puede entenderse como w es un peso (cuanto mayor es el peso, más importante es esta característica) y b es un sesgo. Si hay múltiples características , entonces están w, recuerda w T ∗ xw^T*xwtx .
Insertar descripción de la imagen aquí
Como se muestra en la figura anterior, después de configurar la capa oculta en 50 dimensiones (que también puede entenderse como 50 neuronas), el tamaño de la matriz H es una matriz (4 * 50).
Insertar descripción de la imagen aquí

En otras palabras, 50 neuronas son una matriz con 50 características, y cada fila es su valor w. La capa de entrada aquí tiene un total de dos dimensiones, solo w1 y w2. El valor b no se mencionará aquí. Suponiendo que sea 0 ,
Insertar descripción de la imagen aquí
podemos simplificar y finalmente obtener el significado de 4*50
Insertar descripción de la imagen aquí

De la capa oculta a la capa de salida

Lo que conecta la capa oculta y la capa de salida es W2 y b2, y la entrada es el valor H de la entrada de la capa oculta. Lo mismo se hace mediante operaciones matriciales:
Y = w 2 ∗ H + b 2 Y=w2*H+b2Y=w 2h+b 2
La capa de salida final son los últimos 4 cuadrantes.
H esuna matriz de 4 50. La matriz w2 de la capa de salida es 504. Finalmente, se obtiene una matriz de 4 * 4.
No haré un dibujo detallado aquí El significado general es el siguiente.

  1. H es una matriz de 4 * 50. De hecho, una columna contiene 50 neuronas y las filas son los valores de salida H de la primera ronda de cálculo de los 4 conjuntos de datos. El propósito de la capa oculta es calcular un H valor.
  2. La matriz w de la capa de salida es 50 * 4. El propósito es comprimir 50 neuronas en 4 características de salida, que es la probabilidad de que cada conjunto de datos esté en 4 cuadrantes. Entonces el resultado final es 4*4

capa de activación

A través del cálculo de las dos ecuaciones lineales anteriores, podemos obtener el resultado final Y, pero si todavía está impresionado por el cálculo del álgebra lineal, debe saber: la operación de una serie de ecuaciones lineales se puede expresar en última instancia mediante una ecuación lineal. ecuación. En otras palabras, las dos ecuaciones anteriores se pueden expresar mediante una ecuación lineal después de combinarlas. Esto es cierto para la red neuronal doble, incluso si la profundidad de la red aumenta a 100 capas, sigue siendo la misma. En este caso, la red neuronal pierde su significado.
Entonces aquí es donde necesitamos inyectar alma a la red: la capa de activación.
En resumen, la capa de activación agrega no linealidad al resultado de la operación matricial.
Para saber por qué es necesaria, consulte: https://blog.csdn.net/liaomin416100569/article/details/130597944?spm=1001.2014.3001.5501

La capa de activación es una capa en una red neuronal, su función es agregar una función de conversión no lineal entre la señal de entrada y la señal de salida, para que la red pueda aprender y representar mejor relaciones no lineales complejas. La importancia de la capa de activación es aumentar la capacidad de expresión no lineal del modelo, de modo que la red neuronal pueda manejar mejor datos de entrada complejos, como imágenes, texto y voz. La elección de la función de activación también es muy importante: diferentes funciones de activación tienen características diferentes.
Hay tres funciones de activación de uso común en la capa de activación, a saber, la función escalonada, Sigmoide y ReLU, como se muestra a continuación:
Insertar descripción de la imagen aquí

  • Función escalonada: cuando la entrada es menor o igual a 0, la salida es 0; cuando la entrada es mayor que 0, la salida es 1.
  • Sigmoide: cuando la entrada se acerca al infinito positivo/infinito negativo, la salida está infinitamente cerca de 1/0.
  • ReLU: cuando la entrada es menor que 0, la salida es 0; cuando la entrada es mayor que 0, la salida es igual a la entrada.

Entre ellos, el valor de salida de la función escalonada salta y tiene solo dos valores, por lo que rara vez se usa; la función sigmoidea tiene un cambio muy pequeño en la pendiente de la curva (el gradiente desaparece) cuando el valor absoluto de x es grande Y el cálculo es más complicado; ReLU Es una función de activación comúnmente utilizada en la actualidad.

¿Cómo se calcula específicamente la función de activación?
Si el valor H calculado por la fórmula H = X * W1 + b1 es: (1, -2,3, -4,7 ...), luego de pasar por la capa de activación de la función escalonada, se convertirá en (1, 0,1,0,1…), después de pasar por la capa de activación ReLU, se convertirá en (1,0,3,0,7…).

Cabe señalar que después de cada cálculo de la capa oculta (operación lineal matricial), se debe agregar una capa de activación; de lo contrario, el cálculo lineal de esta capa no tendrá sentido.
En este momento, la red neuronal se vuelve como se muestra en la siguiente figura:
Insertar descripción de la imagen aquí
Todos sabemos (?) que la red neuronal se divide en dos pasos: "entrenamiento" y "uso". Si está en el paso "usar", todo el proceso se ha completado en la Figura 4. En la matriz Y (tamaño 4 * 4) obtenida, la muestra actual con el valor más grande representa la clasificación actual.

Pero para una red utilizada para "entrenamiento", la imagen de arriba no es suficiente. Al menos la salida actual Y no es lo suficientemente "bonita".

Normalización de la producción

Supongamos que el valor de salida Y de una determinada muestra puede ser una matriz como (3,1,0.1,0.5). Es cierto que podemos encontrar el valor máximo "3" dentro y encontrar la clasificación I correspondiente, pero esto no es intuitivo. Queremos que el resultado final sea probabilidad, lo que significa que podemos generar resultados como (90%, 5%, 2%, 3%), de esta manera no solo podemos encontrar la clasificación con mayor probabilidad, sino también saber la probabilidad calculada de cada valor de clasificación.
¿Cómo se calcula específicamente?
La fórmula de cálculo es la siguiente:
Insertar descripción de la imagen aquí
En pocas palabras, se lleva a cabo en tres pasos: (1) Usar e como base para elevar la potencia exponencial de todos los elementos; (2) Sumar todas las potencias exponenciales; (3) Hacer cocientes entre estas potencias exponenciales y la suma.

En el resultado obtenido de esta manera, la suma de todos los elementos debe ser 1 y cada elemento puede representar un valor de probabilidad.

A la capa que utiliza esta fórmula de cálculo para normalizar los resultados de salida la llamamos capa "Softmax". En este momento, la red neuronal quedará como se muestra a continuación:
Insertar descripción de la imagen aquí

Cómo medir la calidad de la producción

Luego de pasar la capa Softmax, obtenemos las probabilidades correspondientes a las cuatro categorías I, II, III y IV, sin embargo, cabe señalar que este es el resultado del valor de probabilidad calculado por la red neuronal, no la situación real.

Por ejemplo, el resultado de salida de Softmax es (90%, 5%, 3%, 2%), y el resultado real es (100%, 0, 0, 0). Aunque los resultados de salida se pueden clasificar correctamente, existe una brecha entre ellos y los resultados reales. La predicción de los resultados de una red excelente debe ser infinitamente cercana al 100%, por esta razón necesitamos hacer una "Cuantificación".

Una solución intuitiva es restar la probabilidad de salida de Softmax de 1, como 1-90% = 0,1. Pero un método más común e inteligente es encontrar el negativo del logaritmo.

Siguiendo usando el 90% como ejemplo, el logaritmo negativo es: -log0.9=0.046

Como puede imaginar, cuanto más cerca esté la probabilidad del 100%, más cerca estará el valor del resultado del cálculo de 0, lo que indica que el resultado es más preciso. El resultado se denomina "Error de entropía cruzada".

Nuestro propósito al entrenar redes neuronales es reducir esta "pérdida de entropía cruzada" tanto como sea posible.
Insertar descripción de la imagen aquí

Retropropagación y optimización de parámetros.

El proceso anterior es en realidad el proceso de propagación hacia adelante de la red neuronal. Para resumir en una oración: la propagación de la red neuronal es una operación matricial en la forma Y = WX + b; para agregar no linealidad a la operación matricial, La activación debe agregarse a la capa oculta, los resultados de la capa de salida deben procesarse en valores de probabilidad a través de la capa Softmax y la calidad de la red actual se cuantifica mediante la pérdida de entropía cruzada.

Después de calcular la pérdida de entropía cruzada, es hora de iniciar la propagación hacia atrás. De hecho, la retropropagación es un proceso de optimización de parámetros, y los objetos de optimización son todos W y b en la red (porque todos los demás parámetros están determinados).

La magia de la red neuronal es que puede optimizar automáticamente W y B. En el aprendizaje profundo, la cantidad de parámetros a veces alcanza cientos de millones, pero el principio de optimización es el mismo que el de nuestra red neuronal de dos capas.

Las redes neuronales requieren iteraciones repetidas. Como en el ejemplo anterior, la probabilidad calculada por primera vez es del 90% y el valor de pérdida de entropía cruzada es 0,046; el valor de pérdida se propaga hacia atrás para realizar los ajustes correspondientes de W1, b1, W2 y b2; y se realiza la segunda operación, en este momento la probabilidad puede aumentar al 92%, en consecuencia, el valor de pérdida también disminuirá y luego el valor de pérdida se propagará hacia atrás para ajustar los parámetros W1, b1, W2, y b2. Y así sucesivamente, el valor de la pérdida se hace cada vez más pequeño hasta que estamos satisfechos.

En este punto tenemos los ideales W1, b1, W2, b2.

Para obtener más información, consulte el capítulo sobre cómo derivar el algoritmo BP.

Referencia de contenido: https://zhuanlan.zhihu.com/p/65472471

sobreajuste

El abandono es una técnica utilizada en redes neuronales para evitar el sobreajuste. Se implementa estableciendo aleatoriamente la salida de algunos nodos en 0 durante el entrenamiento. Específicamente, cada nodo tiene una cierta probabilidad de "apagarse", es decir, su salida se establece en 0. De esta manera, las conexiones entre nodos se interrumpen aleatoriamente, lo que obliga a la red a aprender características más sólidas en lugar de depender de nodos o conexiones específicos. Esta aleatoriedad puede verse como una técnica de regularización que puede prevenir eficazmente el sobreajuste.

El sobreajuste se refiere al fenómeno de que un modelo funciona bien con los datos de entrenamiento pero tiene un mal rendimiento con los datos de prueba. Esto generalmente se debe a que el modelo es demasiado complejo y los datos de entrenamiento son muy pocos o demasiado ruidosos. Al utilizar la tecnología Dropout, podemos reducir la complejidad del modelo y hacerlo más adaptable a diferentes datos de entrenamiento. De esta manera, podemos generalizar mejor el modelo y así lograr un mejor rendimiento en los datos de prueba.

Supongamos que tenemos una tarea de clasificación binaria y necesitamos identificar perros y gatos a partir de imágenes. Usamos redes neuronales convolucionales para el entrenamiento, pero debido al pequeño conjunto de datos, es probable que ocurran problemas de sobreajuste.

Para resolver este problema, podemos agregar una capa de abandono a la red neuronal convolucional. Por ejemplo, podemos agregar una capa de abandono antes de la capa completamente conectada y establecer su probabilidad de salida en 0,5. Esto significa que en cada lote de entrenamiento, las salidas de la mitad de los nodos de la capa se establecerán aleatoriamente en 0. De esta manera, la red no depende demasiado de nodos o conexiones específicos y puede adaptarse mejor a diferentes datos de entrenamiento.

Derivación del algoritmo BP

definición

Primero, aquí hay una definición del algoritmo de retropropagación (reimpreso de Wikipedia): Backpropagation (inglés: Backpropagation, abreviado como BP) es la abreviatura de "error backpropagation" y es un método de optimización (como el método de descenso de gradiente) Métodos comunes utilizados para entrenar redes neuronales artificiales. Este método calcula el gradiente de la función de pérdida para todos los pesos de la red. Este gradiente se retroalimenta al método de optimización, que se utiliza para actualizar los pesos para minimizar la función de pérdida. (Retropropagación del error)

Explicación del algoritmo

Si le pregunta a alguien que conoce el algoritmo BP "¿Cómo derivar el algoritmo BP?", la respuesta que obtendrá probablemente sea "¿No es sólo la regla de derivación de la cadena?" Creo que esta respuesta no es útil para la persona que pregunta. la pregunta. Es bueno que la derivación de BP requiera una derivación en cadena, pero el interrogador a menudo quiere una respuesta intuitiva: después de todo, la comprensión es el rey. La respuesta intuitiva no es otra que los diagramas.
Nota: La siguiente imagen es de hecho el algoritmo de retropropagación, pero no es el backprop en el aprendizaje profundo. Sin embargo, la idea general de retroceder es la misma. Después de todo, el error no se puede calcular de adelante hacia atrás. (El gráfico computacional se opera en el aprendizaje profundo). Si no comprende la oración anterior por el momento, puede fingir que no lo dije. No importa ~ (¿manualmente?)

Los siguientes dos conjuntos de imágenes se utilizan para explicar los algoritmos de propagación hacia adelante y hacia atrás de las redes neuronales. El primer conjunto de imágenes proviene de un sitio web extranjero, con imágenes vívidas. Si le resulta difícil explicarlo y comprenderlo simplemente, puede consultar el segundo conjunto de imágenes: un ejemplo específico de algoritmos de propagación hacia adelante y hacia atrás. ¡Creo que incluso un novato que acaba de comenzar (siempre que tenga un poco de conocimiento básico de matemáticas avanzadas) definitivamente puede comprender el algoritmo de retropropagación!

Primero, tome una red neuronal simple de tres capas como ejemplo, de la siguiente manera:
Insertar descripción de la imagen aquí
cada neurona se compone de dos partes: la primera parte (e) es la suma de los productos del valor de entrada y el coeficiente de peso, y la segunda parte (e) es la suma de los productos del valor de entrada y el coeficiente de peso. (f (e)) es una activación La salida de la función (función no lineal), y = f (e) es la salida de una determinada neurona, de la siguiente manera:
Insertar descripción de la imagen aquí

propagación hacia adelante

Propagación de la red neuronal de primera capa.

donde wx 1 1 w_{x1}1wx1 _1 significa que x1 corresponde al valor w de la primera neurona,wx 2 1 w_{x2}1wx2 _1 , indicando que x2 corresponde al valor w de una neurona.

Insertar descripción de la imagen aquí
La segunda capa de propagación de redes neuronales
Insertar descripción de la imagen aquí
La tercera capa de propagación de redes neuronales
Insertar descripción de la imagen aquí

Propagación hacia atrás

Hasta ahora, la propagación hacia adelante de la red neuronal se ha completado y la salida final y es el resultado (resultado de predicción) calculado por la red neuronal de propagación hacia adelante, pero este resultado de predicción no es necesariamente correcto y debe compararse con la etiqueta real. ( z) Compara y calcula el error ( δ \deltaδ ), de la siguiente manera:
Insertar descripción de la imagen aquí
Comencemos a calcular el error de cada neurona (δ \deltaδ )
Insertar descripción de la imagen aquí
Calcule el error de la primera capa.
Insertar descripción de la imagen aquí
A continuación, usaremos el error de retropropagación para calcular la derivada de cada neurona (peso), e iniciaremos la retropropagación para modificar el peso. Calcularemos la
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
segunda w
Insertar descripción de la imagen aquí
para calcular la tercera capa
Insertar descripción de la imagen aquí
. En este punto, se han completado la dirección frontal de toda la red, la propagación hacia atrás y la actualización del peso.

Ejemplos específicos

Incluso si lee todo lo anterior confundido, a través de los siguientes ejemplos, creo que la mayoría de las personas pueden entender fácilmente el algoritmo BP. La siguiente imagen es una red neuronal simple, por ejemplo:
Insertar descripción de la imagen aquí
la siguiente es la operación directa (feedforward) (la función de activación es sigmoidea):
Insertar descripción de la imagen aquí
la siguiente es la propagación hacia atrás (encontrar el gradiente del error de la red para cada parámetro de peso):

Primero encontremos el más simple, encontremos la derivada del error E con respecto a w5. En primer lugar, está claro que se trata de un proceso de "derivación en cadena". Para preguntar por la derivada del error E con respecto a w5, primero debemos encontrar la derivada del error E con respecto a out o1, luego encontrar la derivada de o1 con respecto a o1 neto, y finalmente encontrar la derivada de o1 neto con respecto a w5.Derivada, a través de esta regla de la cadena, podemos encontrar la derivada (derivada parcial) del error E con respecto a w5, como se muestra en La siguiente figura:
Insertar descripción de la imagen aquí
Se ha calculado la derivada (gradiente), y el siguiente es el proceso de retropropagación y actualización de parámetros:
Insertar descripción de la imagen aquí
arriba Las imágenes son muy obvias. Si aún no lo entiendes, realmente tienes que callarte y pensar en ello. (Es broma ~) Si miras pacientemente las imágenes de arriba, definitivamente lo entenderás.

Si desea encontrar la derivada del error E con respecto a w1, habrá más de una ruta de derivación del error E con respecto a w1, lo cual será un poco más complicado, pero cambiar la sopa no cambia la medicina. El proceso de cálculo es el siguiente:
Insertar descripción de la imagen aquí

Referencia de derivación de pb: https://blog.csdn.net/ft_sunshine/article/details/90221691

combate real de tensorflow

Cargar conjunto de datos

keras.datasets.mnist es un conjunto de datos de dígitos escritos a mano integrado en el marco de Keras, que contiene 60.000 imágenes de entrenamiento y 10.000 imágenes de prueba. Cada imagen es una imagen en escala de grises de 28x28 píxeles y el valor de cada píxel oscila entre 0 y 255. Este conjunto de datos se utiliza comúnmente para tareas de clasificación de imágenes y reconocimiento de dígitos en el campo del aprendizaje automático.

El valor de retorno de keras.datasets.mnist es una tupla (x_train, y_train), (x_test, y_test), que representa el conjunto de entrenamiento y el conjunto de prueba respectivamente. Entre ellos, x_train y x_test son matrices numerosas con formas de (60000, 28, 28) y (10000, 28, 28) respectivamente, que representan datos de imagen. y_train e y_test son matrices numerosas con formas (60000,) y (10000,), que representan las etiquetas de imagen correspondientes, es decir, los números representados por cada imagen.
Registre el conjunto de datos y dibuje las primeras 20 imágenes.

#%%

from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt

# 加载数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_test_ori=x_test 
# 打印数据集信息
print('训练集图像数据形状:', x_train.shape)
print('训练集标签数据形状:', y_train.shape)
print('测试集图像数据形状:', x_test.shape)
print('测试集标签数据形状:', y_test.shape)

# 绘制前20张训练集图像
plt.figure(figsize=(10, 10))
for i in range(20):
    plt.subplot(5, 5, i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(x_train[i], cmap=plt.cm.binary)
    plt.xlabel(y_train[i])
plt.show()

producción

训练集图像数据形状: (60000, 28, 28)
训练集标签数据形状: (60000,)
测试集图像数据形状: (10000, 28, 28)
测试集标签数据形状: (10000,)

Insertar descripción de la imagen aquí

La ruta de descarga de imágenes predeterminada es ~/.keras/datasets, en la ventana: C:\Users\current nombre de usuario.keras\datasets, el tamaño se estima en unos 10 MB.

Preprocesamiento de datos

x_train = x_train.reshape(x_train.shape[0], 784).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], 784).astype('float32') / 255
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

En el código anterior, convertimos la dimensión de los datos de entrada de 28x28 a 784, porque los datos que procesamos generalmente son una matriz y una fila representa una muestra de datos. Debe convertirse en datos de 784 * 1 y el rango de valores de píxeles Escala de 0-255 a 0-1. Al mismo tiempo, realizamos una codificación one-hot en los datos de la etiqueta y los convertimos en un vector de 10 dimensiones, donde cada dimensión representa un número.

codificación de un solo host

La codificación one-hot es una técnica que convierte variables discretas en variables continuas y se usa ampliamente en aprendizaje automático y aprendizaje profundo. Codifica el valor de cada variable discreta en un bit binario, de los cuales solo un bit binario es 1 y los bits binarios restantes son 0. Los ejemplos son los siguientes:

Supongamos que existe una variable discreta "color" cuyos valores posibles son "rojo", "amarillo" y "azul". Podemos codificar estos tres valores en un vector binario de longitud 3 de la siguiente manera:

Rojo: [1, 0, 0]

Amarillo: [0, 1, 0]

Azul: [0, 0, 1]

Este método de codificación es codificación one-hot. En el aprendizaje automático, podemos utilizar este método de codificación para procesar variables discretas y convertirlas en variables continuas para facilitar el aprendizaje y el uso del modelo.

keras.utils.to_categorical()

keras.utils.to_categorical()La función convierte etiquetas de categorías de números enteros en codificación one-hot. En la codificación one-hot, cada etiqueta de categoría se representa como un vector con una longitud igual al número total de categorías, en el que el valor de posición correspondiente a la etiqueta de categoría es 1 y las posiciones restantes son 0.

Para la tarea de reconocimiento de dígitos escritos a mano, hay 10 categorías en total, es decir, los números del 0 al 9, por lo que el vector de etiqueta debe convertirse en una codificación unidimensional de 10 dimensiones.

Por ejemplo, si la etiqueta original es 5, la codificación one-hot convertida es [0, 0, 0, 0, 0, 1, 0, 0, 0, 0], donde el valor de la sexta posición (comenzando desde 0) es 1, lo que indica que la etiqueta original es 5.

El propósito de esto es permitir que la red neuronal comprenda mejor las diferencias y similitudes entre categorías para que pueda realizar predicciones de clasificación más precisas.

Construir un modelo de perceptrón multicapa

Usamos keras.Sequential para construir un modelo que contiene una capa de entrada, una capa oculta y una capa de salida. La dimensión de la capa de entrada es 784 (es decir, el número de píxeles en cada imagen), la capa oculta contiene 512 neuronas, la función de activación es ReLU, la capa de salida contiene 10 neuronas y la función de activación es softmax. Al mismo tiempo, utilizamos Dropout para evitar el sobreajuste.

# 构建模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(512, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

tf.keras.secuencial

keras.Sequential es una clase en Keras, que se utiliza para construir rápidamente modelos de redes neuronales. Proporciona una forma sencilla de crear modelos secuenciales, es decir, modelos en los que una serie de capas se apilan una encima de otra en orden. En keras.Sequential, puedes construir una red neuronal agregando capas.

keras.Sequential se define de la siguiente manera:

keras.Sequential(
    layers=None, 
    name=None
)

Entre ellos, capas es una lista que contiene capas apiladas en orden; nombre es el nombre del modelo.
El ejemplo anterior del uso de keras.Sequential para crear una red neuronal simple:

model = tf.keras.Sequential([
    tf.keras.layers.Dense(512, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

Creamos un modelo de red neuronal con tres capas. La primera capa es una capa completamente conectada, que contiene 512 neuronas, utiliza la función de activación ReLU y la forma de entrada es (784,). La segunda capa es una capa de abandono y la tercera capa es una capa completamente conectada que contiene 10 neuronas y utiliza la función de activación Softmax.

keras.capas.densas

keras.layers.Dense es una clase en Keras que se utiliza para crear capas completamente conectadas. La capa completamente conectada es la capa más básica de la red neuronal: cada neurona de ella está conectada a cada neurona de la capa anterior. keras.layers.Dense se puede utilizar para crear capas de entrada, capas de salida y capas ocultas.

keras.layers.Dense se define de la siguiente manera:

keras.layers.Dense(
    units, 
    activation=None, 
    use_bias=True, 
    kernel_initializer='glorot_uniform', 
    bias_initializer='zeros', 
    kernel_regularizer=None, 
    bias_regularizer=None, 
    activity_regularizer=None, 
    kernel_constraint=None, 
    bias_constraint=None, 
    **kwargs
)

Entre ellos, las unidades representan el número de neuronas en la capa; la activación representa la función de activación de la capa; use_bias representa si se debe usar el sesgo; kernel_initializer representa el método de inicialización de la matriz de peso; sesgo_initializer representa el método de inicialización del vector de sesgo; kernel_regularizer , sesgo_regularizer y Activity_regularizer representan elementos de regularización; kernel_constraint, sesgo_constraint representan elementos de restricción.

A continuación se muestra un ejemplo del uso de keras.layers.Dense para crear una capa completamente conectada:

import tensorflow.keras as keras
layer =  tf.keras.layers.Dense(512, activation='relu', input_shape=(784,)),

En este ejemplo, creamos una capa completamente conectada que contiene 512 neuronas. La función de activación es ReLU y la forma de entrada es (784,), lo que significa que los datos de entrada de esta capa son un vector con una longitud de 784.

Algunos parámetros y métodos comunes de keras.layers.Dense:

  • unidades: el número de neuronas en esta capa;
  • activación: función de activación de esta capa;
  • use_bias: si se debe utilizar el sesgo;
  • kernel_initializer: método de inicialización de la matriz de pesos;
  • sesgo_initializer: método de inicialización del vector de sesgo;
  • kernel_regularizer, sesgo_regularizer, Activity_regularizer: elementos de regularización;
  • kernel_constraint, sesgo_constraint: elementos de restricción;
  • Layer.get_weights(): obtiene la matriz de peso y el vector de sesgo de esta capa;
  • Layer.set_weights (pesos): establece la matriz de peso y el vector de sesgo de esta capa.
    Lo anterior es información básica y el uso de keras.layers.Dense.

keras.capas.Abandono

tf.keras.layers.Dropout es un método de regularización aplicado en redes neuronales para reducir los efectos del sobreajuste. Durante el entrenamiento, la capa Dropout establece aleatoriamente una parte de los elementos del tensor de entrada en 0, lo que obliga a la red a aprender una representación de características más sólida y evita el sobreajuste. Específicamente, la capa de abandono establece aleatoriamente la salida de una parte de las neuronas del tensor de entrada en 0 con una cierta probabilidad (generalmente 0,5). Estas neuronas enmascaradas no participarán en la propagación hacia adelante ni hacia atrás. Hacerlo obliga a la red a aprender más funciones durante el entrenamiento y hace que la red sea más robusta ante pequeños cambios en la entrada.

En tf.keras.layers.Dropout, puede establecer un parámetro de velocidad para controlar la proporción de neuronas protegidas, es decir, establecer aleatoriamente cuántos elementos del tensor de entrada son 0. Específicamente, si tasa = 0,5, significa que el 50% de las neuronas se seleccionan aleatoriamente para generar 0 durante el proceso de entrenamiento y no se realizan operaciones durante el proceso de prueba. Al mismo tiempo, la capa tf.keras.layers.Dropout se puede colocar en cualquier lugar de la red neuronal, generalmente después de la capa completamente conectada, para reducir el impacto del sobreajuste.

La función principal de la capa Dropout es reducir el impacto del sobreajuste, mejorando así la capacidad de generalización del modelo. Al proteger aleatoriamente algunas neuronas, la capa de abandono puede obligar a la red a aprender una representación de características más sólida y hacer que la red sea más robusta ante pequeños cambios en la entrada. Esto puede aumentar la solidez del modelo y mejorar la capacidad de generalización del modelo, lo que hace que el modelo funcione mejor en el conjunto de pruebas.

Cabe señalar que la capa de abandono no debe usarse durante el proceso de prueba, porque el proceso de prueba requiere la propagación hacia adelante de todo el modelo en lugar de configurar algunas neuronas en 0. Por lo tanto, durante el proceso de prueba, todas las neuronas deben participar en la propagación hacia adelante para obtener resultados de predicción más precisos. Para resolver este problema, puede utilizar la capa Dropout durante el proceso de capacitación y desactivar la capa Dropout durante el proceso de prueba, o ajustar la salida de acuerdo con las características de Dropout.

keras.capas.otros

keras.layersEl módulo proporciona muchas clases de capas de redes neuronales comunes. Algunas de las capas comúnmente utilizadas incluyen:

  • Dense: Capa completamente conectada, cada nodo de entrada está conectado al nodo de salida
  • Conv2D: Capa de convolución bidimensional, que realiza operaciones de convolución en imágenes u otras entradas bidimensionales.
  • MaxPooling2D: Capa de agrupación máxima bidimensional, que reduce la resolución de la entrada
  • Dropout: Descarte aleatoriamente una parte de los nodos de entrada para reducir el sobreajuste
  • Flatten: Aplana la entrada en un tensor unidimensional
  • Activation: Capa de función de activación, como ReLU, Sigmoid, Softmax, etc.
  • BatchNormalization: Capa de normalización por lotes, utilizada para acelerar la convergencia y reducir el sobreajuste
  • Embedding: Capa de incrustación de palabras, convierte palabras discretas en representaciones vectoriales continuas
  • LSTM: Capa de bucle de memoria larga a corto plazo, utilizada para procesar datos de series de tiempo
  • GRU: Capa de unidad recurrente cerrada, utilizada para procesar datos de series de tiempo

Estas capas se pueden combinar o apilar para construir modelos complejos de redes neuronales. Además de estas capas comúnmente utilizadas, también se keras.layersproporcionan muchas otras capas, como Conv1D, Conv3D, UpSampling2D, SeparableConv2D, GlobalMaxPooling2Detc. GlobalAveragePooling2DLa capa adecuada se puede seleccionar en función de los requisitos de la tarea específica.

Compilación de modelos

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

Este código se utiliza para compilar el modelo, que contiene tres parámetros:

  1. optimizador: Optimizador, utilizado para controlar la tasa de aprendizaje del modelo. Aquí utilizamos el optimizador Adam, que es un optimizador ampliamente utilizado que puede ajustar de forma adaptativa la tasa de aprendizaje.

  2. pérdida: función de pérdida, utilizada para medir el error del modelo durante el proceso de entrenamiento. Aquí utilizamos la función de pérdida de entropía cruzada, que es adecuada para problemas de clasificación múltiple y puede medir eficazmente la diferencia entre las predicciones del modelo y las etiquetas verdaderas.

  3. Métricas: Indicadores de evaluación, utilizados para evaluar el desempeño del modelo. Aquí, utilizamos la precisión como métrica de evaluación, que puede medir la precisión de clasificación del modelo en el conjunto de prueba.

En general, el propósito de este código es especificar el optimizador, la función de pérdida y las métricas de evaluación que el modelo utilizará durante el proceso de capacitación.

optimizador

Los optimizadores más utilizados incluyen los siguientes:

  1. Descenso de gradiente estocástico (SGD): Es el optimizador más básico y sencillo, busca la solución óptima mediante iteración continua, la cadena correspondiente es: 'sgd'.

  2. Adam: Es uno de los optimizadores más utilizados actualmente. Combina las ventajas de Adagrad y RMSprop. La cadena correspondiente es: 'adam.

  3. Adagrad: ajusta de forma adaptativa la tasa de aprendizaje de cada parámetro, adecuado para conjuntos de datos dispersos, la cadena correspondiente es: 'adagrad.

  4. RMSprop: Similar a Adagrad, pero utiliza una media móvil ponderada exponencialmente del cuadrado del gradiente para adaptarse mejor a funciones objetivo no estacionarias. La cadena correspondiente es: 'rmsprop.

  5. Adadelta: combina las ventajas de Adagrad y RMSprop y al mismo tiempo resuelve el problema de la rápida disminución de la tasa de aprendizaje de Adagrad. La cadena correspondiente es: 'adadelta.

  6. Adamax: Es una variante de Adam que utiliza la norma L∞ en lugar de la norma L2. La cadena correspondiente es: 'adamax.

  7. Nadam: Es una combinación del impulso de Adam y Nesterov, que puede adaptarse mejor a funciones convexas y no convexas. La cadena correspondiente es: 'nadam.

Los anteriores son optimizadores de uso común. Cada optimizador tiene sus ventajas y desventajas. La elección del optimizador adecuado debe basarse en escenarios y tareas específicos.

función de pérdida

Las funciones de pérdida comunes incluyen:

  1. Error cuadrático medio (MSE): esta función de pérdida se usa a menudo en problemas de regresión para calcular el promedio de las diferencias al cuadrado entre el valor predicho y el valor real.
    La representación de cadena en Keras es: 'mse'

  2. Pérdida de entropía cruzada (CE): esta función de pérdida se utiliza a menudo en problemas de clasificación y mide la capacidad de ajuste del modelo calculando la entropía cruzada entre el valor predicho y el valor real.
    La representación de cadena en Keras es: 'categorical_crossentropy' (para problemas de clasificación múltiple) o 'binary_crossentropy' (para problemas de clasificación binaria).

  3. Pérdida logarítmica (LogLoss): esta función de pérdida se usa a menudo en problemas de clasificación binaria y mide la capacidad de ajuste del modelo calculando la pérdida logarítmica entre el valor predicho y el valor real.
    La representación de cadena en Keras es: 'binary_crossentropy'

  4. Función de pérdida de bisagra: esta función de pérdida se usa a menudo en modelos de máquina de vectores de soporte (SVM) para medir la capacidad de ajuste del modelo calculando la pérdida de bisagra entre el valor predicho y el valor real.
    La representación de cadena en Keras es: 'bisagra'

  5. Función de pérdida de Huber: esta función de pérdida se utiliza a menudo en problemas de regresión para medir la capacidad de ajuste del modelo calculando la pérdida suave L1 entre el valor predicho y el valor real.
    La representación de cadena en Keras es: 'huber_loss'

Por supuesto, estas son solo funciones de pérdida comunes, existen otras funciones de pérdida, como la pérdida focal, etc.

Índice de evaluación

Los indicadores de evaluación comunes incluyen:

  1. Precisión: este indicador se utiliza para problemas de clasificación y representa la proporción del número de muestras clasificadas correctamente por el modelo con respecto al número total de muestras.
    La representación de cadena en Keras es: 'precisión'

  2. Precisión: este indicador se utiliza para problemas de clasificación y representa la proporción del número de muestras predichas correctamente como clase positiva por el modelo con respecto al número total de muestras predichas como clase positiva.
    La representación de cadena en Keras es: 'precisión'

  3. Recuerde: este indicador se utiliza para problemas de clasificación y representa la proporción del número de muestras predichas correctamente como positivas por el modelo con respecto al número total de muestras que realmente son positivas.
    La representación de cadena en Keras es: 'recordar'

  4. Puntuación F1: este indicador combina precisión y recuperación, y es el promedio armónico de los dos, que puede evaluar de manera más completa el rendimiento del modelo.
    La representación de cadena en Keras es: 'f1_score'

  5. Error cuadrático medio (MSE): este indicador se utiliza en problemas de regresión y representa el error cuadrático promedio entre el valor predicho del modelo y el valor real.
    La representación de cadena en Keras es: 'mse'

  6. Error absoluto medio (MAE): este indicador se utiliza en problemas de regresión y representa el error absoluto medio entre el valor predicho del modelo y el valor real.
    La representación de cadena en Keras es: 'mae'

Por supuesto, estos son solo indicadores de evaluación comunes, y existen otros indicadores de evaluación, como el AUC.

Entrenamiento modelo

history = model.fit(x_train, y_train, 
                    epochs=10, 
                    batch_size=128, 
                    validation_data=(x_test, y_test))

En el código anterior, utilizamos model.fit para el entrenamiento de modelos, configurando 10 épocas y 128 tamaños de lote. Al mismo tiempo, utilizamos el conjunto de pruebas para la validación del modelo.

En cada época, el modelo debe entrenarse en todo el conjunto de datos de entrenamiento, en lugar de solo en una muestra o un lote. Por lo tanto, en cada época, el modelo debe realizar propagación hacia adelante y hacia atrás en todas las muestras de entrenamiento para calcular el error y el gradiente correspondientes a cada muestra, y utilizar estos gradientes para actualizar los parámetros de peso del modelo.

Para acelerar el entrenamiento del modelo, el conjunto de datos de entrenamiento generalmente se divide en varios lotes y cada lote contiene varias muestras. En cada época, el modelo divide todo el conjunto de datos de entrenamiento en varios lotes y luego realiza una propagación hacia adelante y hacia atrás en cada lote para actualizar los parámetros de peso. Por lo tanto, en cada época, el modelo necesita realizar propagación hacia adelante y hacia atrás varias veces para completar el entrenamiento de todo el conjunto de datos de entrenamiento.

Si el tamaño del lote = 128, los datos se dividen en 128 partes en una época, y cada parte se propaga hacia adelante y hacia atrás con 512 neuronas para la corrección del descenso de gradiente w y b, por lo que una época realmente realiza 128 si el algoritmo de descenso de gradiente se establece en 10
. épocas, puede entenderse como un algoritmo de descenso de gradiente de 128 * 10.
Por ejemplo, para el reconocimiento de dígitos escritos a mano, los datos se procesan durante dos épocas y 256 veces de descenso de gradiente, y la precisión alcanza el 97%.

Tenga cuidado de no procesar 60.000 muestras en un lote. La memoria no se puede utilizar. La ejecución de una época puede tardar varias horas.

Evaluación del modelo

# 评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

# 预测结果
predictions = model.predict(x_test)

En el código anterior, usamos model.evaluate para evaluar el modelo y model.predict para hacer predicciones.

Si ocurre un error durante la operación

InternalError: Intentando realizar la operación BLAS usando StreamExecutor sin soporte BLAS
[[node sequential/dense/MatMul (definido en C:\Users\liaomin\AppData\Local\Temp\ipykernel_28392\2909523142.py:25) ]] [Op:__inference_test_function_361 ]

Simplemente instálelo directamente. La versión gpu de tensorflow requiere la biblioteca blas, pero la versión cpu no.

conda install blas

Predicción del modelo

Seleccione un elemento de prueba y luego muestre la imagen y use el modelo para predecir

# 预测第10个测试数据的结果
predictions = model.predict(np.array([x_test[9]]))
print("预测结果:", np.argmax(predictions))

# 绘制第10个测试数据的图形
plt.imshow(x_test_ori[9], cmap=plt.cm.binary)
plt.show()

Insertar descripción de la imagen aquí

carrera completa

#%%

#%%

import tensorflow as tf
from tensorflow.keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
# 加载数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_test_ori=x_test
# 数据预处理
x_train = x_train.reshape(x_train.shape[0], 784).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], 784).astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)

# 构建模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(512, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

# 编译模型
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
# 训练模型
history = model.fit(x_train, y_train, 
                    epochs=2,   #这里为了节约时间,就两轮就差不多了97%正确率了,训练十次差不多0.98左右
                    batch_size=128, 
                    validation_data=(x_test, y_test))
# 评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

# 预测第10个测试数据的结果
predictions = model.predict(np.array([x_test[9]]))
print("预测结果:", np.argmax(predictions))

# 绘制第10个测试数据的图形
plt.imshow(x_test_ori[9], cmap=plt.cm.binary)
plt.show()

Resultados de salida

Epoch 1/2

  1/469 [..............................] - ETA: 2:17 - loss: 2.2535 - accuracy: 0.1562
 13/469 [..............................] - ETA: 1s - loss: 1.3687 - accuracy: 0.6358  
 25/469 [>.............................] - ETA: 1s - loss: 0.9935 - accuracy: 0.7331
 38/469 [=>............................] - ETA: 1s - loss: 0.8118 - accuracy: 0.7775
 52/469 [==>...........................] - ETA: 1s - loss: 0.7005 - accuracy: 0.8057
 59/469 [==>...........................] - ETA: 1s - loss: 0.6644 - accuracy: 0.8137
 70/469 [===>..........................] - ETA: 1s - loss: 0.6148 - accuracy: 0.8256
 83/469 [====>.........................] - ETA: 1s - loss: 0.5690 - accuracy: 0.8376
 97/469 [=====>........................] - ETA: 1s - loss: 0.5308 - accuracy: 0.8479
111/469 [======>.......................] - ETA: 1s - loss: 0.5008 - accuracy: 0.8562
124/469 [======>.......................] - ETA: 1s - loss: 0.4797 - accuracy: 0.8621
136/469 [=======>......................] - ETA: 1s - loss: 0.4648 - accuracy: 0.8659
145/469 [========>.....................] - ETA: 1s - loss: 0.4548 - accuracy: 0.8683
158/469 [=========>....................] - ETA: 1s - loss: 0.4398 - accuracy: 0.8727
172/469 [==========>...................] - ETA: 1s - loss: 0.4253 - accuracy: 0.8765
185/469 [==========>...................] - ETA: 1s - loss: 0.4145 - accuracy: 0.8802
199/469 [===========>..................] - ETA: 1s - loss: 0.3999 - accuracy: 0.8843
212/469 [============>.................] - ETA: 1s - loss: 0.3899 - accuracy: 0.8872
225/469 [=============>................] - ETA: 1s - loss: 0.3804 - accuracy: 0.8902
238/469 [==============>...............] - ETA: 0s - loss: 0.3700 - accuracy: 0.8933
252/469 [===============>..............] - ETA: 0s - loss: 0.3619 - accuracy: 0.8951
266/469 [================>.............] - ETA: 0s - loss: 0.3537 - accuracy: 0.8979
280/469 [================>.............] - ETA: 0s - loss: 0.3460 - accuracy: 0.9001
291/469 [=================>............] - ETA: 0s - loss: 0.3401 - accuracy: 0.9018
303/469 [==================>...........] - ETA: 0s - loss: 0.3350 - accuracy: 0.9032
316/469 [===================>..........] - ETA: 0s - loss: 0.3298 - accuracy: 0.9046
330/469 [====================>.........] - ETA: 0s - loss: 0.3250 - accuracy: 0.9061
343/469 [====================>.........] - ETA: 0s - loss: 0.3198 - accuracy: 0.9073
357/469 [=====================>........] - ETA: 0s - loss: 0.3132 - accuracy: 0.9090
368/469 [======================>.......] - ETA: 0s - loss: 0.3088 - accuracy: 0.9103
381/469 [=======================>......] - ETA: 0s - loss: 0.3051 - accuracy: 0.9115
395/469 [========================>.....] - ETA: 0s - loss: 0.3017 - accuracy: 0.9125
409/469 [=========================>....] - ETA: 0s - loss: 0.2970 - accuracy: 0.9139
423/469 [==========================>...] - ETA: 0s - loss: 0.2927 - accuracy: 0.9152
437/469 [==========================>...] - ETA: 0s - loss: 0.2889 - accuracy: 0.9163
448/469 [===========================>..] - ETA: 0s - loss: 0.2855 - accuracy: 0.9173
458/469 [============================>.] - ETA: 0s - loss: 0.2827 - accuracy: 0.9181
469/469 [==============================] - 3s 5ms/step - loss: 0.2800 - accuracy: 0.9189 - val_loss: 0.1337 - val_accuracy: 0.9610
Epoch 2/2

  1/469 [..............................] - ETA: 1s - loss: 0.1849 - accuracy: 0.9375
 13/469 [..............................] - ETA: 1s - loss: 0.1216 - accuracy: 0.9597
 25/469 [>.............................] - ETA: 1s - loss: 0.1333 - accuracy: 0.9584
 37/469 [=>............................] - ETA: 1s - loss: 0.1389 - accuracy: 0.9573
 49/469 [==>...........................] - ETA: 1s - loss: 0.1370 - accuracy: 0.9597
 63/469 [===>..........................] - ETA: 1s - loss: 0.1326 - accuracy: 0.9606
 75/469 [===>..........................] - ETA: 1s - loss: 0.1349 - accuracy: 0.9596
 86/469 [====>.........................] - ETA: 1s - loss: 0.1339 - accuracy: 0.9597
 98/469 [=====>........................] - ETA: 1s - loss: 0.1360 - accuracy: 0.9594
110/469 [======>.......................] - ETA: 1s - loss: 0.1385 - accuracy: 0.9587
123/469 [======>.......................] - ETA: 1s - loss: 0.1385 - accuracy: 0.9582
136/469 [=======>......................] - ETA: 1s - loss: 0.1371 - accuracy: 0.9591
147/469 [========>.....................] - ETA: 1s - loss: 0.1369 - accuracy: 0.9593
158/469 [=========>....................] - ETA: 1s - loss: 0.1361 - accuracy: 0.9595
170/469 [=========>....................] - ETA: 1s - loss: 0.1355 - accuracy: 0.9600
182/469 [==========>...................] - ETA: 1s - loss: 0.1360 - accuracy: 0.9601
194/469 [===========>..................] - ETA: 1s - loss: 0.1348 - accuracy: 0.9603
206/469 [============>.................] - ETA: 1s - loss: 0.1330 - accuracy: 0.9610
217/469 [============>.................] - ETA: 1s - loss: 0.1322 - accuracy: 0.9610
228/469 [=============>................] - ETA: 1s - loss: 0.1304 - accuracy: 0.9617
240/469 [==============>...............] - ETA: 1s - loss: 0.1301 - accuracy: 0.9616
252/469 [===============>..............] - ETA: 0s - loss: 0.1290 - accuracy: 0.9618
265/469 [===============>..............] - ETA: 0s - loss: 0.1276 - accuracy: 0.9623
278/469 [================>.............] - ETA: 0s - loss: 0.1264 - accuracy: 0.9625
291/469 [=================>............] - ETA: 0s - loss: 0.1253 - accuracy: 0.9629
304/469 [==================>...........] - ETA: 0s - loss: 0.1246 - accuracy: 0.9632
318/469 [===================>..........] - ETA: 0s - loss: 0.1235 - accuracy: 0.9635
332/469 [====================>.........] - ETA: 0s - loss: 0.1230 - accuracy: 0.9636
345/469 [=====================>........] - ETA: 0s - loss: 0.1220 - accuracy: 0.9641
358/469 [=====================>........] - ETA: 0s - loss: 0.1214 - accuracy: 0.9643
368/469 [======================>.......] - ETA: 0s - loss: 0.1210 - accuracy: 0.9644
380/469 [=======================>......] - ETA: 0s - loss: 0.1209 - accuracy: 0.9643
392/469 [========================>.....] - ETA: 0s - loss: 0.1206 - accuracy: 0.9645
404/469 [========================>.....] - ETA: 0s - loss: 0.1205 - accuracy: 0.9644
415/469 [=========================>....] - ETA: 0s - loss: 0.1206 - accuracy: 0.9643
427/469 [==========================>...] - ETA: 0s - loss: 0.1205 - accuracy: 0.9642
440/469 [===========================>..] - ETA: 0s - loss: 0.1201 - accuracy: 0.9644
452/469 [===========================>..] - ETA: 0s - loss: 0.1201 - accuracy: 0.9643
464/469 [============================>.] - ETA: 0s - loss: 0.1198 - accuracy: 0.9644
469/469 [==============================] - 2s 5ms/step - loss: 0.1198 - accuracy: 0.9644 - val_loss: 0.0944 - val_accuracy: 0.9716

  1/313 [..............................] - ETA: 8s - loss: 0.0785 - accuracy: 0.9688
 19/313 [>.............................] - ETA: 0s - loss: 0.0754 - accuracy: 0.9852
 36/313 [==>...........................] - ETA: 0s - loss: 0.0956 - accuracy: 0.9705
 54/313 [====>.........................] - ETA: 0s - loss: 0.1193 - accuracy: 0.9641
 73/313 [=====>........................] - ETA: 0s - loss: 0.1268 - accuracy: 0.9606
 93/313 [=======>......................] - ETA: 0s - loss: 0.1233 - accuracy: 0.9610
112/313 [=========>....................] - ETA: 0s - loss: 0.1196 - accuracy: 0.9637
130/313 [===========>..................] - ETA: 0s - loss: 0.1234 - accuracy: 0.9618
151/313 [=============>................] - ETA: 0s - loss: 0.1204 - accuracy: 0.9617
171/313 [===============>..............] - ETA: 0s - loss: 0.1137 - accuracy: 0.9642
191/313 [=================>............] - ETA: 0s - loss: 0.1163 - accuracy: 0.9638
210/313 [===================>..........] - ETA: 0s - loss: 0.1119 - accuracy: 0.9658
230/313 [=====================>........] - ETA: 0s - loss: 0.1048 - accuracy: 0.9681
245/313 [======================>.......] - ETA: 0s - loss: 0.1003 - accuracy: 0.9695
263/313 [========================>.....] - ETA: 0s - loss: 0.0979 - accuracy: 0.9699
282/313 [==========================>...] - ETA: 0s - loss: 0.0943 - accuracy: 0.9712
303/313 [============================>.] - ETA: 0s - loss: 0.0911 - accuracy: 0.9723
313/313 [==============================] - 1s 3ms/step - loss: 0.0944 - accuracy: 0.9716
Test accuracy: 0.9715999960899353

Guardado y carga del modelo.

TensorFlow proporciona dos formas de guardar y cargar modelos:
1. Utilice tf.train.Checkpoint:

import tensorflow as tf

# 定义模型
model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(10, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dense(10, activation='softmax')
])

# 定义优化器和损失函数
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test))

# 创建 Checkpoint 对象
checkpoint = tf.train.Checkpoint(model=model)

# 保存模型
checkpoint.save('./model.ckpt')

# 加载模型
checkpoint.restore('./model.ckpt')

2. Utilice tf.keras.callbacks.ModelCheckpoint:

import tensorflow as tf

# 定义模型
model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(10, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dense(10, activation='softmax')
])

# 定义优化器和损失函数
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 定义 ModelCheckpoint 回调函数
checkpoint = tf.keras.callbacks.ModelCheckpoint('./model.h5', save_best_only=True, save_weights_only=False, monitor='val_loss')

# 训练模型
model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test), callbacks=[checkpoint])

# 加载模型
model = tf.keras.models.load_model('./model.h5')

El primer método utiliza el objeto tf.train.Checkpoint para guardar y cargar el modelo, lo que puede guardar los pesos y el estado del optimizador del modelo. También admite guardar y restaurar el modelo durante el proceso de entrenamiento. El segundo método utiliza la función de devolución de llamada tf.keras.callbacks.ModelCheckpoint para guardar el modelo. Puede especificar guardar el mejor modelo y puede elegir guardar los pesos del modelo o el modelo completo.

Dibujar reconocimiento de números escritos a mano en la interfaz de usuario

Primero reescribe el código tensorflow anterior para guardar el modelo.

# 定义 ModelCheckpoint 回调函数
checkpoint = tf.keras.callbacks.ModelCheckpoint('./model.h5', save_best_only=True, save_weights_only=False, monitor='val_loss')

# 训练模型
history = model.fit(x_train, y_train, 
                    epochs=8, 
                    batch_size=128, 
                    validation_data=(x_test, y_test),
                    callbacks=[checkpoint]
                    )

Dibuje la interfaz de usuario, cargue el modelo y prediga la visualización en la interfaz de usuario

import tkinter as tk
from PIL import Image, ImageDraw
import numpy as np;
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
# 加载模型并进行数字识别
def recognize_digit():
    # 将画板图像转换成灰度图像,并将其大小调整为 28x28,注意要用convert,因为彩色图像是rgb是三维的,resize只是改变了rg,需要convert转换成灰度的二维
    image_resized = np.array(image.resize((28, 28)).convert('L'))
    # 反转图像,因为灰度图像是黑底白字,但是我们训练的图片都是白底黑字,所以取反
    image_resized = np.invert(image_resized)
    # plt.imshow(image_resized, cmap=plt.cm.binary)
    # plt.show()
    # 将图像转换为数字数组
    data = image_resized.reshape(1, 784).astype('float32') / 255.0

    # 在这里添加您的识别代码
    model = tf.keras.models.load_model('./model.h5')
    predictions = model.predict(np.array([data]))
    result_label.configure(text="识别结果为:" + str(np.argmax(predictions)))

# 清空画板
def clear_canvas():
    draw.rectangle((0, 0, 280, 280), fill="white")
    canvas.delete("all")

# 创建窗口
window = tk.Tk()
window.title("手写数字识别")
window.geometry("400x400")

# 创建画布
canvas = tk.Canvas(window, width=280, height=280, bg="white")
canvas.grid(row=0, column=0, columnspan=2)

# 创建清空画布按钮
clear_button = tk.Button(window, text="清空画板", command=clear_canvas)
clear_button.grid(row=1, column=0)

# 创建识别按钮
recognize_button = tk.Button(window, text="识别数字", command=recognize_digit)
recognize_button.grid(row=1, column=1)

# 创建识别结果标签
result_label = tk.Label(window, text="")
result_label.grid(row=2, column=0, columnspan=2)

# 创建画板图像
image = Image.new("RGB", (280, 280), (255, 255, 255))
draw = ImageDraw.Draw(image)

# 绑定画板事件
def on_mouse_down(event):
    global prev_x, prev_y
    prev_x, prev_y = event.x, event.y

def on_mouse_move(event):
    global prev_x, prev_y
    canvas.create_line(prev_x, prev_y, event.x, event.y, width=20)
    draw.line((prev_x, prev_y, event.x, event.y), fill="black", width=20)
    prev_x, prev_y = event.x, event.y

canvas.bind("<Button-1>", on_mouse_down)
canvas.bind("<B1-Motion>", on_mouse_move)

# 显示窗口
window.mainloop()

Efecto del programa
Insertar descripción de la imagen aquí
Para el reconocimiento de dígitos escritos a mano, la precisión depende no sólo del rendimiento del modelo, sino también de la calidad y diversidad de los datos. Al entrenar el modelo, el conjunto de datos utilizado puede ser diferente de los datos en el escenario de aplicación real, lo que hace que el modelo no pueda generalizarse bien a datos nuevos y desconocidos.

Además, la dificultad para reconocer números escritos a mano también se ve afectada por muchos factores, como el estilo de escritura, el tamaño de la letra, el grosor del trazo, la dirección de escritura, etc. Si estos factores no se cubren en el conjunto de entrenamiento, es posible que el modelo no pueda reconocer con precisión nuevos dígitos escritos a mano. Por lo tanto, para mejorar la precisión del reconocimiento de dígitos escritos a mano, es necesario utilizar más conjuntos de datos y más ricos, y ajustar y optimizar los parámetros del modelo para mejorar su capacidad de generalización.

Eche un vistazo al siguiente ejemplo: nuestro perceptrón multicapa mlp parece básicamente impotente.
Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/liaomin416100569/article/details/130572559
Recomendado
Clasificación