Tensorflow笔记:第七讲卷积神经网络本节目标:学会使用CNN实现对手写数字的识别。7.1√全连接NN:每个神经元与前后相邻层的每一个神经元都有连接关系,输入是特征,输出为预测的结果。参数个数:∑(前层×后层+后层)一张分辨率仅仅是28x28的黑白图像,就有近40万个待优化的参数。现实生活中高分辨率的彩色图像,像素点更多,且为红绿蓝三通道信息。待优化的参数过多,容易导致模型过拟合。为避免这种现象,实际应用中一般不会将原始图片直接喂入全连接网络。√在实际应用中,会先对原始图像进行特征提取,把提取到的特征喂给全连接网络,再让全连接网络计算出分类评估值。例:先将此图进行多次特征提取,再把提取后的计算机可读特征喂给全连接网络。√卷积Convolutional卷积是一种有效提取图片特征的方法。一般用一个正方形卷积核,遍历图片上的每一个像素点。图片与卷积核重合区域内相对应的每一个像素值乘卷积核内相对应点的权重,然后求和,再加上偏置后,最后得到输出图片中的一个像素值。例:上面是5x5x1的灰度图片,1表示单通道,5x5表示分辨率,共有5行5列个灰度值。若用一个3x3x1的卷积核对此5x5x1的灰度图片进行卷积,偏置项b=1,则求卷积的计算是:(-1)x1+0x0+1x2+(-1)x5+0x4+1x2+(-1)x3+0x4+1x5+1=1(注意不要忘记加偏置1)。输出图片边长=(输入图片边长–卷积核长+1)/步长,此图为:(5–3+1)/1=3,输出图片是3x3的分辨率,用了1个卷积核,输出深度是1,最后输出的是3x3x1的图片。√全零填充Padding有时会在输入图片周围进行全零填充,这样可以保证输出图片的尺寸和输入图片一致。例:在前面5x5x1的图片周围进行全零填充,可使输出图片仍保持5x5x1的维度。这个全零填充的过程叫做padding。输出数据体的尺寸=(W−F+2P)/S+1W:输入数据体尺寸,F:卷积层中神经元感知域,S:步长,P:零填充的数量。例:输入是7×7,滤波器是3×3,步长为1,填充为0,那么就能得到一个5×5的输出。如果步长为2,输出就是3×3。如果输入量是32x32x3,核是5x5x3,不用全零填充,输出是(32-5+1)/1=28,如果要让输出量保持在32x32x3,可以对该层加一个大小为2的零填充。可以根据需求计算出需要填充几层零。32=(32-5+2P)/1+1,计算出P=2,即需填充2层零。√使用padding和不使用padding的输出维度上一行公式是使用padding的输出图片边长,下一行公式是不使用padding的输出图片边长。公式如果不能整除,需要向上取整数。如果用全零填充,也就是padding=SAME。如果不用全零填充,也就是padding=VALID。√Tensorflow给出的计算卷积的函数函数中要给出四个信息:对输入图片的描述、对卷积核的描述、对卷积核滑动步长的描述以及是否使用padding。1)对输入图片的描述:用batch给出一次喂入多少张图片,每张图片的分辨率大小,比如5行5列,以及这些图片包含几个通道的信息,如果是灰度图则为单通道,参数写1,如果是彩色图则为红绿蓝三通道,参数写3。2)对卷积核的描述:要给出卷积核的行分辨率和列分辨率、通道数以及用了几个卷积核。比如上图描述,表示卷积核行列分辨率分别为3行和3列,且是1通道的,一共有16个这样的卷积核,卷积核的通道数是由输入图片的通道数决定的,卷积核的通道数等于输入图片的通道数,所以卷积核的通道数也是1。一共有16个这样的卷积核,说明卷积操作后输出图片的深度是16,也就是输出为16通道。3)对卷积核滑动步长的描述:上图第二个参数表示横向滑动步长,第三个参数表示纵向滑动步长。第一个1和最后一个1这里固定的。这句表示横向纵向都以1为步长。4)是否使用padding:用的是VALID。注意这里是以字符串的形式给出VALID。√对多通道的图片求卷积多数情况下,输入的图片是RGB三个颜色组成的彩色图,输入的图片包含了红、绿、蓝三层数据,卷积核的深度应该等于输入图片的通道数,所以使用3x3x3的卷积核,最后一个3表示匹配输入图像的3个通道,这样这个卷积核有三层,每层会随机生成9个待优化的参数,一共有27个待优化参数w和一个偏置b。对于彩色图,按层分解开,可以直观表示为上面这张图,三个颜色分量:红色分量、绿色分量和蓝色分量。卷积计算方法和单层卷积核相似,卷积核为了匹配红绿蓝三个颜色,把三层的卷积核套在三层的彩色图片上,重合的27个像素进行对应点的乘加运算,最后的结果再加上偏置项b,求得输出图片中的一个值。这个5x5x3的输入图片加了全零填充,使用3x3x3的卷积核,所有27个点与对应的待优化参数相乘,乘积求和再加上偏置b得到输出图片中的一个值6。针对上面这幅彩色图片,用conv2d函数实现可以表示为:一次输入batch张图片,输入图片的分辨率是5x5,是3通道的,卷积核是3x3x3,一共有16个卷积核,这样输出的深度就是16,核滑动横向步长是1,纵向步长也是1,padding选择same,保证输出是5x5分辨率。由于一共用了16个卷积核,所以输出图片是5x5x16。√池化PoolingTensorflow给出了计算池化的函数。最大池化用tf.nn.max_pool函数,平均池化用tf.nn.avg_pool函数。函数中要给出四个信息,对输入的描述、对池化核的描述、对池化核滑动步长的描述和是否使用padding。1)对输入的描述:给出一次输入batch张图片、行列分辨率、输入通道的个数。2)对池化核的描述:只描述行分辨率和列分辨率,第一个和最后一个参数固定是1。3)对池化核滑动步长的描述:只描述横向滑动步长和纵向滑动步长,第一个和最后一个参数固定是1。4)是否使用padding:padding可以是使用零填充SAME或者不使用零填充VALID。√舍弃Dropout在神经网络训练过程中,为了减少过多参数常使用dropout的方法,将一部分神经元按照一定概率从神经网络中舍弃。这种舍弃是临时性的,仅在训练时舍弃一些神经元;在使用神经网络时,会把所有的神经元恢复到神经网络中。比如上面这张图,在训练时一些神经元不参加神经网络计算了。Dropout可以有效减少过拟合。Tensorflow提供的dropout的函数:用tf.nn.dropout函数。第一个参数链接上一层的输出,第二个参数给出神经元舍弃的概率。在实际应用中,常常在前向传播构建神经网络时使用dropout来减小过拟合加快模型的训练速度。dropout一般会放到全连接网络中。如果在训练参数的过程中,输出=tf.nn.dropout(上层输出,暂时舍弃神经元的概率),这样就有指定概率的神经元被随机置零,置零的神经元不参加当前轮的参数优化。√卷积NN:借助卷积核(kernel)提取特征后,送入全连接网络。卷积神经网络可以认为由两部分组成,一部分是对输入图片进行特征提取,另一部分就是全连接网络,只不过喂入全连接网络的不再是原始图片,而是经过若干次卷积、激活和池化后的特征信息。卷积神经网络从诞生到现在,已经出现了许多经典网络结构,比如Lenet-5、Alenet、VGGNet、GoogleNet和ResNet等。每一种网络结构都是以卷积、激活、池化、全连接这四种操作为基础进行扩展。Lenet-5是最早出现的卷积神经网络,由Lecun团队首先提出,Lenet-5有效解决了手写数字的识别问题。7.2Lenet神经网络是YannLeCun等人在1998年提出的,该神经网络充分考虑图像的相关性。√Lenet神经网络结构为:①输入为32*32*1的图片大小,为单通道的输入;②进行卷积,卷积核大小为5*5*1,个数为6,步长为1,非全零填充模式;③将卷积结果通过非线性激活函数;④进行池化,池化大小为2*2,步长为1,全零填充模式;⑤进行卷积,卷积核大小为5*5*6,个数为16,步长为1,非全零填充模式;⑥将卷积结果通过非线性激活函数;⑦进行池化,池化大小为2*2,步长为1,全零填充模式;⑧全连接层进行10分类。Lenet神经网络的结构图及特征提取过程如下所示:Lenet神经网络结构图Lenet神经网络的输入是32*32*1,经过5*5*1的卷积核,卷积核个数为6个,采用非全零填充方式,步长为1,根据非全零填充计算公式:输出尺寸=(输入尺寸-卷积核尺寸+1)/步长=(32-5+1)/1=28.故经过卷积后输出为28*28*6。经过第一层池化层,池化大小为2*2,全零填充,步长为2,由全零填充计算公式:输出尺寸=输入尺寸/步长=28/2=14,池化层不改变深度,深度仍为6。用同样计算方法,得到第二层池化后的输出为5*5*16。将第二池化层后的输出拉直送入全连接层。√根据Lenet神经网络的结构可得,Lenet神经网络具有如下特点:①卷积(Conv)、池化(ave-pooling)、非线性激活函数(sigmoid)相互交替;②层与层之间稀疏连接,减少计算复杂度。√对Lenet神经网络进行微调,使其适应Mnist数据集:由于Mnist数据集中图片大小为28*28*1的灰度图片,而Lenet神经网络的输入为32*32*1,故需要对Lenet神经网络进行微调。①输入为28*28*1的图片大小,为单通道的输入;②进行卷积,卷积核大小为5*5*1,个数为32,步长为1,全零填充模式;③将卷积结果通过非线性激活函数;④进行池化,池化大小为2*2,步长为2,全零填充模式;⑤进行卷积,卷积核大小为5*5*32,个数为64,步长为1,全零填充模式;⑥将卷积结果通过非线性激活函数;⑦进行池化,池化大小为2*2,步长为2,全零填充模式;⑧全连接层,进行10分类。Lenet进行微调后的结构如下所示:√Lenet神经网络在Mnist数据集上的实现,主要分为三个部分:前向传播过程(mnist_lenet5_forward.py)、反向传播过程(mnist_lenet5_backword.py)、测试过程(mnist_lenet5_test.py)。第一,前向传播过程(mnist_lenet5_forward.py)实现对网络中参数和偏置的初始化、定义卷积结构和池化结构、定义前向传播过程。具体代码如下所示:注释:1)定义前向传播过程中常用到的参数。图片大小即每张图片分辨率为28*28,故IMAGE_SIZE取值为28;Mnist数据集为灰度图,故输入图片通道数NUM_CHANNELS取值为1;第一层卷积核大小为5,卷积核个数为32,故CONV1_SIZE取值为5,CONV1_KERNEL_NUM取值为32;第二层卷积核大小为5,卷积核个数为64,故CONV2_SIZE取值为5,CONV2_KERNEL_NUM为64;全连接层第一层为512个神经元,全连接层第二层为10个神经元,故FC_SIZE取值为512,OUTPUT_NODE取值为10,实现10分类输出。2)把前向传播过程中,常用到的方法定义为函数,方便调用。在mnist_lenet5_forward.py文件中,定义四个常用函数:权重w生成函数、偏置b生成函数、卷积层计算函数、最大池化层计算函数,其中,权重w生成函数和偏置b生成函数与之前的定义相同。√①卷积层计算函数描述如下:tf.nn.conv2d(输入描述[batch,行分辨率,列分辨率,通道数],卷积核描述[行分辨率,列分辨率,通道数,卷积核个数],核滑动步长[1,行步长,列步长,1],填充模式padding)例如:tf.nn.conv2d(x=[100,28,28,1],w=[5,5,1,6],strides=[1,1,1,1],padding='SAME')本例表示卷积输入x为28*28*1,一个batch_size为100,卷积核大小为5*5,卷积核个数为6,垂直方向步长为1,水平方向步长为1,填充方式为全零填充。√②最大池化层计算函数描述如下:tf.nn.max_pool(输入描述[batch,行分辨率,列分辨率,通