简介

在上一篇博客:数据挖掘入门系列教程(十点五)之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. ajax请求以及递归

    function f1() { console.log("hello"); f1(); }; f1();//浏览器崩溃,因为没有结束条件——死循环 改进如下: var i=0; f ...

  2. 前端之jQuery基础篇02-事件

    什么是事件: 在元素上移动鼠标. 选取单选按钮 点击元素 常见的DOM事件: 鼠标事件:click() 当鼠标单击发生click事件 : <!DOCTYPE html> <html& ...

  3. MySQL 在Docker下快速安装(Ubuntu 16.4)

    采用dockerhub安装 docker run -p 3306:3306 --name mysql -v /mydata/mysql/log:/var/log/mysql -v /mydata/my ...

  4. Centos下载新版内核

                                                                                              下载新版内核的安装文 ...

  5. Array(数组)对象-->数组遍历

    1.数组的遍历: 方法1:使用for循环语句 /*定义数组*/ var arr=[1,2,3,4,5]; /*遍历*/ for (var i = 0;i<arr.length;i++){ con ...

  6. vue中axios的安装使用

    axios是一个基于 promise 的 HTTP 库,在vue中axios是比较常用的网络请求方法. 安装 npm install axios -S 在main.js配置 import axios ...

  7. Windows Server 2016 Storage Replication

    Storage Replication是Windows Server 2016中新增的一项功能,它是利用windows server自带的块存储复制技术 首先,我们简答粗暴的交代一下部署需求: 1.该 ...

  8. AJ学IOS(11)UI之图片自动轮播

    AJ分享,必须精品 先看效果 代码 #import "NYViewController.h" #define kImageCount 5 @interface NYViewCont ...

  9. 区块链 Hyperledger Fabric v1.0.0 环境搭建

    前言:最近项目涉及到超级账本,在有些理论知识的基础上,需要整一套环境来. 这是一个特别要注意的事情,笔者之前按照网络上推荐,大部分都是推荐ubuntu系统的,于是下载Ubuntu系统(16.04.5和 ...

  10. 打印图片的属性和实现另存图片功能以及使用numpy

    上一篇我们已经学了如何读取图片的功能了以及和opencv的环境搭建了,今天接着来学习,哈哈哈,今天刚好五一,也没闲着,继续学习. 1. 首先我们来实现打印出图片的一些属性功能, 先来看一段代码: im ...