前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用Tensorflow2.0实现卷积神经网络CNN

利用Tensorflow2.0实现卷积神经网络CNN

作者头像
用户7569543
发布2020-07-20 11:19:42
1.9K0
发布2020-07-20 11:19:42
举报

前面几节课我们给大家介绍的都是全连接神经网络,但全连接神经网络有个明显的缺点,那就是当网络层数较多时(尤其是在图像识别任务中),它每层的参数数量容易变得很大,不好控制。所以本节课老shi准备给大家介绍另外一种非常重要的网络结构——卷积神经网络。卷积神经网络(Convolutional Neural Network, CNN)近几年在深度学习中的应用非常广泛,特别是在图像识别、语音识别以及本文处理方面。可以说,卷积神经网络是深度学习中最重要的神经网络之一,例如图像识别中非常有名的LeNet、AlexNet、 ResNet、VGGNet、InceptionNet等网络结构都是在卷积神经网络基础上得来的。

全连接神经网络 VS 卷积神经网络

全连接神经网络之所以不太适合图像识别任务,主要有以下几个方面的问题:

1.参数数量太多

假设一个输入图片由1000*1000像素组成,那么输入层就有1000*1000=100万节点。假设第一个隐藏层有100个节点,那么仅这一层就有(1000*1000+1)*100=1亿个参数,这个参数量确实非常大!如果我们的网络层数再多一些,那么参数数量就会更多,因此它的扩展性较差。

2.没有利用像素之间的位置信息

对于图像识别任务来说,每个像素和其周围像素的联系是比较紧密的,和离得很远的像素之间的联系可能就很小了。如果一个神经元和上一层所有神经元相连,那么就相当于对于一个像素来说,把图像的所有像素都等同看待,这不符合前面的假设。当我们完成每个连接权重的学习之后,最终可能会发现,有大量的权重,它们的值都是很小的(也就是这些连接其实无关紧要)。努力学习大量并不重要的权重,这样的学习必将是非常低效的。

3.网络层数限制

我们知道网络层数越多其表达能力越强,但是通过梯度下降法来训练深度全连接神经网络很困难的,因为全连接神经网络的梯度很难传递超过3层(梯度会消失)。因此,我们不可能得到一个很深的全连接神经网络,也就限制了它的能力。

那么,卷积神经网络又是怎么解决以上这些问题的呢?主要有四个思路:

1.局部连接

这是最容易想到的,每个神经元不再像全连接网络那样和上一层的所有神经元连接,而是只和一小部分神经元连接,这样参数量就大大减少了。

2.权值共享

每一组连接可以共享同一个权重,而不是每个连接有一个不同的权重,这样也大大减少了很多参数。

3.下采样

卷积神经网络可以通过池化层来进行下采样减少每层的样本数,同样也可以进一步减少参数量,同时还可以提高模型的鲁棒性。

4.充分利用位置信息

卷积核通过不断的卷积操作充分利用每个像素点之间的位置信息,更适用于图像识别任务中。

总之,对于图像识别任务来说,卷积神经网路通过尽可能保留重要参数,去掉大量不重要的参数,来达到更好的学习效果。

什么是卷积神经网络

首先,我们先获得一个感性的认识,以下是卷积神经网络的示意图。

卷积神经网络由若干卷积层(Convolution Layer)、池化层(Pooling Layer)和全连接层(Fully Connected Network)组成。它的常用架构模式为:

INPUT -> [[CONV]*N -> POOL?]*M -> [FC]*K

也就是输入数据INPUT,经过N个卷积层叠加,然后(可选)叠加一个池化层,重复这个结构M次,最后叠加K个全连接层。

注:每个卷积层后不一定需要连接池化层,看实际情况而定。

卷积神经网络各层计算

1、卷积层

我们用一个简单的例子来讲述如何计算卷积,假设有一个5*5的图像,使用3*3的卷积核(filter)进行卷积,最后想得到一个3*3的Feature Map,如下图所示:

为了描述清楚卷积计算过程,我们首先对图像的每个像素进行编号,用X(i,j)表示图像image的第i行第j列元素;对卷积核filter的每个权重进行编号,用W(m,n)表示第m行第n列权重,用Wb表示卷积核的偏置项(上图中每个卷积核filter的偏置项bias都是0);对Feature Map的每个元素进行编号,用a(i,j)表示Feature Map的第i行第j列元素;用f表示激活函数(这个例子选择relu函数作为激活函数)。然后,使用下列公式计算卷积:

例如,对于Feature Map左上角元素来说,其卷积计算方法为:

=relu(1+0+1+0+1+0+0+0+1+0)

=relu(4)

=4

下面的动图显示了整个Feature Map的计算过程:

以上是卷积步幅等于1的情况,当卷积步幅设置为2时,Feature Map就变成了2*2了。这说明Feature Map的大小是和原来图像大小和步幅有关系。它们满足以下关系:

在上面的两个公式中,W2是卷积后Feature Map的宽度,W1是卷积前图像的宽度,F是卷积核filter的宽度,P是原始图像周围填充0的数量(也就是在原始图像周围补几圈0,如果P是1,那么就是补1圈0,以此类推),S是步幅;H2是卷积后Feature Map的高度,H1是卷积前原始图像的高度。

注:卷积神经网络中的卷积和数学中的卷积是有区别的,卷积神经网络中的卷积严格来说应该叫互相关操作,只是通常我们都习惯叫卷积操作而已。

2、池化层

池化层主要的作用是下采样,通过去掉Feature Map中不重要的样本,进一步减少参数数量。池化的方法很多,最常用的是Max Pooling。Max Pooling实际上就是在n*n的样本中取最大值,作为采样后的样本值。下图是2*2卷积核,步长为2的池化操作:

除了Max Pooling之外,常用的还有Mean Pooling(取均值),对于深度为D的Feature Map,各层独立做池化操作,因此池化后的深度仍为D(池化深度不变,样本数减少)。

3、全连接层

全连接神经网络前面已经详细介绍过了,这里不再赘述。

最后,我们一起来看一个卷积神经网络CNN实现人脸分类的实例。有兴趣的同学可以自己动手试一下。ok,本节课到此。下节课给大家介绍深度学习中常用的激活函数,敬请期待!

代码语言:javascript
复制
#coding:utf8
import numpy as np
from sklearn import datasets
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
import  tensorflow.keras as keras
import warnings
warnings.filterwarnings("ignore")

# 导入数据
faces_data = datasets.fetch_olivetti_faces()


# 显示原始图片
i = 0
plt.figure(figsize=(20, 20))
for img in faces_data.images:
    #总共400张图片,每个人10个头像,共40个人
    plt.subplot(20, 20, i+1)
    plt.imshow(img, cmap="gray")
    plt.xticks([])
    plt.yticks([])
    plt.xlabel(faces_data.target[i])
    i = i + 1
plt.show()



X = faces_data.images
y = faces_data.target
# 400张图片,每张图片64x64,灰色图片通道数为1
X = X.reshape(400, 64, 64, 1)  

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)



model = keras.Sequential()
# 第一层卷积,卷积核数为128,卷积核3x3,激活函数使用relu,输入是每张原始图片64x64*1
model.add(keras.layers.Conv2D(128, kernel_size=3, activation='relu', input_shape=(64, 64, 1)))
# 第一池化层
model.add(keras.layers.MaxPool2D((2, 2), strides=2))

# 第二层卷积,卷积核数为64,卷积核3x3,激活函数使用relu
model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu'))
# 第二池化层
model.add(keras.layers.MaxPool2D((2, 2), strides=2))

#把多维数组压缩成一维,里面的操作可以简单理解为reshape,方便后面全连接层使用
model.add(keras.layers.Flatten())
#对应cnn的全连接层,40个人对应40种分类,激活函数使用softmax,进行分类
model.add(keras.layers.Dense(40, activation='softmax'))


model.compile(optimizer='adam',loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 进行训练和预测
model.fit(X_train, y_train, epochs=10)
y_predict = model.predict(X_test)
# 打印实际标签与预测结果
print(y_test[0], np.argmax(y_predict[0]))
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 多赞云数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像识别
腾讯云图像识别基于深度学习等人工智能技术,提供车辆,物体及场景等检测和识别服务, 已上线产品子功能包含车辆识别,商品识别,宠物识别,文件封识别等,更多功能接口敬请期待。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档