使用CNN卷积神经网络(2)

使用Tensorflow搭建简单的CNN卷积神经网络对fashion_mnist数据集进行分类

不了解是那么是CNN卷积神经网络的小伙伴可以参考上一篇博客(Tensorflow学习笔记No.4.1)

2.Tensorflow卷积神经网络相关API简介

2.1.keras.layers.Conv2D()二维卷积层

例如:

model.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same')

  向model中添加一个二维卷积层,第一个参数是filter,也就是卷积核的个数,决定了这层卷积层输出的数据有多少个通道。第二个参数是卷积核的大小,这里使用的是3×3的卷积核。activation是激活函数,不再赘述。

  padding则是卷积层的填充模式。简单来说,设卷积核的尺寸为k×k,输入数据的尺寸为size×size,若填充模式为‘same’,则卷积层输出的尺寸与输入时相同,为size×size,若为默认模式‘valid’,则输出的尺寸为(size-(k-1))×(size-(k-1))。  

  strides参数(示例中没有出现),它是卷积核每次移动的跨度,默认为(1, 1),分别是在x和y轴上移动的跨度,若调整为(2, 2)则卷积层的输出尺寸会将变为原来的1/2,即(size/2)×(size/2),同理,若为(k, k)则输出尺寸变为(size/k)×(size/k),使用这个参数会严重减少输出信息,虽然能明显减少网络容量,但是容易造成关键特征的丢失,慎重使用!

2.2.keras.layers.MaxPool2D()二维卷积的池化层

例如:

1 model.add(keras.layers.MaxPool2D())
2 model.add(keras.layers.AveragePooling2D())
3 model.add(keras.layers.GlobalAveragePooling2D())

  向model中添加二维池化层。

  池化层默认尺寸pool_size参数为2×2,会把数据的尺寸缩小至原来的1/2,并且不改变深度。

  示例中的三种池化层分别为最大值池化,均值池化与全局均值池化。

  最大值池化,选择pool_size×pool_size范围内的最大值作为当前位置的值,每次移动pool_size个单位,若size无法被整除则自动填充。均值池化同理,计算范围内的均值作为当前位置的值。全局池化有所不同,它是将全部数据进行池化压缩,将数据的尺寸size×size缩小为1×1,不改变深度,通常放在全连接层之前。

3.使用Tensorflow搭建简单的卷积神经网络模型

使用tensorflow建立一个简单的CNN网络模型,对fashion_mnist数据集进行分类,是一个较为简单的10分类问题。

首先导入需要用到的模块

1 from tensorflow import keras
2 import matplotlib.pyplot as plt
3 import numpy as np
4 import pandas as pd

3.1加载并处理数据

  加载fashion_mnist数据集,并分为训练集和测试集。

fashion_mnist = keras.datasets.fashion_mnist
(train_image, train_label), (test_image, test_label) = fashion_mnist.load_data()

  此时的train_image与test_image的尺寸分别为(6000, 28, 28), (1000, 28, 28),分别对应图片数,图片的长和宽。

  但是卷积神经网络的输入时图片,图片应该有三个维度,长宽以及通道数(channel),fashion_mnist数据集中均为灰度图像,所以只有一个通道,我们给测试集和训练集分别加上这一维度以便作为神经网络的输入。

1  train_image = np.expand_dims(train_image, -1)
2 test_image = np.expand_dims(test_image, -1)

  这里使用了numpy的.expand_dims()方法扩展了数据集的通道,数据尺寸的最后方加入了一个维度。

  现在数据的尺寸变为(num, 28, 28, 1),即num个28×28的单通道灰度图像。

3.2建立网络模型

  使用keras.Sequential()方法建立一个Sequential模型。

1 model = keras.Sequential()

  首先向其中添加输入层,我们要尽量保留数据的特征,所以第一层就直接选用处理图像效果较好的Conv2D卷积层,尽可能的获取图像特征。

1 model.add(keras.layers.Conv2D(32, (3, 3),
2 input_shape = (28, 28, 1),
3 activation = 'relu',
4 padding = 'same'
5 ))

  Conv2D()中的主要参数在2.1中均有提及,这里不再赘述。

  input_shape参数与之前建立的Sequential模型类似,表示输入数据的尺寸,这里为28×28的单通道灰度图像,所以input_shape应该为(28, 28, 1)。

  随后向网络中添加池化层,提取主要特征并缩小数据规模。

  规模缩小到过程也是扩大感受野的过程,随着特征规模的缩小,单个卷积核单次所能覆盖的图像特征范围逐渐扩大,这是一个逐渐从提取局部特征转变为提取全局特征的过程。

