,,Python实战之MNIST手写数字识别详解

,,Python实战之MNIST手写数字识别详解

MNIST数据集是机器学习领域中非常经典的数据集。它由60000个训练样本和10000个测试样本组成,每个样本都是28*28像素的灰度手写数字图片。本文主要介绍MNIST手写数字识别的实现,有需要的可以参考一下。

目录

数据集1的介绍。数据预处理2。网络建设。网络配置关于优化器关于损失函数关于索引4。网络培训和测试。绘制损耗和精度随时间的变化图6。完全码

数据集介绍

MNIST数据集是机器学习领域中非常经典的数据集。它由60,000个训练样本和10,000个测试样本组成。每个样本都是28 * 28像素的灰色手写数字图片,在keras中内置。本文采用Tensorflow下的Keras(Keras中文文档)神经网络API来构建网络。

在开始之前,我们先回忆一下机器学习的一般工作流程(表示在本文中使用,表示不在本文中使用)。

1.定义问题并收集数据集()

2.选择衡量成功的指标()

3.确定评估方法()

4.准备数据()

5.开发比基准更好的模型()

6.扩大模型比例()

7.模型的正则化和参数的调整()

最后一层激活函数和损失函数的选择

下面开始正文~

1.数据预处理

要首先导入数据,请使用mnist.load()函数。

让我们来看看它的源代码语句:

def load_data(path='mnist.npz '):

' ' '加载[MNIST数据集](http://yann . le Cun . com/exdb/mnist/)。

这是60,000张28x28的10位数灰度图像的数据集,

以及一万张图片的测试集。

更多信息请访问

