• 售前

  • 售后

热门帖子
入门百科

Python实战之MNIST手写数字辨认详解

[复制链接]
万象争辉1 显示全部楼层 发表于 2022-1-8 08:25:17 |阅读模式 打印 上一主题 下一主题
目次


  • 数据集先容
  • 1.数据预处置处罚
  • 2.网络搭建
  • 3.网络配置

    • 关于优化器
    • 关于丧失函数
    • 关于指标

  • 4.网络训练与测试
  • 5.绘制loss和accuracy随着epochs的变革图
  • 6.完备代码

数据集先容

MNIST数据集是机器学习范畴中非常经典的一个数据集,由60000个训练样本和10000个测试样本构成,每个样本都是一张28 * 28像素的灰度手写数字图片,且内置于keras。本文接纳Tensorflow下Keras(Keras中文文档)神经网络API举行网络搭建。
开始之前,先追念下机器学习的通用工作流程( √表示本文用到,×表示本文没有用到 )
1.界说问题,网络数据集(√)
2.选择权衡乐成的指标(√)
3.确定评估的方法(√)
4.预备数据(√)
5.开发比基准更好的模型(×)
6.扩大模型规模(×)
7.模型正则化与调治参数(×)
关于末了一层激活函数与丧失函数的选择

下面开始正文~

1.数据预处置处罚

首先导入数据,要使用mnist.load()函数
我们来看看它的源码声明:
  1. def load_data(path='mnist.npz'):
  2.   """Loads the [MNIST dataset](http://yann.lecun.com/exdb/mnist/).
  3.   This is a dataset of 60,000 28x28 grayscale images of the 10 digits,
  4.   along with a test set of 10,000 images.
  5.   More info can be found at the
  6.   [MNIST homepage](http://yann.lecun.com/exdb/mnist/).
  7.   Arguments:
  8.       path: path where to cache the dataset locally
  9.           (relative to `~/.keras/datasets`).
  10.   Returns:
  11.       Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
  12.       **x_train, x_test**: uint8 arrays of grayscale image data with shapes
  13.         (num_samples, 28, 28).
  14.       **y_train, y_test**: uint8 arrays of digit labels (integers in range 0-9)
  15.         with shapes (num_samples,).
  16.   """
复制代码
可以看到,内里包含了数据集的下载链接,以及数据集规模、尺寸以及数据类型的声明,且函数返回的是四个numpy array构成的两个元组。
导入数据集并reshape至想要外形,再标准化处置处罚。
此中内置于keras的to_categorical()就是one-hot编码——将每个标签表示为全零向量,只有标签索引对应的元素为1.
eg: col=10
  1. [0,1,9]-------->[ [1,0,0,0,0,0,0,0,0,0],
  2.                   [0,1,0,0,0,0,0,0,0,0],
  3.                   [0,0,0,0,0,0,0,0,0,1] ]        
复制代码
我们可以手动实现它:
  1. def one_hot(sequences,col):
  2.         resuts=np.zeros((len(sequences),col))
  3.         # for i,sequence in enumerate(sequences):
  4.         #         resuts[i,sequence]=1
  5.         for i in range(len(sequences)):
  6.                 for j in range(len(sequences[i])):
  7.                         resuts[i,sequences[i][j]]=1
  8.         return resuts
复制代码
下面是预处置处罚过程
  1. def data_preprocess():
  2.     (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
  3.     train_images = train_images.reshape((60000, 28, 28, 1))
  4.     train_images = train_images.astype('float32') / 255
  5.     #print(train_images[0])
  6.     test_images = test_images.reshape((10000, 28, 28, 1))
  7.     test_images = test_images.astype('float32') / 255
  8.     train_labels = to_categorical(train_labels)
  9.     test_labels = to_categorical(test_labels)
  10.     return train_images,train_labels,test_images,test_labels
复制代码
2.网络搭建

这里我们搭建的是卷积神经网络,就是包含一些卷积、池化、全连接的简单线性堆积。我们知道多个线性层堆叠实现的仍旧是线性运算,添加层数并不会扩展假设空间(从输入数据到输出数据的全部大概的线性变换集合),因此必要添加非线性或激活函数。relu是最常用的激活函数,也可以用prelu、elu
  1. def build_module():
  2.     model = models.Sequential()
  3.     #第一层卷积层,首层需要指出input_shape形状
  4.     model.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)))
  5.     #第二层最大池化层
  6.     model.add(layers.MaxPooling2D((2,2)))
  7.     #第三层卷积层
  8.     model.add(layers.Conv2D(64, (3,3), activation='relu'))
  9.     #第四层最大池化层
  10.     model.add(layers.MaxPooling2D((2,2)))
  11.     #第五层卷积层
  12.     model.add(layers.Conv2D(64, (3,3), activation='relu'))
  13.     #第六层Flatten层,将3D张量平铺为向量
  14.     model.add(layers.Flatten())
  15.     #第七层全连接层
  16.     model.add(layers.Dense(64, activation='relu'))
  17.     #第八层softmax层,进行分类
  18.     model.add(layers.Dense(10, activation='softmax'))
  19.     return model