1 model.add(keras.layers.MaxPool2D())

  继续添加卷积层与池化层,最后添加全连接层输出分类结果,最终的模型为:

 1 model = keras.Sequential()
2 model.add(keras.layers.Conv2D(32, (3, 3),
3 input_shape = (28, 28, 1),
4 activation = 'relu',
5 padding = 'same'
6 ))
7 #32个卷积核,每个卷积核大小为3*3,输入规格,激活函数,填充为使输出与原尺寸相同,默认(valid)为不填充
8 model.add(keras.layers.MaxPool2D())
9 #默认为2*2池化层
10 model.add(keras.layers.Conv2D(64, (3, 3), activation = 'relu'))
11 model.add(keras.layers.GlobalAveragePooling2D())
12 #全局平均池化
13 model.add(keras.layers.Dense(10, activation = 'softmax'))
14 #输出层,10分类

  这样就搭建好了一个简单的卷积神经网络。

3.3使用.compile()方法与.fit()方法训练模型

  这里与之前的训练方式相同,不熟悉的小伙伴可以翻翻之前的博客(Tensorflow学习笔记No.1)进行查看,代码如下:

1 model.compile(optimizer = 'adam',
2 loss = 'sparse_categorical_crossentropy',
3 metrics = ['acc']
4 )
5
6 history = model.fit(train_image, train_label, epochs = 30, validation_data = (test_image, test_label))

  训练过程:

  如果你使用的是notebook类的环境,训练完成后插入以下代码(Tensorflow学习笔记No.0中有相关介绍)即可查看训练的正确率图像:

1 %matplotlib inline
2 plt.plot(history.epoch, history.history.get('acc'), label = 'acc')
3 plt.plot(history.epoch, history.history.get('val_acc'), label = 'val_acc')
4 plt.legend()

  图像如下图所示:

  

4.优化已有网络模型

   以下内容是由本人经过多次试验和验证得到的:

  从刚刚训练的网络模型的训练图像中可以看出:

  训练集的正确率仅有92.5%,说明模型的拟合性不够;测试集与训练集正确率相差较大,说明在后续训练中可能出现过拟合问题。

  (注:过拟合是指在训练集达到非常好的正确率而在测试集上的正确率并不理想,这里出现的情况是训练集和测试集上的正确率均不理想,所以不能称之为过拟合,但通过图像不难看出,我们的模型继续训练下去极有可能出现过拟合现象。)

  所以我们的优化方式从这两个角度出发,首先,增加隐藏单元(卷积核)数量,加深模型深度,以增加模型的拟合度。然后,为了抑制可能出现的过拟合现象,在适当位置加入Dropout层抑制过拟合。

  改进后的模型如下:

 1 model_ = keras.Sequential()
