Le cadre d'apprentissage profond keras réalise la reconnaissance de chiffres manuscrits via le réseau neuronal convolutif cnn

Hier ,nous avons construit un simple réseau neuronal     via keras pour réaliser la reconnaissance des chiffres manuscrits.En conséquence, lorsque nous avons finalement effectué notre propre reconnaissance des chiffres manuscrits, la précision était inquiétante, seulement 60%. Aujourd'hui, la reconnaissance des chiffres manuscrits est réalisée grâce à des réseaux de neurones convolutifs.

    L'idée de construire un réseau neuronal convolutif est similaire à celle d'un simple réseau neuronal, sauf que des concepts tels que la convolution et le pooling sont ajoutés ici. La structure du réseau est un peu plus compliquée, mais l'idée générale reste la même. L'ensemble de données, modifiez l'ensemble de données et créez le modèle de réseau. Compilez le modèle, entraînez le modèle, enregistrez le modèle et utilisez le modèle pour prédire.

    Voici deux exemples. L'un consiste à construire un réseau et enfin à enregistrer le modèle de réseau formé. L'autre consiste à prédire nos propres images de chiffres manuscrites en chargeant le modèle de réseau enregistré.

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")

     Entraînez le modèle et imprimez les informations comme suit :

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 précision a finalement atteint plus de 98,5 %.

    Prédire avec le modèle

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(_))

    Les images numériques sont les suivantes : 

    Les images sont placées dans le répertoire du projet number_images.

    Impression des résultats de prédiction :

 

    C'est différent, la précision est passée de 60 % à 90 %. Même si ce n'est pas à 100%, c'est plutôt bien. 

    Par rapport au code précédent, les changements sont très faibles. La raison principale est que la forme des données a changé lors de la saisie du réseau. Un réseau neuronal simple nécessite une structure (784, *), et un réseau neuronal convolutif nécessite (1, 28, 28, 1 ), des ajustements ont été apportés au traitement des données. Une autre différence est que lorsque le modèle de réseau est ajouté, il s'agissait auparavant d'un simple réseau à deux couches et le réseau neuronal convolutif est beaucoup plus compliqué.

Je suppose que tu aimes

Origine blog.csdn.net/feinifi/article/details/132540824
conseillé
Classement