一、前文回顾
上一节笼统的介绍了卷积的概念和卷积神经网络的结构。但是我个人觉得应该比较难理解。所以这节用一个实例来演示一下。
----理论所不能解决的那些疑难,实践会给你解决----
二、MNIST手写数据集
以前我们通过传统神经网络实现了MINIST手写数据集的学习和识别,我记得准确率可以达到94%左右,今天来看看用卷积神经网络CNN来识别,准确率能达到多少。
为了缩短代码篇幅以及便于理解我会采用google的TensorFlow框架来实现,直接上代码
from tensorflow.keras import datasets, layers, models
if __name__ == "__main__":
# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
# 改变训练数据集图像形状(60000张图片,每张图片大小是28*28,通道为1,也就是灰度图)
train_images = train_images.reshape((60000, 28, 28, 1))
# 改变测试数据集图像形状(10000张图片,每张图片大小是28*28,通道为1,也就是灰度图)
test_images = test_images.reshape((10000, 28, 28, 1))
# 每张图片的像素归一化(0~255的像素值压缩到0~1的区间,以方便运算)
train_images, test_images = train_images / 255.0, test_images / 255.0
# 加载模型
model = models.Sequential()
# 添加卷积层,卷积核大小为3*3,输出维度为32,激励函数为Relu
model.add(layers.Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)))
# 添加池化层,池化方式为2*2大小的四个像素中的最大值作为要处理的像素值。
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation="relu"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation="relu"))
# 把输出展开为一维数组
model.add(layers.Flatten())
# 全连接层(64个神经元,并且和上一层的每个神经元相连接,这样可以减少图像特征信息的损失)
model.add(layers.Dense(64, activation="relu"))
# 全连接层(输出神经元为10个,然后用softmax函数进行分类,概率最大的就是预测值)
model.add(layers.Dense(10, activation="softmax"))
model.summary()
# 添加损失函数:交叉熵损失函数
# 添加优化器:adam
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 训练神经网络
model.fit(train_images, train_labels, epochs=5)
# 评价神经网络
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
# 输出评价结果
print(test_acc)
执行以后准确率可以到98%多了,这个准确度已经超过了人眼的识别率。我们再来一张动图以便加强对神经网络的识别过程的理解(网上找的图,所以网络结构和我们的不太一样,但是都是CNN网络)。说实话看起来很抽象,但是能对CNN结构有个大概的印象就足够了。

三、优化器(optimizer)
优化器:就是怎么样让损失函数以最快的速度到达最小值,这中间有很多算法,比如SGD,Momentum,AdaGrad,adam等等,有兴趣的可以自己去查查看,反正我没兴趣。
四、池化层
上一节有提到池化,但是没有具体说清楚,所以在这里补充一下。池化层的目的是为了减少参数以加快运算速度,具体的操作方法也很简单,看下图

MaxPooling就是从2*2(或者其他指定大小区域)的格子里选最大的只拿出来计算,其余就忽视掉了。当然也有AveragePooling就是2*2的格子里面的平均值,不过图像处理方面一般都会选择MaxPooling
池化层的特点
①池化层没有参数,只是对图像中的像素进行消减
②图像的维度没有变化,
③即使输入图像稍微有点区别,输出也保持不变
五、小结
从最初的感知机到传统神经网络,再到现在的卷积神经网络,一整套已经说完了,剩下的就是怎么样利用CNN来具体实现各种需求了,比如人脸识别,行人检测等等。在正式进入CNN实战之前,我决定先把图像处理的基础夯实,所以神经网络就到此结束。接下来我会陆续更新一些图像处理的基础知识。(我只会基础,毕竟javaWeb才是我吃饭的家伙,图像处理深度学习只是兴趣)
Comments