简介

在上一篇博客:数据挖掘入门系列教程(十点五)之DNN介绍及公式推导中,详细的介绍了DNN,并对其进行了公式推导。本来这篇博客是准备直接介绍CNN的,但是想了一下,觉得还是使用keras构建一个DNN网络,然后进行一定的分类操作,这样能够更加的直观一点。

在这篇博客中将介绍:

  • keras的基本使用
  • 使用keras构建DNN对MNIST数据集进行预测

使用前准备

这次我们将使用keras库去构建神经网络,然后默认使用tensorflow作为后端,我是用的python库版本如下:

  • keras:version 2.3.1
  • tensorflow:version 2.1.0

这篇博客并不会讲keras,tensorflow的安装,不过值得注意的是,如果自己电脑有英伟达的显卡就尽量去装gpu版本的tensorflow,然后安装对应版本的cuda。一般来说使用GPU能够大幅度提高程序计算的速度(我的mx250哭晕在厕所)。至于AMD的显卡,emm,我就不知道支不支持了。

关于keras的具体使用,可以去看一看官方文档,但是目前官方文档的目录栏有一点问题,因此建议大家去看这个keras 中文文档,这个是根据官方文档生成的。

准备数据集

这里我们使用keras提供MNIST数据集,训练集为 60,000 张$ 28\times 28 = 784$像素灰度图像,测试集为 10,000 同规格图像,总共 10 类数字标签。

from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

然后我们可以看一看数据集的shape:

print(x_train.shape, 'x_train samples')
print(x_test.shape, 'x_test samples')
print(y_train.shape, 'y_trian samples')
print(y_test.shape, 'Y_test samples')

此时,我们就已经加载好数据集了。我们可以稍微的看一看数据集长什么样子:

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(12,10))
x, y = 8, 6
for i in range(x*y):
plt.subplot(y, x, i+1)
plt.imshow(x_train[i],interpolation='nearest')
plt.show()

因为数据集并不能能够直接进行训练或者训练效果不好,在这里我们将数据进行一下变换。比如说归一化,onehot编码(这个必须做)。

数据集的变换

首先,我们的DNN的设计如下:

输入层是由784个神经元构成的,但是在前面我们已经知道x_train.shape(6000,28,28)。输出层由10个神经元构成,而y_train.shape(6000,),毋庸置疑,我们需要对x,y数据进行编码。

对于x数据来说,我们需要将它变成(6000,784)的类型,对于y我们进行onehot编码就行了(one hot编码在前面已经介绍过了,这里就不多做介绍了),同时在这里我们还将数据进行归一化(可以提高模型的准确率)。

import keras
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
# 将数据变成float类型,这样能够被255除
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255 # one hot 编码,将类向量(整数)转换为二进制类矩阵。
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

构建DNN网络

首先我们导入Sequential

from keras.models import Sequential

Sequential是一个顺序模型:多个网络层的线性堆叠,每一层接受上一层的输入,向下一层进行输出,示意图如下:

这里,再说一个概念,全连接层,很简单理解,就是某一层用数学公式来表达就是\(output = W\times input\),比如说下图中的layer2和layer3就是全连接的,也就是说layer2是全连接层。在keras中,可以使用Dense去创建一个全连接层。

关于Dense的参数,截取官方文档如下:

参数

  • units: 正整数,输出空间维度。
  • activation: 激活函数 (详见 activations)。 若不指定,则不使用激活函数 (即,「线性」激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (see initializers).
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向的的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层的输出的正则化函数 (它的 "activation")。 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

然我们来看一看具体的使用(里面涉及的几个激活函数随便去网上搜一下就知道了):

from keras.layers import Dense, Dropout
# 创建一个网络模型
model = Sequential()
# 创建输入层 512代表的是输出维度为512,也就是第二层神经元有512个,输入维度为(784,),激活函数为Relu
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2)) # 创建layer2,然后向下层输出的空间维度为512
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2)) # 输出层,因为只有10个数字,所以输出空间维度为10,激活函数为softmax。
model.add(Dense(10, activation='softmax')) # 网络模型的介绍
print(model.summary())

Dropout 应用于输入。Dropout 包括在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合

简单点来说,他就是这样的,随机(按比率)将某一个输入值变成0,这样他就没办法向下一层传递信息。

打印的网络结构模型如下所示,还是有蛮多参数的:

接着我们就来讲一下如何配置这个模型,在keras中,配置一个模型至少需要两个参数lossoptimizer。其中loss就是损失函数optimizer就是优化器,也就是前篇博客提到的优化方法,比如说梯度下降法,牛顿法等等,metrics代表在训练和测试期间的模型评估标准。

from keras.optimizers import RMSprop

model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(),
metrics=['accuracy'])

这里我们选择RMSprop,具体内容可以参考Day 69: rmsprop,然后loss我们选择categorical_crossentropy,因为它是多分类任务。其表达式为:

\(C E(x)=-\sum_{i=1}^{C} y_{i} \log f_{i}(x)\)

其中, \(x\)表示输入样本, \(C\)为待分类的类别总数。 \(y_{i}\) 为第\(i\)个类别对应的真实标签, \(f_{i}(x)\) 为对应的模 型输出值。

开始训练

最后我们可以使用这个模型来训练数据了,代码:

# history保存了每一次训练的loss,accuracy
history = model.fit(x_train, y_train,
batch_size=128,
epochs=32,
verbose=1,
validation_data=(x_test, y_test))

x_train, y_train这个就没必要解释了,很简单,就是训练的数据集。

  • batch_size代表每一次梯度更新的样本数,默认32。如何理解这个这一个参数呢?意思就是说每次一训练的时候训练batch_size个样本,针对每一个样本我们都可以求出它对应的loss,然后我们求和然后取平均\(C E(x)_{\text {final}}=\frac{\sum_{b=1}^{batch\_size} C E\left(x^{(b)}\right)}{N}\),然后再使用BP算法。
  • epochs: 训练模型迭代轮次。
  • verbose: 0, 1 或 2。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
  • validation_data:用来评估损失,以及在每轮结束时的任何模型度量指标。 模型将不会在这个数据上进行训练。

部分打印数据如下:

在我的笔记本i5十代u,mx250的情况下,训练了大概1分多钟,毕竟数据集还是比较小的,然后参数也不是很多。

进行评估

# 这里的verbose和fit中的含义一样
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

最后结果如下图:

训练过程的accuracy和loss

这里我们将每一次轮训练以及测试对应的loss和accuracy画出来:


# 绘制训练过程中训练集和测试集合的准确率值
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show() # 绘制训练过程中训练集和测试集合的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

总结

ok,这篇博客就结束了。总的来说还是蛮顺利的,因为不需要去推数学公式,基本上没有什么难度(当然,如果想更好的提高准确率还是蛮难的,可以去kaggle里面看一下大佬的解决方案)。这篇博客简单的介绍了keras使用,我力求将每一个用到的函数都讲清楚,但是实际上很难,因为可能我认为讲清楚了,但是实际上你可能还是没有明白。这个时候可以去多看一下官方文档,或者别人的博客,当然,私信我也是

