失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)

深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)

时间:2021-08-16 08:21:33

相关推荐

深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)

目录

一、前期准备

1.1 环境配置

1.2 CPU和GPU

1.2.1 CPU

1.2.2 GPU

1.2.3 CPU和GPU的区别

第一步:设置GPU

1.3 MNIST 手写数字数据集

第二步:导入数据

1.4 归一化

第三步:归一化

二、其他代码理解

2.1 可视化图片

第四步:可视化

2.2 调整图片格式

第五步:调整图片格式

2.3 构建CNN网络

2.3.1 卷积神经网络(CNN)

2.3.2 主要结构

第六步:构建CNN网络模型

2.3.3 编译模型

第七步:编译模型

2.3.4 训练模型

第八步:训练模型

2.3.5 预测

第九步:预测

活动地址:CSDN21天学习挑战赛

学习:深度学习100例-卷积神经网络(CNN)实现mnist手写数字识别 | 第1天_K同学啊的博客-CSDN博客

(文章内部分相关概念解释来源于百度

一、前期准备

1.1 环境配置

详情请见博主的另一篇文章

深度学习21天——准备(环境配置)_清园暖歌的博客-CSDN博客

1.2 CPU和GPU

1.2.1 CPU

CPU(Central Processing Unit-中央处理器),是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。

1.2.2 GPU

GPU(Graphics Processing Unit-图形处理器),是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。

1.2.3 CPU和GPU的区别

(1)缓存

CPU有大量的缓存结构,目前主流的CPU芯片上都有四级缓存,这些缓存结构消耗了大量的晶体管,在运行的时候需要大量的电力。

GPU的缓存就很简单,目前主流的GPU芯片最多有两层缓存,而且GPU可以利用晶体管上的空间和能耗做成ALU单元,因此GPU比CPU的效率要高一些。

(2)响应方式

CPU要求的是实时响应,对单任务的速度要求很高,所以就要用很多层缓存的办法来保证单任务的速度。

GPU是把所有的任务都排好,然后再批处理,对缓存的要求相对很低。

(3)浮点运算方式

CPU除了负责浮点整形运算外,还有很多其他的指令集的负载,比如像多媒体解码,硬件解码等,因此CPU是多才多艺的。CPU注重的是单线程的性能,要保证指令流不中断,需要消耗更多的晶体管和能耗用在控制部分,于是CPU分配在浮点计算的功耗就会变少。

GPU基本上只做浮点运算的,设计结构简单,也就可以做的更快。GPU注重的是吞吐量,单指令能驱动更多的计算,相比较GPU消耗在控制部分的能耗就比较少,因此可以把电省下来的资源给浮点计算使用。

(4)应用方向

CPU所擅长的像操作系统这一类应用,需要快速响应实时信息,需要针对延迟优化,所以晶体管数量和能耗都需要用在分支预测、乱序执行、低延迟缓存等控制部分。

GPU适合对于具有极高的可预测性和大量相似的运算以及高延迟、高吞吐的架构运算。

所以,我们在做深度学习时,有条件尽量使用gpu,更有效率、节能

第一步:设置GPU

import tensorflow as tfgpus = tf.config.list_physical_devices("GPU")if gpus:gpu0 = gpus[0] #如果有多个GPU,仅使用第0个GPUtf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用tf.config.set_visible_devices([gpu0],"GPU")

1.3 MNIST 手写数字数据集

MNIST是一个公开的数据集,获取网址为MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges(下载后需解压)

mnist 是一个包含 60,000 个 28x28 的 10 位灰度图像的数据集,以及一个包含 10,000 个图像的测试集。更多信息可以在 MNIST 主页上找到

第二步:导入数据

import tensorflow as tffrom tensorflow.keras import datasets, layers, modelsimport matplotlib.pyplot as plt(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

train_images:uint8 具有形状的灰度图像数据的 NumPy 数组(60000, 28, 28),包含训练数据。像素值范围从 0 到 255。

train_labels:uint8 NumPy 数字标签数组(0-9 范围内的整数)与形状(60000,)对于训练数据。

test_images:uint8 NumPy 灰度图像数据数组,形状为 (10000, 28, 28),包含测试数据。像素值范围从 0 到 255。

test_labels:uint8 NumPy 数字标签数组(0-9 范围内的整数)与形状(10000,)为测试数据。

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()assert x_train.shape == (60000, 28, 28)assert x_test.shape == (10000, 28, 28)assert y_train.shape == (60000,)assert y_test.shape == (10000,)

1.4 归一化

归一化是为了消除量纲,因为数据都是 0-255 的像素值,所以这里除以 255

第三步:归一化

# 将像素的值标准化至0到1的区间内。train_images, test_images = train_images / 255.0, test_images / 255.0train_images.shape,test_images.shape,train_labels.shape,test_labels.shape"""输出:((60000, 28, 28), (10000, 28, 28), (60000,), (10000,))"""

二、其他代码理解

2.1 可视化图片

第四步:可视化

plt.figure(figsize=(20,10)) # 生成指定宽和高的画布(20,10)for i in range(20):plt.subplot(5,10,i+1)# 生成5行10列位置,这个是第i+1个plt.xticks([]) # 横坐标刻度为空plt.yticks([]) # 纵坐标刻度为空plt.grid(False) # False:设置背景网格线不显示plt.imshow(train_images[i], cmap=plt.cm.binary) # 显示第i个图片,binary为黑白色(二值)plt.xlabel(train_labels[i]) # 显示第i个标签plt.show()

(1)figure语法说明

figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)

num:图像编号或名称,数字为编号 ,字符串为名称

figsize:指定figure的宽和高,单位为英寸;

dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80 1英寸等于2.5cm,A4纸是 21*30cm的纸张

facecolor:背景颜色

edgecolor:边框颜色

frameon:是否显示边框

参考plt.figure()参数使用详解及运行演示_超级-马里奥的博客-CSDN博客_plot.figure

2.2 调整图片格式

第五步:调整图片格式

#调整数据到我们需要的格式train_images = train_images.reshape((60000, 28, 28, 1))test_images = test_images.reshape((10000, 28, 28, 1))train_images.shape,test_images.shape,train_labels.shape,test_labels.shape"""输出:((60000, 28, 28, 1), (10000, 28, 28, 1), (60000,), (10000,))"""

reshape的第四个参数可能是 排序:顺序或逆序,不确定

2.3 构建CNN网络

2.3.1 卷积神经网络(CNN)

以下概念摘自学习笔记:深度学习(3)——卷积神经网络(CNN)理论篇_新四石路打卤面的博客-CSDN博客_图解卷积神经网络

CNN是一种带有卷积结构的前馈神经网络,卷积结构可以减少深层网络占用的内存量,其中三个关键操作——局部感受野、权值共享、池化层,有效的减少了网络的参数个数,缓解了模型的过拟合问题。

卷积层和池化层一般会取若干个,采用卷积层和池化层交替设置,即一个卷积层连接一个池化层,池化层后再连接一个卷积层,依此类推。由于卷积层中输出特征图的每个神经元与其输入进行局部连接,并通过对应的连接权值与局部输入进行加权求和再加上偏置值,得到该神经元输入值,该过程等同于卷积过程,CNN也由此而得名1。

CNN主要应用于图像识别(计算机视觉,CV),应用有:图像分类和检索、目标定位检测、目标分割、人脸识别、骨骼识别和追踪,具体可见MNIST手写数据识别、猫狗大战、ImageNet LSVRC等,还可应用于自然语言处理和语音识别。

总的来说,CNN是为了解决两个难题:① 图像需要处理的数据量太大,导致成本很高,效率很低;② 图像在数字化的过程中很难保留原有的特征,导致图像处理的准确率不高。

2.3.2 主要结构

CNN主要包括以下结构:

(1)输入层(Input layer):输入数据;

(2)卷积层(Convolution layer,CONV):使用卷积核进行特征提取和特征映射;

(3)激活层:非线性映射(ReLU)

(4)池化层(Pooling layer,POOL):进行下采样降维;

(5)光栅化(Rasterization):展开像素,与全连接层全连接,某些情况下这一层可以省去;

(6)全连接层(Affine layer / Fully Connected layer,FC):在尾部进行拟合,减少特征信息的损失;

(7)激活层:非线性映射(ReLU)

(8)输出层(Output layer):输出结果。

其中,卷积层、激活层和池化层可叠加重复使用,这是CNN的核心结构。

在经过数次卷积和池化之后,最后会先将多维的数据进行“扁平化”,也就是把(height,width,channel)的数据压缩成长度为height × width × channel的一维数组,然后再与FC层连接,这之后就跟普通的神经网络无异了。

具体每个层的内容就直接到我上面转的那个博主的文章看吧

第六步:构建CNN网络模型

model = models.Sequential([layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),#卷积层1,卷积核3*3layers.MaxPooling2D((2, 2)), #池化层1,2*2采样layers.Conv2D(64, (3, 3), activation='relu'), #卷积层2,卷积核3*3layers.MaxPooling2D((2, 2)), #池化层2,2*2采样layers.Flatten(),#Flatten层,连接卷积层与全连接层layers.Dense(64, activation='relu'), #全连接层,特征进一步提取layers.Dense(10) #输出层,输出预期结果])# 打印网络结构model.summary()

下图来自深度学习100例-卷积神经网络(CNN)实现mnist手写数字识别 | 第1天_K同学啊的博客-CSDN博客

(1)layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)):

其他参数参考:TensorFlow 之 keras.layers.Conv2D( ) 主要参数讲解_分发吧的博客-CSDN博客_layers.conv2d

32:32个核

(3,3):卷积核大小为3×3

activation='relu':激活函数

input_shape:根据名称判断该参数应该是单个数据的shape值

此外步长未指定,应该是默认的 1

relu激活函数

公式: f ( x ) = m a x ( 0 , x )

图像:

1. 为什么要用ReLU激活函数

由于sigmoid函数在输入远离中心点时导数会很小,会出现梯度消失的现象。使用ReLU激活函数时则不会出现梯度消失的现象。

但是当输入为负数时ReLU函数会死掉,拐点不可导。所以需要做特殊处理。

转自文章:“智能”(5)——ReLU激活函数&卷积神经网络_Nevey-Chen的博客-CSDN博客_activation='relu

sigmoid函数:f(x)= 1/(1+e^(-z))

(2)layers.MaxPooling2D((2, 2))

设置池化层的尺寸为 2×2

其他参数参考:CNN中的最大池化(MaxPool2D)的参数和含义,_园游会的魔法糖的博客-CSDN博客_maxpooling2d

(3)models.Sequential

Sequential()方法是一个容器,描述了神经网络的网络结构,在Sequential()的输入参数中描述从输入层到输出层的网络结构

