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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。