7 pasos para entender el reconocimiento de dígitos escritos a mano Mnist

Hola a todos, soy Dong Dongcan.

Hay muchos proyectos introductorios para el reconocimiento de imágenes, de los cuales el reconocimiento de dígitos escritos a mano de Mnist es definitivamente el más popular.

El proyecto tiene las ventajas de un conjunto de datos pequeño, una red neuronal simple y tareas simples, e integra las cosas que deberían estar en la red CNN. Se puede decir que aunque el gorrión es pequeño, tiene todos los órganos internos.

Muy adecuado para que los principiantes aprendan.

Este artículo lo lleva a través de cada detalle del proyecto en forma de guía de código.

El enlace de descarga del código se adjunta al final del artículo Puede entrenar una red neuronal desde cero sin una GPU.

¿Qué es el reconocimiento de dígitos escritos a mano?

En resumen, se trata de construir una red neuronal convolucional, que puede completar el reconocimiento de números escritos a mano.

Escribo un 6 en papel con un bolígrafo, y la red neuronal reconoce que es un 6, y escribo un 8, y reconoce que es un 8. Es así de simple.

La razón por la que la tarea es simple es que sus etiquetas solo tienen 10 clasificaciones de 0 a 9, que es mucho más pequeña que las 1000 clasificaciones de resnet y otras redes en ImageNet.

Aunque simple, hay muchos principios detrás de esto, y los típicos entrenamientos y algoritmos de CNN están todos ausentes.

Junto con este proyecto, es el famoso conjunto de datos MNIST (Números matemáticos en texto).

El conjunto de datos contiene 60 000 imágenes de entrenamiento y 10 000 imágenes de prueba. Las imágenes son todo tipo de números escritos a mano, que básicamente se ven así.

Lectura intensiva de código en 7 pasos

Después de una breve comprensión de los antecedentes del proyecto, introduciré la red neuronal poco a poco en forma de lectura de código.

Paso 1: importa las bibliotecas necesarias

# 导入NumPy数学工具箱
import numpy as np 
# 导入Pandas数据处理工具箱
import pandas as pd
# 从 Keras中导入 mnist数据集
from keras.datasets import mnist

Keras es una biblioteca de redes neuronales artificiales de código abierto, que contiene muchas redes neuronales y conjuntos de datos clásicos, incluido el conjunto de datos mnist que se utilizará.

Paso 2: Cargue el conjunto de datos

(x_train, y_train), (x_test, y_test)
=  mnist.load_data() 

Este comando usa el módulo mnist que viene con keras para cargar el conjunto de datos (load_data) y asignarlo a cuatro variables.

Entre ellos: x_train guarda la imagen utilizada para el entrenamiento, y y_train es la etiqueta correspondiente. Supongamos que el número en la imagen es 1, luego la etiqueta es 1.

x_test y y_test son imágenes y etiquetas utilizadas para la verificación respectivamente, es decir, el conjunto de verificación. Una vez que se entrena la red neuronal, se puede validar utilizando los datos del conjunto de validación.

Paso 3: Preprocesamiento de datos

Uno de los contenidos del preprocesamiento es cambiar la forma del conjunto de datos para cumplir con los requisitos del modelo.

 # 导入keras.utils工具箱的类别转换工具
from tensorflow.keras.utils import to_categorical
 # 给标签增加维度,使其满足模型的需要
 # 原始标签,比如训练集标签的维度信息是[60000, 28, 28, 1]
X_train = X_train_image.reshape(60000,28,28,1)
X_test = X_test_image.reshape(10000,28,28,1)
 # 特征转换为one-hot编码
y_train = to_categorical(y_train_lable, 10)
y_test = to_categorical(y_test_lable, 10)

Hay un total de 60 000 imágenes de entrenamiento y 10 000 imágenes de verificación en este conjunto de datos, cada imagen tiene una longitud y un ancho de 28 píxeles y la cantidad de canales es 1.

Luego, para el conjunto de entrenamiento x_train, cambie su forma a NHWC = [60000, 28, 28, 1], y el conjunto de validación es similar.

La función de to_categorical es convertir la etiqueta de muestra en una codificación one-hot, y la función de la codificación one-hot es calcular mejor la probabilidad o la puntuación de la categoría.

uno-caliente

La razón por la que se usa la codificación one-hot es que para las 10 etiquetas que generan 0-9, el estado de cada etiqueta debe ser igual y no hay ninguna situación en la que el número de etiqueta 2 sea mayor que el número 1.

Pero si usamos directamente el valor original de la etiqueta (0-9) para calcular el resultado final, habrá una situación en la que la etiqueta 2 sea mayor que la etiqueta 1.

Por lo tanto, en la mayoría de los casos, debe convertir las etiquetas a codificación one-hot, es decir, codificación one-hot, para que no haya tamaño entre las etiquetas.

En este ejemplo, la codificación one-hot de los dígitos 0-9 es:

array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]

Cada fila de vectores representa una etiqueta.