【MNIST首页】(http://yann . le Cun . com/exdb/mnist/)。

参数:

path:本地缓存数据集的路径

(相对于` ~/。keras/datasets `)。

退货:

Numpy数组的元组:`(x_train,y_train),(x_test,y_test)`。

**x_train,x_test**:带有形状的灰度图像数据的uint8数组

(num_samples,28,28)。

**y_train,y_test**: uint8数字标签数组(0-9范围内的整数)

使用形状(num_samples,)。

'''

可以看到,它包含数据集的下载链接,以及数据集大小、大小和数据类型的声明,函数返回由四个numpyarrays组成的两个元组。

导入数据集并将其整形为所需的形状,然后将其标准化。

其中,keras内置的to _ category()是一键代码——。每个标签表示为一个全零向量,只有标签索引对应的元素为1。

例:col=10

[0,1,9] - [ [1,0,0,0,0,0,0,0,0,0],

[0,1,0,0,0,0,0,0,0,0],

[0,0,0,0,0,0,0,0,0,1] ]

我们可以手动实现它:

def one_hot(序列,列):

results=NP . zeros((len(sequences),col))

#对于I,枚举中的序列(sequences):

# results[I,sequence]=1

对于范围内的I(len(sequences)):

对于范围内的j(len(sequences[I])):

结果[i,序列[i][j]]=1

返回结果

以下是预处理过程。

def data_preprocess():

(train_images,train_labels),(test_images,test_labels)=mnist.load_data()

train _ images=train _ images . shape((60000,28,28,1))

train _ images=train _ images . as type(' float 32 ')/255

#打印(train_images[0])

test _ images=test _ images . shape((10000,28,28,1))

test _ images=test _ images . as type(' float 32 ')/255

train _ labels=to _ categorial(train _ labels)

test _ labels=to _ categorial(test _ labels)

返回训练图像,训练标签,测试图像,测试标签

2.网络搭建

这里我们构建的是一个卷积神经网络,它是一个简单的线性累加,有一些卷积、汇集和全连接。我们知道多个线性层的叠加仍然实现线性运算,加层不会扩大假设空间(输入数据到输出数据的所有可能的线性变换集),所以需要加入非线性或激活函数。Relu是最常用的激活函数。也可以使用prelu和elu。

定义build_module():

模特=模特。顺序()

#第一个卷积层,第一层需要注明input_shape形状。

model.add(图层。Conv2D(32,(3,3),activation='relu ',input_shape=(28,28,1)))

#第二大池层

model.add(图层。MaxPooling2D((2,2)))

#第三卷积层

model.add(图层。Conv2D(64,(3,3),activation='relu '))

#第四大池层

model.add(图层。MaxPooling2D((2,2)))

#第五卷积层

model.add(图层。Conv2D(64,(3,3),activation='relu '))

#第六个展平层,将3D张量平铺为矢量。

model.add(图层。Flatten())

#第七个全连接层

model.add(图层。密集(64,activation='relu '))

#第八个softmax层,用于分类。

model.add(图层。Dense(10,激活='softmax '))

回报模型

使用model.summary()查看网络结构:

3.网络配置

网络建立后,关键步骤是设置配置。比如优化器——更新参数的网络梯度下降的具体方法,损失函数3354对生成值与目标值的距离的度量,评价指标等。这些配置可以通过传递model.compile()参数来完成。

我们来看看model.compile()的源代码分析:

定义编译(自我,

optimizer='rmsprop ',

损失=无,

度量=无,

loss _ weights=无,

加权度量=无,

run _急切=无,

步骤执行数=无,

* *夸脱):

“”为培训配置模型。

关于优化器

优化器:字符串(优化器名称)或优化器实例。

字符串格式:例如,使用优化器的默认参数。

实例优化器传入参数:

keras . optimizer . rms prop(lr=0.001,rho=0.9,=无,decay=0.0)

model . compile(optimizer=' rms prop ',loss='mean_squared_error ')

建议使用优化器的默认参数(学习率lr除外,可以自由调整)

参数:

Lr: float=0。学习率。

Rho: float=0。均方根斜率平方的移动平均衰减率。

:float=0。模糊因素。如果没有,默认值为k()。

衰变:浮点=0。每次参数更新后的学习率衰减值。

类似的优化器还有很多,比如SGD,Adagrad,Adadelta,Adam,Adamax,Nadam等等。

关于损失函数

视具体任务而定,一般来说,损失函数应该能很好地描述任务。例如

1.回归问题

希望神经网络的输出值更接近地面实况,选择能描述距离的损失,如L1损失、MSE损失等,应该更合适。

2.分类问题

希望神经网络输出的类别与地面真实的类别一致,选择能够描述类别分布的损失,如cross_entropy,应该更合适。

具体选择见文章开头损失函数的选取。

关于指标

使用“常规”查看上面的列表。先说自定义求值函数:应该在编译时传入。这个函数需要将(y_true,y_pred)作为输入参数,并返回一个张量作为输出结果。

将keras.backend作为K导入

def mean_pred(y_true,y_pred):

返回K.mean(y_pred)

model . compile(optimizer=' rms prop ',

损失='二元交叉熵',

度量=['准确性',平均值_预测值])

4.网络训练与测试

1.培训(安装)

使用model.fit(),它可以接受的参数列表

def fit(自我,

x=无,

y=无,

batch _ size=无,

纪元=1,

详细=1,

回调=无,

验证_拆分=0。

验证数据=无,

洗牌=真,

class_weight=None,

sample _ weight=无

初始纪元=0,

每个时期的步数=无,

验证步骤=无,

验证_批处理_大小=无,

验证频率=1,

最大队列大小=10,

工人=1,

use_multiprocessing=False):

这个源码有300多个总统,具体解读下次再说。

我们对训练数据进行划分,64个样本作为一个小批量传输,所有数据迭代5次。

model.fit(train_images,train_labels,epochs=5,batch_size=64)

测试

使用模型。评估()函数

test_loss,test _ ACC=模型。评估(测试图像,测试标签)

关于测试函数的返回声明:

退货:

标量测试损失(如果模型只有一个输出,没有指标)

或者标量列表(如果模型有多个输出

和/或度量)。属性"模型.度量_名称"将为您提供

标量输出的显示标签。

5.绘制loss和accuracy随着epochs的变化图

model.fit()返回一个历史对象,它包含一个历史成员,记录了训练过程的所有数据。

我们采用matplotlib.pyplot进行绘图,具体见后面完整代码。

退货:

一件历史文物。其“历史.历史”属性为

培训损失值和度量值的记录

在连续的时期,以及验证损失值

和验证指标值(如果适用)。

定义提款损失(历史):

loss=history.history['loss']

epochs=range(1,len(loss) 1)

plt.subplot(1,2,1)#第一张图

plt.plot(历元,损失,‘博’,标签='训练损失)

plt.title("培训损失")

plt.xlabel('纪元)

plt.ylabel("损失")

plt。图例()

plt.subplot(1,2,2)#第二张图

准确性=history.history['准确性]

plt.plot(历元,精度,“博”,标签="训练精度")

plt.title("训练准确性")

plt.xlabel('纪元)

plt.ylabel("准确性")

plt.suptitle("列车数据")

plt。图例()

plt.show()

6.完整代码

从tensorflow.keras.datasets导入mnist

来自张量流导入模型

从张量流导入图层

从tensorflow.keras.utils导入到_分类

将matplotlib.pyplot作为plt导入

将numpy作为铭牌导入

def data_preprocess():

(train_images,train_labels),(test_images,test_labels)=mnist.load_data()

训练图像=训练图像。形状((60000,28,28,1))

训练图像=训练图像。as类型('浮点32 ')/255

#打印(训练图像[0])

测试图像=测试图像。形状((10000,28,28,1))

测试图像=测试图像。as类型('浮点32 ')/255

train _ labels=to _ category(train _ labels)

test _ labels=to _ categorial(测试_标签)

返回训练图像,训练标签,测试图像,测试标签

#搭建网络

定义构建模块():

模特=模特。顺序()

#第一层卷积层

model.add(图层Conv2D(32,(3,3),activation='relu ',input_shape=(28,28,1)))

#第二层最大池化层

model.add(图层MaxPooling2D((2,2)))

#第三层卷积层

model.add(图层Conv2D(64,(3,3),activation='relu '))

#第四层最大池化层

model.add(图层MaxPooling2D((2,2)))

#第五层卷积层

model.add(图层Conv2D(64,(3,3),activation='relu ')。

#第六层变平层,将三维(三维的缩写)张量平铺为向量

model.add(图层Flatten())

#第七层全连接层

model.add(图层。密集(64,激活='relu '))

#第八层softmax层,进行分类

model.add(图层密(10,激活='softmax '))

回报模型

定义提款损失(历史):

loss=history.history['loss']

epochs=range(1,len(loss) 1)

plt.subplot(1,2,1)#第一张图

plt.plot(历元,损失,‘博’,标签='训练损失)

plt.title("培训损失")

plt.xlabel('纪元)

plt.ylabel("损失")

plt。图例()

plt.subplot(1,2,2)#第二张图

准确性=history.history['准确性]

plt.plot(历元,精度,“博”,标签="训练精度")

plt.title("训练准确性")

plt.xlabel('纪元)

plt.ylabel("准确性")

plt.suptitle("列车数据")

plt。图例()

plt.show()

if __name__=='__main__ ':

train_images,train_labels,test_images,test_labels=data_preprocess()

模型=构建模块()

print(model.summary())

模型。编译(optimizer=' rms prop ',loss=' categorical _ crossentropy ',metrics=['accuracy'])

history=model.fit(train_images,train_labels,epochs=5,batch_size=64)

提款损失(历史)

test_loss,test _ ACC=模型。评估(测试图像,测试标签)

print('test_loss=',test_loss,' test_acc=',test_acc)

迭代训练过程中失败和准确(性)的变化

由于数据集相对简单,随机神经网络设计在测试集中的准确率可以达到99.2%。

以上是Python实战中MNIST手写数字识别的详细内容。有关Python中MNIST手写数字识别的更多信息,请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: