使用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. Toast 响应点击事件

    import java.lang.reflect.Field; import android.content.Context; import android.util.Log; import andr ...

  2. 【学习中】Unity插件之NGUI 完整视频教程

    课程 章节 内容 签到 Unity插件之NGUI 完整视频教程 第一章 NGUI基础控件和基础功能学习 1.NGUI介绍和插件的导入 6月29日 2.创建UIRoot 6月29日 3.学习Label控 ...

  3. 【jmespath】—4. 进阶 Flatten Projections

    这里要怎么翻呢?扁平投影? 一.Flatten Projections 1. 核心1 这个可以暂时忽略,一个重要的核心是:对于列表/对象投影,在投影中创建投影时,原始文档的结构将保留. 说人话就是,比 ...

  4. 深入了解Netty【八】TCP拆包、粘包和解决方案

    1.TCP协议传输过程 TCP协议是面向流的协议,是流式的,没有业务上的分段,只会根据当前套接字缓冲区的情况进行拆包或者粘包: 发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由 ...

  5. 发送信息到邮箱的第三方扩展库PHPMailer使用方法

    一.下载 使用composer下载PHPMailer :composer require phpmailer/phpmailer 二.使用实例 use PHPMailer\PHPMailer\PHPM ...

  6. 被Spring坑了一把,查看源码终于解决了DataFlow部署K8s应用的问题

    1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Docker & Kubernetes相关文章:容器技术 基于各种原因,团队的Kubernetes被加了限制,必须在 ...

  7. 保存vuex状态刷新不消失

    写在App.vue中,所有页面共享此方法 export default { name: "app", components: {}, created() { // 页面每次刷新加载 ...

  8. Activiti7 查询用户任务列表

    package com.itheima.activiti; import org.activiti.engine.ProcessEngine; import org.activiti.engine.P ...

  9. Mybatis-使用注解开发

    使用注解开发 [toc] 1. 面向接口编程 大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 ...

  10. pytest allure 生成html测试报告

    前提:需要 java 1.8 以上.python3环境 一.下载pytest pip install pytest 二.下载Allure Pytest Adaptor插件 pip install py ...