keras 深層学習フレームワークは、畳み込みニューラル ネットワーク cnn を通じて手書き数字認識を実現します

    昨日、手書き数字認識を実現するためにkerasを介して簡単なニューラルネットワークを構築した結果、最終的に独自の手書き数字認識を実行したところ、精度はわずか60%で心配されました。現在、手書きの数字認識は畳み込みニューラル ネットワークを通じて実現されています。

    畳み込みニューラル ネットワークを構築するという考え方は、畳み込みやプーリングなどの概念がここで追加されることを除いて、単純なニューラル ネットワークの考え方に似ています。ネットワーク構造は少し複雑ですが、全体的な考え方は同じです。データ セット、データ セットの変更、ネットワーク モデルの構築、モデルのコンパイル、モデルのトレーニング、モデルの保存、モデルの予測への使用。

    ここでは 2 つの例を示します。1 つはネットワークを構築し、最終的に学習済みのネットワーク モデルを保存するものです。もう 1 つは、保存したネットワーク モデルをロードして、独自の手書きの数字の絵を予測するものです。

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

     次のようにモデルをトレーニングし、情報を出力します。

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

    最終的に精度は98.5%以上に達しました。

    モデルで予測する

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

    デジタル写真は以下の通りです。 

    画像はプロジェクト ディレクトリnumber_imagesに配置されます。

    予測結果の出力:

 

    感触が変わり、精度が60%から90%に上がりました。100%ではありませんが、かなり良い状態です。 

    前のコードと比較すると、変更は非常にわずかです。主な理由は、ネットワークの入力時にデータの形状が変化したためです。単純なニューラル ネットワークには (784, *) 構造が必要ですが、畳み込みニューラル ネットワークには (1, 28, 28, 1 ) の構造では、データ処理に調整が加えられていますが、もう 1 つの違いは、ネットワーク モデルが追加されると、以前は単純な 2 層ネットワークでしたが、畳み込みニューラル ネットワークはより複雑になることです。

おすすめ

転載: blog.csdn.net/feinifi/article/details/132540824