tensorflow中tf.keras.models.Sequential()用法_yunfeather的博客-CSDN博客_models.sequential()

(4)layers.dense

tf.layers.dense用于添加一个全连接层。

函数如下:

tf.layers.dense(inputs,#层的输入units,#该层的输出维度activation=None, #激活函数use_bias=True, kernel_initializer=None, # 卷积核的初始化器bias_initializer=tf.zeros_initializer(), # 偏置项的初始化器kernel_regularizer=None, # 卷积核的正则化bias_regularizer=None, # 偏置项的正则化activity_regularizer=None,kernel_constraint=None,bias_constraint=None,trainable=True,name=None, # 层的名字reuse=None # 是否重复使用参数)

部分参数解释:

inputs:输入该层的数据。

units:该层的输出维度。

activation:激活函数。

use_bias:是否使用偏置项。

trainable=True:表明该层的参数是否参与训练。

tf.layers.dense的使用方法_Bubbliiiing的博客-CSDN博客_layers.dense

2.3.3 编译模型

第七步:编译模型

"""这里设置优化器、损失函数以及metrics这三者具体介绍可参考博客:/qq_38251616/category_10258234.html"""pile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])

/qq_38251616/category_10258234.html

tensorflow中pile()用法_yunfeather的博客-CSDN博客pile

adam算法介绍和总结_Only_whitecat的博客-CSDN博客_adam 算法

简而言之,adam算法可以在传统梯度下降算法的基础上,能够自适应的改变学习率

2.3.4 训练模型

plt.imshow(test_images[1])

第八步:训练模型

"""这里设置输入训练数据集(图片及标签)、验证数据集(图片及标签)以及迭代次数epochs关于model.fit()函数的具体介绍可参考博客:/qq_38251616/category_10258234.html"""history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))

/qq_38251616/category_10258234.html

2.3.5 预测

第九步:预测

pre = model.predict(test_images) # 对所有测试图片进行预测pre[1] # 输出第一张图片的预测结果

与测试集的一张图片比较

plt.imshow(test_images[1])

如果觉得《深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。