Supongamos que [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.] representa 0 y [0., 1., 0., 0., 0. , 0., 0., 0., 0., 0.] representan 1. Se puede ver que los dos son ortogonalmente independientes, y no hay problema de quién es más grande que quién.

Paso 4: Crear la red neuronal.

# 从 keras 中导入模型
from keras import models 
# 从 keras.layers 中导入神经网络需要的计算层
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
# 构建一个最基础的连续的模型,所谓连续,就是一层接着一层
model = models.Sequential()
# 第一层为一个卷积,卷积核大小为(3,3), 输出通道32,使用 relu 作为激活函数
model.add(Conv2D(32, (3, 3), activation='relu', 
                 input_shape=(28,28,1)))
# 第二层为一个最大池化层,池化核为(2,2)
# 最大池化的作用,是取出池化核(2,2)范围内最大的像素点代表该区域
# 可减少数据量,降低运算量。
model.add(MaxPooling2D(pool_size=(2, 2)))
# 又经过一个(3,3)的卷积,输出通道变为64,也就是提取了64个特征。
# 同样为 relu 激活函数
model.add(Conv2D(64, (3, 3), activation='relu'))
# 上面通道数增大,运算量增大,此处再加一个最大池化,降低运算
model.add(MaxPooling2D(pool_size=(2, 2)))
# dropout 随机设置一部分神经元的权值为零,在训练时用于防止过拟合
# 这里设置25%的神经元权值为零
model.add(Dropout(0.25)) 
# 将结果展平成1维的向量
model.add(Flatten())
# 增加一个全连接层,用来进一步特征融合
model.add(Dense(128, activation='relu'))
# 再设置一个dropout层,将50%的神经元权值为零,防止过拟合
# 由于一般的神经元处于关闭状态,这样也可以加速训练
model.add(Dropout(0.5)) 
# 最后添加一个全连接+softmax激活,输出10个分类,分别对应0-9 这10个数字
model.add(Dense(10, activation='softmax'))

Cada línea de código anterior se comenta para explicar la función de cada línea. Solo unas pocas líneas son la totalidad de esta red neuronal de reconocimiento de dígitos escritos a mano.

Paso 5: Entrenamiento

# 编译上述构建好的神经网络模型
# 指定优化器为 rmsprop
# 制定损失函数为交叉熵损失
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
# 开始训练              
model.fit(X_train, y_train, # 指定训练特征集和训练标签集
          validation_split = 0.3, # 部分训练集数据拆分成验证集
          epochs=5, # 训练轮次为5轮
          batch_size=128) # 以128为批量进行训练

Época 5/5
329/329 [================================] - 15 s 46 ms/paso - pérdida: 0,1054 - precision: 0.9718 - val_loss: 0.0681 - val_accuracy: 0.9826
Los resultados del entrenamiento son los anteriores, se puede ver que la precisión del entrenamiento final alcanzó el 98.26%, que es bastante alto.

Paso 6: Validación en conjunto de validación

# 在测试集上进行模型评估
score = model.evaluate(X_test, y_test) 
print('测试集预测准确率:', score[1]) # 打印测试集上的预测准确率

313/313 [===============================] - 1s 4ms/paso - pérdida: 0,0662 - precisión: 0,9815 prueba establecer Precisión de predicción: 0.9815000295639038

Se puede ver que también hay un 98% de precisión en el conjunto de validación.

Paso 7: Verifica una imagen

# 预测验证集第一个数据
pred = model.predict(X_test[0].reshape(1, 28, 28, 1)) 
# 把one-hot码转换为数字
print(pred[0],"转换一下格式得到:",pred.argmax())
 # 导入绘图工具包
import matplotlib.pyplot as plt
# 输出这个图片
plt.imshow(X_test[0].reshape(28, 28),cmap='Greys')

Tome la primera imagen del conjunto de validación como ejemplo para la validación.

1/1 [==============================] - 0s 17ms/paso
[4.2905590e-15 2.6790809e-11 2.8249305 e-09 2.3393848e-11 7.1304548e-14
1.8217797e-18 5.7493907e-19 1.0000000e+00 8.0317367e-15 4.6352322e-10]

Convierta el formato para obtener: 7

El número obtenido es 7, y se muestra la imagen, y de hecho es 7. Muestra que el modelo entrenado ha alcanzado el nivel de reconocimiento de números.

Resumir

El proyecto de reconocimiento de dígitos escritos a mano es relativamente simple, con solo dos capas convolucionales, y la carga computacional general no es grande.En lo que respecta a la configuración actual de la computadora, incluso una computadora portátil puede básicamente completar el entrenamiento y la verificación de la red neuronal.

Si está interesado, preste atención a la cuenta oficial "Dong Dongcan is a siege lion" y responda [mnist] en segundo plano para obtener el código fuente y practicarlo.

Supongo que te gusta

Origin blog.csdn.net/dongtuoc/article/details/130958475
Recomendado
Clasificación