数据挖掘入门系列教程(十一)之keras入门使用以及构建DNN网络识别MNIST的更多相关文章

  1. 数据挖掘入门系列教程(十二)之使用keras构建CNN网络识别CIFAR10

    简介 在上一篇博客:数据挖掘入门系列教程(十一点五)之CNN网络介绍中,介绍了CNN的工作原理和工作流程,在这一篇博客,将具体的使用代码来说明如何使用keras构建一个CNN网络来对CIFAR-10数 ...

  2. 数据挖掘入门系列教程(二)之分类问题OneR算法

    数据挖掘入门系列教程(二)之分类问题OneR算法 数据挖掘入门系列博客:https://www.cnblogs.com/xiaohuiduan/category/1661541.html 项目地址:G ...

  3. 数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例)

    数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例) 简介 scikit-learn 估计器 加载数据集 进行fit训练 设置参数 预处理 流水线 结尾 数据挖掘入门系 ...

  4. 数据挖掘入门系列教程(四)之基于scikit-lean实现决策树

    目录 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris 加载数据集 数据特征 训练 随机森林 调参工程师 结尾 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理 ...

  5. 数据挖掘入门系列教程(四点五)之Apriori算法

    目录 数据挖掘入门系列教程(四点五)之Apriori算法 频繁(项集)数据的评判标准 Apriori 算法流程 结尾 数据挖掘入门系列教程(四点五)之Apriori算法 Apriori(先验)算法关联 ...

  6. 数据挖掘入门系列教程(五)之Apriori算法Python实现

    数据挖掘入门系列教程(五)之Apriori算法Python实现 加载数据集 获得训练集 频繁项的生成 生成规则 获得support 获得confidence 获得Lift 进行验证 总结 参考 数据挖 ...

  7. 数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST

    目录 数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST 下载数据集 加载数据集 构建神经网络 反向传播(BP)算法 进行预测 F1验证 总结 参考 数据挖掘入门系 ...

  8. 数据挖掘入门系列教程(九)之基于sklearn的SVM使用

    目录 介绍 基于SVM对MINIST数据集进行分类 使用SVM SVM分析垃圾邮件 加载数据集 分词 构建词云 构建数据集 进行训练 交叉验证 炼丹术 总结 参考 介绍 在上一篇博客:数据挖掘入门系列 ...

  9. 数据挖掘入门系列教程(十点五)之DNN介绍及公式推导

    深度神经网络(DNN,Deep Neural Networks)简介 首先让我们先回想起在之前博客(数据挖掘入门系列教程(七点五)之神经网络介绍)中介绍的神经网络:为了解决M-P模型中无法处理XOR等 ...

随机推荐

  1. localStorage应用(写的时间缓存在本地浏览器)

    最近用了下localStorage,于是想记录加深下映象: 有关更详细的介绍,可以去看https://www.cnblogs.com/st-leslie/p/5617130.html: 我这引用了这个 ...

  2. Codeforces Round #628 (Div. 2)

    1325A - EhAb AnD gCd 题意:随意找两个数是他们的最大公约数 GCD 与最小公倍数 LCM 之和为所给定的值. 思路:找一下规律 ,假设所给的 数位n, 那么我们将n分成 1 ,n- ...

  3. LeetCode 题解 | 242. 有效的字母异位词

    给定两个字符串 s 和t,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram" 输出 ...

  4. 百度找不到,但高手都知道(感觉他们都知道)的一个小细节--BUG调试报告

    语言 Batch 前言 以前我一直不明白为什么那么多应用程序在读取"文件路径"作为参数时为什么总是在正式的"文件路径"前要加上个"-f".& ...

  5. Docker基础修炼2--Docker镜像原理及常用命令

    通过前文的讲解对Docker有了基本认识之后,我们开始进入实战操作,本文先演示Docker三要素之镜像原理和相关命令. 本文的演示环境仍然沿用上一篇文章在本地Centos7中安装的环境,如果你本地没有 ...

  6. MySQL5.7使用Notifier启动、停止服务时出现的问题

    1.选择右击右下角 MySQL Notifier ,选择 Actions -> Manage Monitored Items 2.选择当前的服务 MySQL57  并进行删除 3.然后点击  a ...

  7. 树状数组模板--Color the ball

    Color the ball HDU - 1556 N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电 ...

  8. JNDI数据源的配置及使用 (2010-11-21 21:16:43)转载▼

    JNDI数据源的配置及使用 (2010-11-21 21:16:43)转载▼ 标签: 杂谈 分类: 数据库 数据源的作用 JDBC操作的步骤: 1. 加载驱动程序 2. 连接数据库 3. 操作数据库 ...

  9. Pytorch自定义创建BP神经网络

    class BPNet(nn.Module): def __init__(self, in_dim, n_hidden_1, n_hidden_2,\ n_hidden_3, n_hidden_4, ...

  10. 知识点二:HTTP超文本文件传输协议

    HTTP超文本传输协议概念: http1.1之前采用非持续链接服务器在建立连接上开销较大,http1.1之后默认采用持续连接,并有超时设置 http协议:超文本文件传输协议,用于传输文本文件,请求的方 ...