keras卷积神经网络识别mnist
程序员文章站
2024-03-14 11:45:46
...
前言
卷积神经网络是近年发展起来,并引起广泛重视的一种高效识别方法。20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络(Convolutional Neural Networks-简称CNN)。现在,CNN已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于该网络避免了对图像的复杂前期预处理,可以直接输入原始图像,因而得到了更为广泛的应用.
深层数学内涵先不考究,与之前的多层感知器比较一下代码模型上的区别在于特征值的提取:
多层感知器对于特征值的提取仅仅是将图片的3维矩阵转化为了一维矩阵,然后作为输入层输入;在卷积神经网络里,将数据使用不同滤镜产生多种特征图层,再使用池化层缩减采样,最后使用平坦层达到和多层感知器预处理步骤的功能,将多维矩阵转换为一维作为输入层输入.
关于池化层
- 可以减少需处理的数据点,减少运算量
- 让图像位置差异变小,例如图像的位置可能在背景的左上或右下=方造成干扰
- 参数的数量和计算量下降,在一定程度上控制了过度拟合
源码
#数据预处理
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
np.random.seed()
Using TensorFlow backend.
def images_labels_prediction(images, labels, prediction, index, num=10):
"""
:param images: 点阵像素点图像列表
:param labels: 图像对应真实值
:param prediction: 预测结果
:param index: 数据开始索引
:param num: 显示数据项数
:return:
"""
if num > 25:
num = 25
fig = plt.gcf() # 实例化图形
fig.set_size_inches(15, 15) # 设定图形大小
for i in range(0, num):
ax = plt.subplot(5, 5, 1 + i) # 建立sub_graph子图,为5行5列
ax.imshow(images[index], cmap="binary") # 画出子图
title = "label=" + str(labels[index]) # 设置子图title变量用以显示标签字段
if len(prediction) > 0: # 如果传入预测结果
title += ",predict=" + str(prediction[index]) # 设置标题加入预测结果
ax.set_title(title, fontsize=10) # 设置子图标题
ax.set_xticks([]) # 设置不显示刻度
ax.set_yticks([])
index += 1
plt.show()
(train_image,train_label),(test_image,test_label)=mnist.load_data()
def image_4D(image):
"""
:param image:数字图像特征值
:return: 数字图像四维向量标准化
"""
return image.reshape(image.shape[0],image.shape[1],image.shape[2],1).astype("float32")/255
def label_onehot(label):
"""
:param label:数字集合
:return: 数字进行One-Hot Encoding
"""
return np_utils.to_categorical(label)
train_x=image_4D(train_image)
test_x=image_4D(test_image)
train_y=label_onehot(train_label)
test_y=label_onehot(test_label)
#建立模型
#实例化模型框架
model=Sequential()
#添加卷积运算
#卷积层
#filters:建立滤镜数;kernel_size:滤镜大小;padding(same):让卷积运算不改变大小;input_shape输入层;activation**函数
model.add(Conv2D(filters=16,kernel_size=(5,5),padding="same",input_shape=(28,28,1),activation="relu"))
#池化层
#pool_size:缩减采样大小为
model.add(MaxPooling2D(pool_size=(2*1)))
#添加卷积运算
#卷积层
#filters:建立滤镜数;kernel_size:滤镜大小;padding(same):让卷积运算不改变大小;activation**函数
model.add(Conv2D(filters=36,kernel_size=(5,5),padding="same",activation="relu"))
#池化层
#pool_size:缩减采样大小为
model.add(MaxPooling2D(pool_size=(2*1)))
#Dropout层
#每次训练迭代随机放弃神经元,减轻过度拟合
model.add(Dropout(0.25))
#平坦层
model.add(Flatten())
#隐藏层
model.add(Dense(128,activation="relu"))
model.add(Dropout(0.5))
#添加输出层
model.add(Dense(10,activation="softmax"))
#模型训练
def show_train_history(train_history, mode="acc"):
"""
:param train_history: 训练历史
:param mode: 可视化模式,acc/loss->准确率或失败率
:return:
"""
plt.plot(train_history.history[mode])
plt.plot(train_history.history["val_" + mode])
plt.title("Train History")
plt.ylabel(mode)
plt.xlabel("Epoch")
plt.legend(["train", "validation"], loc="upper left")
plt.show()
def model_exe(model):
print(model.summary())
#编译模型
# 优化器使用adam可以更快收敛,提高准确率,损失函数使用cross_entropy(交叉熵),评估方式设置为准确率
model.compile("adam", "categorical_crossentropy", ["accuracy"])
#模型训练
# 训练数据x为图像特征值,y为图像真实值;每批次项数为200;训练周期epochs;verbose显示训练过程;验证比例为0.2
train_history = model.fit(x=train_x, y=train_y, batch_size=300, epochs=10, verbose=2, validation_split=0.2)
show_train_history(train_history)
scores = model.evaluate(test_x, test_y)
print("acc:", scores[1])
model_exe(model)
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 28, 28, 16) 416
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 14, 14, 16) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 14, 14, 36) 14436
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 7, 7, 36) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 7, 7, 36) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 1764) 0
_________________________________________________________________
dense_1 (Dense) (None, 128) 225920
_________________________________________________________________
dropout_2 (Dropout) (None, 128) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 1290
=================================================================
Total params: 242,062
Trainable params: 242,062
Non-trainable params: 0
_________________________________________________________________
None
Train on 48000 samples, validate on 12000 samples
Epoch 1/10
- 30s - loss: 0.5169 - acc: 0.8350 - val_loss: 0.0977 - val_acc: 0.9692
Epoch 2/10
- 29s - loss: 0.1381 - acc: 0.9600 - val_loss: 0.0639 - val_acc: 0.9799
Epoch 3/10
- 29s - loss: 0.0976 - acc: 0.9710 - val_loss: 0.0492 - val_acc: 0.9855
Epoch 4/10
- 30s - loss: 0.0809 - acc: 0.9759 - val_loss: 0.0462 - val_acc: 0.9865
Epoch 5/10
- 30s - loss: 0.0699 - acc: 0.9789 - val_loss: 0.0427 - val_acc: 0.9871
Epoch 6/10
- 29s - loss: 0.0583 - acc: 0.9815 - val_loss: 0.0374 - val_acc: 0.9894
Epoch 7/10
- 29s - loss: 0.0517 - acc: 0.9840 - val_loss: 0.0342 - val_acc: 0.9900
Epoch 8/10
- 29s - loss: 0.0498 - acc: 0.9852 - val_loss: 0.0346 - val_acc: 0.9903
Epoch 9/10
- 29s - loss: 0.0433 - acc: 0.9863 - val_loss: 0.0326 - val_acc: 0.9904
Epoch 10/10
- 29s - loss: 0.0375 - acc: 0.9881 - val_loss: 0.0327 - val_acc: 0.9904
10000/10000 [==============================] - 2s 188us/step
acc: 0.9913
#进行预测
prediction=model.predict_classes(test_x)
# 使用pd.crosstab建立混淆矩阵.args:测试图像真实值;机器预测结果;设置行名与列名
pd.crosstab(test_label,prediction,rownames=["label"],colnames=["predict"])
predict | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
label | ||||||||||
0 | 975 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 1 | 0 |
1 | 0 | 1133 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
2 | 2 | 1 | 1022 | 2 | 0 | 0 | 0 | 3 | 2 | 0 |
3 | 0 | 0 | 0 | 1005 | 0 | 3 | 0 | 0 | 2 | 0 |
4 | 0 | 2 | 0 | 0 | 974 | 0 | 0 | 0 | 2 | 4 |
5 | 1 | 0 | 0 | 5 | 0 | 880 | 4 | 1 | 0 | 1 |
6 | 3 | 2 | 0 | 1 | 1 | 1 | 949 | 0 | 1 | 0 |
7 | 0 | 3 | 1 | 3 | 0 | 0 | 0 | 1018 | 1 | 2 |
8 | 3 | 1 | 2 | 3 | 0 | 0 | 0 | 2 | 960 | 3 |
9 | 1 | 2 | 0 | 0 | 3 | 2 | 0 | 3 | 1 | 997 |
#总结:卷积神经网络的耗时比多层感知器的训练更多,但是准确度达到0.99
上一篇: PCNN 脉冲耦合神经网络初探
推荐阅读
-
keras卷积神经网络识别mnist
-
【深度学习】LeNet卷积神经网络(MNIST 计算机视觉数据集)
-
深度学习(Pytorch) 卷积神经网络训练 fashion mnist
-
Tensorflow 02: 卷积神经网络-MNIST
-
从手写数字图片(MNIST)识别看卷积神经网络
-
利用keras搭建AlexNet神经网络识别kaggle猫狗图片
-
简洁明了的tensorflow2.0教程——用keras实现mnist数字识别
-
用卷积神经网络(CNN)识别文字
-
BP神经网络手写数字识别软件EasyOCR 1.2.0发布,新增MNIST数据集图片和宽幅数字识别 神经网络人工智能BP神经网络手写数字识别OCR
-
tensorflow2.0之keras实现卷积神经网络