赞
踩
昨天通过keras构建简单神经网络实现手写数字识别,结果在最后进行我们自己的手写数字识别的时候,准确率堪忧,只有60%。今天通过卷积神经网络来实现手写数字识别。
构建卷积神经网络和简单神经网络思路类似,只不过这里加入了卷积、池化等概念,网络结构复杂了一些,但是整体的思路没有变化,加载数据集,数据集修改,搭建网络模型,编译模型,训练模型,保存模型,利用模型预测。
这里还是给出两个例子,一个是构建网络,最后保存训练好的网络模型,一个是通过加载保存的网络模型预测我们自己的手写数字图片。
- 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)的结构, 在数据处理上做了调整,另一个不一样的地方就是网络模型在添加的时候,之前就是简单的两层网络,卷积神经网络复杂了很多。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。