复制代码
使用model.summary()检察搭建的网路结构:


3.网络配置

网络搭建好之后还必要关键的一步设置配置。比如:优化器——网络梯度降落举行参数更新的具体方法、丧失函数——权衡天生值与目标值之间的间隔、评估指标等。配置这些可以通过 model.compile() 参数转达做到。
我们来看看model.compile()的源码分析下:
  1.   def compile(self,
  2.               optimizer='rmsprop',
  3.               loss=None,
  4.               metrics=None,
  5.               loss_weights=None,
  6.               weighted_metrics=None,
  7.               run_eagerly=None,
  8.               steps_per_execution=None,
  9.               **kwargs):
  10.     """Configures the model for training.
复制代码


关于优化器

优化器:字符串(优化器名称)或优化器实例。
字符串格式:比如使用优化器的默认参数
实例优化器举行参数传入:
  1. keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)
  2. model.compile(optimizer='rmsprop',loss='mean_squared_error')
复制代码
建议使用优化器的默认参数 (除了学习率 lr,它可以被自由调治)
参数:
  1. lr: float >= 0. 学习率。
  2. rho: float >= 0. RMSProp梯度平方的移动均值的衰减率.
  3. epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
  4. decay: float >= 0. 每次参数更新后学习率衰减值。
复制代码
类似还有很多多少优化器,比如SGD、Adagrad、Adadelta、Adam、Adamax、Nadam等

关于丧失函数

取决于具体任务,一般来说丧失函数要可以或许很好的描绘任务。比如
1.回归问题
盼望神经网络输出的值与ground-truth的间隔更近,选取能描绘间隔的loss应该会更合适,比如L1 Loss、MSE Loss等
2.分类问题
盼望神经网络输出的种别与ground-truth的种别一致,选取能描绘种别分布的loss应该会更合适,比如cross_entropy
具体常见选择可检察文章开始处关于丧失函数的选择

关于指标

通例使用检察上述列表即可。下面说说自界说评价函数:它应该在编译的时间(compile)转达进去。该函数必要以 (y_true, y_pred) 作为输入参数,并返回一个张量作为输出结果。
  1. import keras.backend as K
  2. def mean_pred(y_true, y_pred):
  3.     return K.mean(y_pred)
  4. model.compile(optimizer='rmsprop',
  5.               loss='binary_crossentropy',
  6.               metrics=['accuracy', mean_pred])
复制代码
4.网络训练与测试

1.训练(拟合)
使用model.fit(),它可以继续的参数列表
  1. def fit(self,
  2.           x=None,
  3.           y=None,
  4.           batch_size=None,
  5.           epochs=1,
  6.           verbose=1,
  7.           callbacks=None,
  8.           validation_split=0.,
  9.           validation_data=None,
  10.           shuffle=True,
  11.           class_weight=None,
  12.           sample_weight=None,
  13.           initial_epoch=0,
  14.           steps_per_epoch=None,
  15.           validation_steps=None,
  16.           validation_batch_size=None,
  17.           validation_freq=1,
  18.           max_queue_size=10,
  19.           workers=1,
  20.           use_multiprocessing=False):
复制代码
这个源码有300多行长,具体的解读放在下次。
我们对训练数据举行分别,以64个样本为小批量举行网络转达,对全部数据迭代5次
  1. model.fit(train_images, train_labels, epochs = 5, batch_size=64)
复制代码
2.测试

使用model.evaluates()函数
  1. test_loss, test_acc = model.evaluate(test_images, test_labels)
复制代码
关于测试函数的返回声明:
  1. Returns:
  2.         Scalar test loss (if the model has a single output and no metrics)
  3.         or list of scalars (if the model has multiple outputs
  4.         and/or metrics). The attribute `model.metrics_names` will give you
  5.         the display labels for the scalar outputs.
复制代码
5.绘制loss和accuracy随着epochs的变革图

model.fit()返回一个History对象,它包含一个history成员,记载了训练过程的全部数据。
我们接纳matplotlib.pyplot举行绘图,具体见背面完备代码。
  1. Returns:
  2.         A `History` object. Its `History.history` attribute is
  3.         a record of training loss values and metrics values
  4.         at successive epochs, as well as validation loss values
  5.         and validation metrics values (if applicable).
复制代码
  1. def draw_loss(history):
  2.     loss=history.history['loss']
  3.     epochs=range(1,len(loss)+1)
  4.     plt.subplot(1,2,1)#第一张图
  5.     plt.plot(epochs,loss,'bo',label='Training loss')
  6.     plt.title("Training loss")
  7.     plt.xlabel('Epochs')
  8.     plt.ylabel('Loss')
  9.     plt.legend()
  10.     plt.subplot(1,2,2)#第二张图
  11.     accuracy=history.history['accuracy']
  12.     plt.plot(epochs,accuracy,'bo',label='Training accuracy')
  13.     plt.title("Training accuracy")
  14.     plt.xlabel('Epochs')
  15.     plt.ylabel('Accuracy')
  16.     plt.suptitle("Train data")
  17.     plt.legend()
  18.     plt.show()
复制代码
6.完备代码
  1. from tensorflow.keras.datasets import mnistfrom tensorflow.keras import modelsfrom tensorflow.keras import layersfrom tensorflow.keras.utils import to_categoricalimport matplotlib.pyplot as pltimport numpy as npdef data_preprocess():
  2.     (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
  3.     train_images = train_images.reshape((60000, 28, 28, 1))
  4.     train_images = train_images.astype('float32') / 255
  5.     #print(train_images[0])
  6.     test_images = test_images.reshape((10000, 28, 28, 1))
  7.     test_images = test_images.astype('float32') / 255
  8.     train_labels = to_categorical(train_labels)
  9.     test_labels = to_categorical(test_labels)
  10.     return train_images,train_labels,test_images,test_labels#搭建网络def build_module():    model = models.Sequential()    #第一层卷积层    model.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)))    #第二层最大池化层    model.add(layers.MaxPooling2D((2,2)))    #第三层卷积层    model.add(layers.Conv2D(64, (3,3), activation='relu'))    #第四层最大池化层    model.add(layers.MaxPooling2D((2,2)))    #第五层卷积层    model.add(layers.Conv2D(64, (3,3), activation='relu'))    #第六层Flatten层,将3D张量平铺为向量    model.add(layers.Flatten())    #第七层全连接层    model.add(layers.Dense(64, activation='relu'))    #第八层softmax层,举行分类    model.add(layers.Dense(10, activation='softmax'))    return modeldef draw_loss(history):
  11.     loss=history.history['loss']
  12.     epochs=range(1,len(loss)+1)
  13.     plt.subplot(1,2,1)#第一张图
  14.     plt.plot(epochs,loss,'bo',label='Training loss')
  15.     plt.title("Training loss")
  16.     plt.xlabel('Epochs')
  17.     plt.ylabel('Loss')
  18.     plt.legend()
  19.     plt.subplot(1,2,2)#第二张图
  20.     accuracy=history.history['accuracy']
  21.     plt.plot(epochs,accuracy,'bo',label='Training accuracy')
  22.     plt.title("Training accuracy")
  23.     plt.xlabel('Epochs')
  24.     plt.ylabel('Accuracy')
  25.     plt.suptitle("Train data")
  26.     plt.legend()
  27.     plt.show()if __name__=='__main__':    train_images,train_labels,test_images,test_labels=data_preprocess()    model=build_module()    print(model.summary())    model.compile(optimizer='rmsprop', loss = 'categorical_crossentropy', metrics=['accuracy'])    history=model.fit(train_images, train_labels, epochs = 5, batch_size=64)    draw_loss(history)    test_loss, test_acc = model.evaluate(test_images, test_labels)    print('test_loss=',test_loss,'  test_acc = ', test_acc)
复制代码
迭代训练过程中loss和accuracy的变革


由于数据集比较简单,恣意的神经网络计划在测试集的正确率可达到99.2%
以上就是Python实战之MNIST手写数字辨认详解的具体内容,更多关于Python MNIST手写数字辨认的资料请关注脚本之家别的干系文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作