实验四:深度学习算法及应用
一、实验目的
1、了解深度学习的基本原理;
2、能够使用深度学习开源工具;
3、应用深度学习算法求解实际问题。
二、实验要求
1、解释深度学习原理;
2、对实验性能进行分析;
3、回答思考题。
三、实验平台
1、https://www.educoder.net/paths/369
2、百度飞桨及AIstudio平台
https://www.paddlepaddle.org.cn/
3、华为昇腾平台
https://www.hiascend.com/zh/developer/case-studies
四、实验内容与步骤
选用一个实验平台,采用开源深度学习工具求解实际人工智能应用问题,例如计算机视觉、自然语言处理、无人驾驶、语音识别等。
五、思考题:
1.深度算法参数的设置对算法性能的影响?
六、实验报告要求
1.应用问题的描述;
2.对算法原理进行解释;
2.对实验步骤进行详细描述;
3.对实验结果进行分析。
实验四:深度学习算法及应用
一、应用问题描述
编写 Python 代码动手搭建 CNN 模型实现手写数字识别
构建出如下结构的卷积神经网络:
64 个 55 的卷积核组成的卷积层,激活函数为 relu;
最大池化层,池化核大小为 22;
扁平;
128 个神经元的全连接层,激活函数为 relu;
10 个神经元的全连接层,激活函数为 softmax。
二、算法原理和代码实现
1、认识数据
训练一个卷积神经网络来识别 MNIST 数据集种的数字。
2、卷积神经网络
想要识别图像中的物体,就需要提取出比较好的特征,该特征应能很好地描述想要识别的物体。所以物体的特征提取是一项非常重要的工作。而图像中物体的特征以下几种特点:
①物体的特征可能只占图像中的一小部分。
②同样的特征可能出现在不同图像中的不同位置。
③缩放图像的大小对物体特征的影响可能不大。
3、卷积
卷积说白了就是有一个卷积核(其实就是一个带权值的滑动窗口)在图像上从左到右,从上到下地扫描,每次扫描的时候都会将卷积核里的值所构成的矩阵与图像被卷积核覆盖的像素值矩阵做内积。整个过程如下图所示,其中黄色方框代表卷积核,绿色部分代表单通道图像,红色部分代表卷积计算后的结果,通常称为特征图:
内积的计算结果就是图像中3 行 3 列子图像与卷积核的相似程度,相似程度越高说明该区域中的像素值与卷积核越相似。
4、池化
池化就是将输入图像进行缩小,减少像素信息,只保留重要信息。通常情况下,池化区域是 2 行 2 列的大小,然后按一定规则转换成相应的值。最大池化保留了每一小块内的最大值,也就是相当于保留了这一块最佳的匹配结果。
5、全连接网络
提取好特征之后就可以使用全连接网络来进行分类。
可以将全连接网络理解成很多个简单的分类器的组合,来构建成一个非常强大的分类器。
全连接网络的大致结构如下:
输入层:对图像进行卷积,池化等计算之后并进行扁平后的特征图。
隐藏层:隐藏层中每个方块代表一个神经元,每一个神经元可以看成是一个很简单的线性分类器和激活函数的组合。
输出层:输出层中神经元的数量一般为标签类别的数量。
6、卷积神经网络大致结构
通常来说卷积,池化可以多叠加几层用来提取特征,然后接上一个全连接网络来进行分类。大致结构如下:
扁平:卷积或者池化后想要接上全连接层之前需要接入扁平层,相当于一个接口
7、使用 Keras 构建卷积神经网络
Keras 遵从了极简主义,提供了一些简单易用的接口,使得我们能够很快的构建出属于自己的卷积神经网络。
构建卷积神经网络的步骤如下:
1 . 实例化 Sequential 对象。
2 . 往 Sequential 对象中添加层(卷积层,池化层,全连接层…)。
实例化 Sequential 对象
from keras.models import Sequential
model = Sequential()
添加层
add 的对象是 Layer 对象,例如 Conv2D (卷积层), MaxPooling2D (最大池化层), Flatten (扁平层), Dense (全连接层)等。
add 一层全连接层
from keras.layers import Dense
model = Sequential()
‘’’
units=64表示这层有64个神经元
activation=‘relu’表示这层的激活函数是relu
‘’’
model.add(Dense(units=64, activation=‘relu’)
add 一层卷积层
from keras.layers import Conv2D
model = Sequential()
‘’’
16表示该卷积层有16个卷积核
kernel_size=3表示卷积核的大小为33
activation='relu’表示卷积层的激活函数是relu
input_shape=[IMAGE_HEIGHT, IMAGE_WIDTH, 3]表示待卷积图像为3232的3通道图像
‘’’
model.add(Conv2D(16, kernel_size=3, activation=‘relu’, input_shape=[32, 32, 3]))
add 一层最大池化层
from keras.layers import Conv2D
model = Sequential()
‘’’
pool_size=2表示池化窗口的大小为2*2
‘’’
model.add(MaxPooling2D(pool_size=2))
add 一层扁平层
from keras.layers import Conv2D
model = Sequential()
‘’’
卷积或者池化后想要接上全连接层之前需要接入扁平层
‘’’
model.add(Flatten())
完整代码
from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D, Flatten, Dense
import numpy as np
# 设置随机种子
np.random.seed(1447)
def build_model():
# 实例化Sequential对象
model = Sequential()
# 1.有32个5*5的神经元的卷积层,激活函数为relu,输入的数据为宽28高28的灰度图像
model.add(Conv2D(32, (5, 5), activation='relu', input_shape=[28, 28, 1]))
# 2.有64个5*5的神经元的卷积层,激活函数为relu
model.add(Conv2D(64, (5, 5), activation='relu'))
# 3.最大池化层,池化核大小为2*2
model.add(MaxPool2D(pool_size=(2, 2)))
# 4.扁平
model.add(Flatten())
# 5.有128个神经元的全连接层,激活函数为relu
model.add(Dense(128, activation='relu'))
# 6.有10个神经元的全连接层,激活函数为softmax
model.add(Dense(10, activation='softmax'))
return model
当构建好模型后就可以使用compile函数编译模型,编译模型的作用是来指定损失函数、参数的更新方法等信息。
‘’’
loss=‘categorical_crossentropy’表示使用交叉熵损失函数
optimizer=keras.optimizers.SGD(lr=0.0001)表示训练时使用mini-batch梯度下降方法来更新参数,学习率为0.0001
metrics=[‘accu\fracy’]表示训练时模型主要考量正确率
‘’’
model.compile(loss=‘categorical_crossentropy’, optimizer=keras.optimizers.SGD(lr=0.0001),
metrics=[‘accu\fracy’])
编译完模型之后,就可以使用 Keras 提供的 fit 函数来进行模型的训练了。 fit 函数的使用也十分简单,只需传入训练集的图像、训练集图像所对应的 onehot 编码、训练的迭代次数以及 batch 数量即可。
‘’’
images表示的是训练集图像
onehot表示的是训练集图像所对应的onehot编码
epochs=5表示的是迭代5次
batch=32表示batch的数量是32
verbose=0表示在训练过程中不打印损失值、正确率等信息
‘’’
model.fit(images, onehot, epochs=5, batch_size=32, verbose=0)
训练好模型之后,我们就可以使用训练好的模型进行预测了。代码如下:
‘’’
images表示待预测图像
batch_size表示batch的数量
‘’’
result = model.predict(images, batch_size=32)
三、实验结果
四、思考题
深度算法参数的设置对算法性能的影响?
batch,学习率,迭代次数,dropout的keep_prob大小都会影响算法的性能;
batch为50时比其他条件相同时batch为100效果要稍微好一些;
学习率大了收敛速度快,但是会有抖动现象,学习率小了收敛速度又很慢;
未收敛之前,错误率随着迭代次数的增加而减小,但越到后面越趋于稳定,所以迭代次数并不是越多越好,还要考虑时间耗费;
dropout小于1时,会增加模型训练的时间,但是一定程度上可以解决过拟合的问题。