El marco de aprendizaje profundo de keras realiza el reconocimiento de dígitos escritos a mano a través de una red neuronal convolucional cnn

Ayer , construimos una red neuronal simple     a través de keras para realizar el reconocimiento de dígitos escritos a mano. Como resultado, cuando finalmente realizamos nuestro propio reconocimiento de dígitos escritos a mano, la precisión era preocupante, solo el 60%. Hoy en día, el reconocimiento de dígitos escritos a mano se logra mediante redes neuronales convolucionales.

    La idea de construir una red neuronal convolucional es similar a la de una red neuronal simple, excepto que aquí se agregan conceptos como convolución y agrupación. La estructura de la red es un poco más complicada, pero la idea general sigue siendo la misma. conjunto de datos, modificar el conjunto de datos, construir el modelo de red, compilar el modelo, entrenar el modelo, guardar el modelo y utilizar el modelo para predecir.

    Aquí hay dos ejemplos: uno es construir una red y finalmente guardar el modelo de red entrenado, y el otro es predecir nuestras propias imágenes de dígitos escritas a mano cargando el modelo de red guardado.

import keras
import numpy as np
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Conv2D, Flatten, MaxPool2D
from tensorflow.keras import datasets, utils
# 数据处理
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[1], 1)
x_train = x_train.astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[1], 1)
x_test = x_test.astype('float32') / 255
y_train = utils.to_categorical(y_train, num_classes=10)
y_test = utils.to_categorical(y_test, num_classes=10)
# 构建模型
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation="relu", input_shape=(28, 28, 1)))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Conv2D(filters=36, kernel_size=(3, 3), padding='same', activation="relu"))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.25))
model.add(Dense(10, activation="softmax"))
# 编译
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
# 训练
model.fit(x_train, y_train, epochs=5, batch_size=128, validation_data=(x_test, y_test))
# 保存模型
model.save("mnist.h5")

     Entrene el modelo e imprima la información de la siguiente manera:

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 28, 28, 16)        160       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 14, 14, 16)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 14, 14, 36)        5220      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 7, 7, 36)         0         
 2D)                                                             
                                                                 
 dropout (Dropout)           (None, 7, 7, 36)          0         
                                                                 
 flatten (Flatten)           (None, 1764)              0         
                                                                 
 dense (Dense)               (None, 128)               225920    
                                                                 
 dropout_1 (Dropout)         (None, 128)               0         
                                                                 
 dense_1 (Dense)             (None, 10)                1290      
                                                                 
=================================================================
Total params: 232,590
Trainable params: 232,590
Non-trainable params: 0
_________________________________________________________________
Epoch 1/5
2023-08-28 16:03:54.677314: I tensorflow/stream_executor/cuda/cuda_dnn.cc:368] Loaded cuDNN version 8800
469/469 [==============================] - 10s 17ms/step - loss: 0.2842 - accuracy: 0.9123 - val_loss: 0.0628 - val_accuracy: 0.9798
Epoch 2/5
469/469 [==============================] - 7s 16ms/step - loss: 0.0836 - accuracy: 0.9743 - val_loss: 0.0473 - val_accuracy: 0.9841
Epoch 3/5
469/469 [==============================] - 7s 16ms/step - loss: 0.0627 - accuracy: 0.9801 - val_loss: 0.0325 - val_accuracy: 0.9886
Epoch 4/5
469/469 [==============================] - 7s 15ms/step - loss: 0.0497 - accuracy: 0.9844 - val_loss: 0.0346 - val_accuracy: 0.9882
Epoch 5/5
469/469 [==============================] - 7s 15ms/step - loss: 0.0422 - accuracy: 0.9867 - val_loss: 0.0298 - val_accuracy: 0.9898

    La precisión finalmente alcanzó más del 98,5%.

    Predecir con modelo

import keras
import numpy as np
import cv2
from keras.models import load_model

model = load_model("mnist.h5")


def predict(img_path):
    img = cv2.imread(img_path, 0)
    img = img.reshape(28, 28).astype("float32") / 255  # 0 1
    img = img.reshape(1, 28, 28, 1)  # 28 * 28 -> (1,28,28,1)
    label = model.predict(img)
    label = np.argmax(label, axis=1)
    print('{} -> {}'.format(img_path, label[0]))


if __name__ == '__main__':
    for _ in range(10):
        predict("number_images/b_{}.png".format(_))

    Las imágenes digitales son las siguientes: 

    Las imágenes se colocan en el directorio del proyecto number_images.

    Se imprimen los resultados de la predicción:

 

    Se siente diferente, la precisión ha aumentado del 60% al 90%. Aunque no está al 100%, está bastante bien. 

    En comparación con el código anterior, los cambios son muy pequeños. La razón principal es que la forma de los datos ha cambiado cuando se ingresa la red. Una red neuronal simple requiere una estructura (784, *) y una red neuronal convolucional requiere (1, 28, 28, 1) Estructura, se han realizado ajustes en el procesamiento de datos. Otra diferencia es que cuando se agrega el modelo de red, antes era una red simple de dos capas y la red neuronal convolucional es mucho más complicada.

Supongo que te gusta

Origin blog.csdn.net/feinifi/article/details/132540824
Recomendado
Clasificación