2 model_.add(keras.layers.Conv2D(64, (3, 3),
3 input_shape = (28, 28, 1),
4 activation = 'relu',
5 padding = 'same'
6 ))
7 model_.add(keras.layers.Conv2D(64, (3, 3), activation = 'relu', padding = 'same'))
8 #添加两层Conv2D以提高拟合能力
9 model_.add(keras.layers.MaxPool2D())
10 model_.add(keras.layers.Dropout(0.25))
11 #添加Dropout抑制过拟合
12 model_.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same'))
13 model_.add(keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same'))
14 model_.add(keras.layers.MaxPool2D())
15 model_.add(keras.layers.Dropout(0.25))
16 model_.add(keras.layers.Conv2D(256, (3, 3), activation = 'relu', padding = 'same'))
17 model_.add(keras.layers.Conv2D(256, (3, 3), activation = 'relu', padding = 'same'))
18 model_.add(keras.layers.Dropout(0.25))
19 model_.add(keras.layers.GlobalAveragePooling2D())
20 model_.add(keras.layers.Dense(256, activation = 'relu'))
21 #添加Dense层进行过渡
22 model_.add(keras.layers.Dense(10, activation = 'softmax'))

  经过调整后的模型得到如下结果:

  模型的正确率图像如下:

  经过调整后的模型,拟合度有了较为明显的提高,在测试集上可以达到接近95%的正确率,在测试集上也能达到较为满意的效果,正确率约92.5%。

后续将会对模型进行改进,争取达到更高的准确率!

Tensorflow学习笔记No.4.2的更多相关文章

  1. Tensorflow学习笔记2:About Session, Graph, Operation and Tensor

    简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...

  2. Tensorflow学习笔记2019.01.22

    tensorflow学习笔记2 edit by Strangewx 2019.01.04 4.1 机器学习基础 4.1.1 一般结构: 初始化模型参数:通常随机赋值,简单模型赋值0 训练数据:一般打乱 ...

  3. Tensorflow学习笔记2019.01.03

    tensorflow学习笔记: 3.2 Tensorflow中定义数据流图 张量知识矩阵的一个超集. 超集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S ...

  4. TensorFlow学习笔记之--[compute_gradients和apply_gradients原理浅析]

    I optimizer.minimize(loss, var_list) 我们都知道,TensorFlow为我们提供了丰富的优化函数,例如GradientDescentOptimizer.这个方法会自 ...

  5. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

  6. 深度学习-tensorflow学习笔记(2)-MNIST手写字体识别

    深度学习-tensorflow学习笔记(2)-MNIST手写字体识别超级详细版 这是tf入门的第一个例子.minst应该是内置的数据集. 前置知识在学习笔记(1)里面讲过了 这里直接上代码 # -*- ...

  7. tensorflow学习笔记(4)-学习率

    tensorflow学习笔记(4)-学习率 首先学习率如下图 所以在实际运用中我们会使用指数衰减的学习率 在tf中有这样一个函数 tf.train.exponential_decay(learning ...

  8. tensorflow学习笔记(3)前置数学知识

    tensorflow学习笔记(3)前置数学知识 首先是神经元的模型 接下来是激励函数 神经网络的复杂度计算 层数:隐藏层+输出层 总参数=总的w+b 下图为2层 如下图 w为3*4+4个   b为4* ...

  9. tensorflow学习笔记(2)-反向传播

    tensorflow学习笔记(2)-反向传播 反向传播是为了训练模型参数,在所有参数上使用梯度下降,让NN模型在的损失函数最小 损失函数:学过机器学习logistic回归都知道损失函数-就是预测值和真 ...

  10. tensorflow学习笔记(1)-基本语法和前向传播

    tensorflow学习笔记(1) (1)tf中的图 图中就是一个计算图,一个计算过程.                                       图中的constant是个常量 计 ...

随机推荐

  1. Hihocoder 小Hi小Ho扫雷作死一二三

    这里贴下不用枚举方格是否为雷的方法 a表示输入标号,初始值为-1代表未探知 b表示当前格子是否有雷,初始化为0,0表示未探知,1表示探知肯定有雷,2表示探知肯定无雷(我也不知道为什么不初始化为-1,作 ...

  2. 关于ASP.NET MVC的权限认证的一些总结

    最近在学ASP.NET MVC的权限认证的一些东西,上网搜索了一阵,发现网上的方法大多数是以下几类: 一.FormsAuthentication.SetAuthCookie(admin.Name, f ...

  3. vue-cli3项目配置eslint代码规范

    前言 最近接手了一个项目,由于之前为了快速开发,没有做代码检查.为了使得代码更加规范以及更易读,所以就要eslint上场了. 安装依赖 安装依赖有两种方法: 1. 在cmd中打上把相应的依赖加到dev ...

  4. 「面向 offer 学算法」笔面试大杀器 -- 单调栈

    目录 前言 单调栈 初入茅庐 小试牛刀 打怪升级 出师试炼 前言 单调栈是一种比较简单的数据结构.虽然简单,但在某些题目中能发挥很好的作用. 最近很多大厂的笔试.面试中都出现了单调栈的题目,而还有不少 ...

  5. Medium

    https://www.medium.com 破解阅读限制 https://medium-unlimited.ml/download/

  6. leetcode刷题-74搜索二维矩阵

    题目 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列.每行的第一个整数大于前一行的最后一个整数.示例 1: 输入:matrix ...

  7. python应用 处理excel数据

    实现功能 excel表格中有4列数,分别为RMF计算得到的 β,γ,势能面及组态,需要挑选出相同 β 值下势能面最低时的组态.为了减小数据量,先将 β 值保留两位小数. 代码 import xlrd ...

  8. appium 基础二:常用api接口

    一.获取手机分辨率 size=driver.get_window_size()#获取手机屏幕大小,分辨率 print(size)#{'width': 720, 'height': 1280} 得到的是 ...

  9. JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位

    对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...

  10. Linux实战(20):Docker部署EKL入门环境记录文档

    安装环境: centos7 ,EKL全套为7.5.2版本 前期工作 拉取已下三个镜像 docker.io/logstash 7.5.2 b6518c95ed2f 6 months ago 805 MB ...