深度学习——卷积神经网络来龙去脉和MINST图像识别应用

新机器视觉

共 5735字,需浏览 12分钟

 ·

2021-09-26 23:58

点击下方卡片,关注“新机器视觉”公众号

视觉/图像重磅干货,第一时间送达

转自 | 古月居

01

写在前面

现在机器学习、深度学习的研究日益增多,并且不断成熟,许多人开始走向人工智能学习的领域。从入门到实战,是一个比较好的学习路线。我从开始接触到现在大概1年时间,其中有些时候忙着课程和其他事情,从视频学习到看书,接着尝试实战项目,这一步步走来确实学习到了许多知识。原理知识能够在实际应用中提供创新和优化的方向,而实践则能够进一步加深对理论方面的理解。

在此之前,我总结记录了一些机器学习的实战,包括《机器学习应用——电影评论情感分析模型构建》《多分类器集成学习:多数票机制、Bagging、Adaboost实例分析》《基于sklearn库的机器学习模型与调优实践详细步骤》等,感兴趣的伙伴可以查看,偏向实践更加有趣!


这次准备总结之前学习到的CNN,整理了卷积神经网络的详细内容,了解其原理来龙去脉,掌握实战深入浅出



02

深度卷积神经网络(DCNN)

1、卷积神经网络

卷积神经网络(Convolutional Neural Network,CNN,又称为ConvNet)有着它特殊的功能,网络中保留了空间信息,因此可以更好地适用于图像分类问题。原理来源于人类视觉生物学数据的启发,视觉基于多个皮质层,每层识别越来越多的结构性信息。我们看到的是很多单个的像素;然后从这些像素中,我们识别出几何组成;再然后……这样越来越多的复杂的元素,如物体、面部、人类躯干、动物等被识别出来。


很明显,图像识别分类问题就是CNN的用武之地。


深度卷积神经网络,是由很多神经网络层组成。卷积层和池化层这两种不同的网络层,经常交互出现。每个滤波器的深度在网络中由左向右增加。最后一部分通常由一个或多个全连接层组成,如下图。

2、卷积

CNN中最基础的操作是卷积,再精确一点,基础CNN所用的卷积是一种2-D卷积。也就是说,kernel只能在x,y上滑动位移,不能进行深度 (跨通道) 位移。


假设输入图像使用tf(TensorFlow)顺序,它在3个信道上的形状为(256,256),这可以表示成(256, 256, 3)。Keras中,添加一个输出维度为32并且每个滤波器为3×3的卷积层,可以写成:


model = Sequential()model.add(Conv2D(32, (3, 3), input_shape=(256, 256, 3))


这就是说,我们用3个输入信道(或输入滤波器)在一个256×256的图像上进行3×3的卷积运算,得到了一个32个信道(输出滤波器)的输出,卷积结果类似下图。

3、池化

池化,是一种降采样操作,主要目标是降低feature maps的特征空间,或者可以认为是降低feature maps的分辨率。因为feature map参数太多,而图像细节不利于高层特征的抽取。


常用的有最大池化和平均池化。


最大池化:简单地输出最大激活值作为这个区域的观测结果。在Keras中,定义一个2×2的最大池化层:


model.add(MaxPooling2D(pool_size = (2, 2)))


直观地举例如图:

平均池化:把这个区域观察到的激活值取平均值。如上图用平均池化则会得到:[[1.7,4],[3.75,2,5]]



03

Keras构建LeNet——CNN族群

LeNet是一个较简单的卷积神经网络。下图显示了其结构:输入的二维图像,先经过两次卷积层到池化层,再经过全连接层,最后使用softmax分类作为输出层。


from keras import backend as Kfrom keras.models import Sequentialfrom keras.layers.convolutional import Conv2Dfrom keras.layers.convolutional import MaxPooling2Dfrom keras.layers.core import Activationfrom keras.layers.core import Flattenfrom keras.layers.core import Densefrom keras.datasets import mnistfrom keras.utils import np_utilsfrom keras.optimizers import SGD, RMSprop, Adamimport numpy as npimport matplotlib.pyplot as plt


定义LeNet网络:


# 定义ConvNetclass LeNet:    @staticmethod    def build(input_shape, classes):        model = Sequential()        # CONV => RELU => POOL        model.add(Conv2D(20, kernel_size=5, padding="same",                         input_shape=input_shape))        model.add(Activation("relu"))        model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))        # CONV => RELU => POOL         model.add(Conv2D(50, kernel_size=5, border_mode="same"))        model.add(Activation("relu"))        model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))         # Flatten层到RELU层        model.add(Flatten())        model.add(Dense(500))        model.add(Activation("relu"))        # softmax分类器        model.add(Dense(classes))        model.add(Activation("softmax"))        return model

各层和参数说明:

1、最先是卷积阶段,我们使用ReLU激活函数,并用最大池化方法。我们的网络将学习20个卷积滤波器,其中每个滤波器的大小都是5×5。输出维度和输入形状相同,因而将是28×28像素。注意,因为二维卷积是我们管道中的第一个阶段,我们必须定义它的input_shape。最大池化操作实现了一个滑窗,它在网络层上滑动,并取水平和垂直各两个像素区域上的最大值。


2、之后的第二个卷积阶段也是用ReLU激活函数,后面再次跟着最大池化方法。把学到的卷积滤波器数量从前面的20增加到50个。在更深的网络层增加滤波器数目是深度学习中一个普遍采用的技术。


3、最后一个全连接网络,它包含500个神经元,其后是具有10个类别的softmax分类器。



04

深度学习CNN识别MINST图像

使用上一步定义的LeNet卷积神经网络,加载Keras里面封装的MINST图像数据集进行训练。


训练集和测试集划分:

60000 train samples
10000 test samples


完整代码和详细注释如下:


# 网络和训练NB_EPOCH = 5BATCH_SIZE = 128VERBOSE = 1OPTIMIZER = Adam()VALIDATION_SPLIT = 0.2IMG_ROWS, IMG_COLS = 28, 28NB_CLASSES = 10INPUT_SHAPE = (1, IMG_ROWS, IMG_COLS)# 混合并划分训练集和测试集数据(X_train, y_train), (X_test, y_test) = mnist.load_data()K.set_image_dim_ordering("th")# 把它们看成float类型并归一化X_train = X_train.astype('float32')X_test = X_test.astype('float32')X_train /= 255X_test /= 255# 我们需要使用形状60K×[1×28×28]作为卷积网络的输入X_train = X_train[:, np.newaxis, :, :]X_test = X_test[:, np.newaxis, :, :]print(X_train.shape[0], 'train samples')print(X_test.shape[0], 'test samples')# 将类向量转换成二值类别矩阵y_train = np_utils.to_categorical(y_train, NB_CLASSES)y_test = np_utils.to_categorical(y_test, NB_CLASSES)# 初始化优化器和模型model = LeNet.build(input_shape=INPUT_SHAPE, classes=NB_CLASSES)model.compile(loss="categorical_crossentropy", optimizer=OPTIMIZER,              metrics=["accuracy"])history = model.fit(X_train, y_train,                    batch_size=BATCH_SIZE, epochs=NB_EPOCH,                    verbose=VERBOSE, validation_split=VALIDATION_SPLIT)score = model.evaluate(X_test, y_test, verbose=VERBOSE)print("Test score:", score[0])print('Test accuracy:', score[1])# 列出全部历史数据print(history.history.keys())# 汇总准确率历史数据plt.plot(history.history['acc'])plt.plot(history.history['val_acc'])plt.title('model accuracy')plt.ylabel('accuracy')plt.xlabel('epoch')plt.legend(['train', 'test'], loc='upper left')plt.show()# 汇总损失函数历史数据plt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.title('model loss')plt.ylabel('loss')plt.xlabel('epoch')plt.legend(['train', 'test'], loc='upper left')plt.show()


经过5个epoch,就获得一个近似99%的准确率,绘制出模型准确率和损失函数的变化图如图。


Test accuracy: 0.9899



05

总结

在此之前,我总结记录了一些机器学习的实战,包括《机器学习应用——电影评论情感分析模型构建》《多分类器集成学习:多数票机制、Bagging、Adaboost实例分析》《基于sklearn库的机器学习模型与调优实践详细步骤》等,感兴趣的伙伴可以查看,偏向实践更加有趣!


这一篇整理了卷积神经网络的详细内容,了解其原理来龙去脉,通过简单入门项目深入浅出。CNN在图像识别分类的应用广泛,在许多深度学习任务中也会用到CNN神经网络。

—版权声明—

仅用于学术分享,版权属于原作者。

若有侵权,请联系微信号:yiyang-sy 删除或修改!


—THE END—
浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报