一、前期准备(环境配置)
(1)在自己的电脑上配置了深度学习cpu版的框架
(2)在连接的服务器上配置了深度学习gpu版的框架
(3)中间遇到了许多问题,配置方法及问题的解决见另三篇博文
https://editor.csdn.net/md/?articleId=114679859
https://editor.csdn.net/md/?articleId=114850424
https://editor.csdn.net/md/?articleId=115034747
- 另附:
%matplotlib inline
是在jupyter和Ipyter里使用的,spyder和pycharm里不用,应该注释掉,否则报错 - cv2的正确安装命令应该是这样的:
pip install opencv-python
二、对卷积神经网络(CNN)基础的学习
- 根据师兄们发的链接、视频、答疑还有自己网络搜索大致掌握,思路历程为先对各部分的概念和作用有一个整体把握,在脑海中形成一个卷积神经网络的模型,然后再逐步对各部分进行深入了解,在学习过程中遇到不清楚的专业术语和数学公式等另外拓展加深理解。
(一)整体结构
-
数据输入层:主要对源数据做基本的数据处理,如去均值、归一化、PCA
-
卷积层:通过卷积计算将样本数据进行降维采样,以获取具有空间关系特征的数据
-
激活层:激活层对数据进行非线性变换处理,目的是对数据维度进行扭曲来获得更多连续的概率密度空间。在CNN中,激活层一般采用的激活函数是ReLU,它具有收敛快、求梯度简单等特点
-
池化层(下采样):池化层加载连续的卷积层中间,用于压缩数据的维度以减少过拟合
-
全连接层:全连接层在所有的神经网络层级之间都有权重连接,最终连接到输出层
-
(全连接层之前的层是提取特征,全连接层的作用是分类)
-
稀疏交互:指在深度神经网络中,处于深层次的单元可能与绝大部分输入是间接交互的。
-
参数共享:指在一个模型的多个函数中使用的参数。
-
等变表示:指当一个函数输入改变时,如果其输出也以同样的方式改变,那么这个函数就具备等变表示性。
-
softmax层
从这个图上可以看出来,softmax层只是对神经网络的输出结果进行了一次换算,将输出结果用概率的形式表现出来
- 假设一个5分类问题,然后一个样本I的标签y=[0,0,0,1,0],也就是说样本的真实标签是4,假设模型预测的结果概率(softmax的输出)p=[0.1,0.05,0.05,0.7,0.1],可以看出这个预测是对的,那么对应的损失L=-log(0.7),也就是当样本经过网络参数产生这样的预测p时,它的损失是-log(0.7)
(二)卷积
-
当输入为多维图像(或者多通道特征图)时,若图中输入图像尺寸为6×6,通道数为3;卷积核有2个,每个尺寸为3×3,通道数为3(与输入图像通道数一致),卷积时,是以滑动窗口的形式,从左至右,从上至下,3个通道的对应位置相乘求和,输出结果为2张4×4的特征图。
-
一般地,当输入为m×n×c时,每个卷积核为k×k×c,即每个卷积核的通道数应与输入的通道数相同(因为多通道需同时卷积),输出的特征图数量与卷积核数量一致
-
卷积过程实质上就是两个矩阵做乘法,在卷积过程后,原始输入矩阵会有一定程度的缩小,比如自定义卷积核大小为3*3,步长为1时,矩阵长宽会缩小2,所以在一些应用场合下,为了保持输入矩阵的大小,我们在卷积操作前需要对数据进行扩充,常见的扩充方法为0填充方式。
卷积核的选择
- 在当今深度网络的发展趋势中,提升网络的宽度和深度已经是常规操作,能够解决过拟合的同时带来了大量参数的问题,所以减少计算参数也是必要的。在很多网络中,都使用了3个3x3卷积核来代替7x7卷积核,使用了2个3x3卷积核来代替5x5卷积核
- 这样做的主要目的是:(1)保证具有相同感知野的条件下,提升了网络的深度,在一定程度上提升了神经网络的效果 (2)减少计算参数量;【对于两个3x3卷积核,所用的参数总量为2 x (3x3) x channels, 对于5x5卷积核为 5x5 x channels, 因此可以显著地减少参数的数量,可以减少大约30%的参数数量。】
(三)池化
- 池化层的大小一般为2*2,步长为1
- pooling池化的作用体现在降采样:保留显著特征、降低特征维度,增大kernel的感受野。池化层可对提取到的特征信息进行降维,一方面使特征图变小,简化网络计算复杂度并在一定程度上避免过拟合的出现;一方面进行特征压缩,提取主要特征
- 池化中最大池化(Max pooling)”是最为常见的,还有平均池化、全局平均池化、全局最大池化、重叠池化、空金字塔池化
- tf.nn.max_pool(value, ksize, strides, padding, name=None)
- torch.nn.functional.avg_pool2d(input, kernel_size, stride=None,
padding=0, ceil_mode=False, count_include_pad=True) -
- padding:和卷积类似,可以取’VALID’ 或者’SAME’
SAME:是填充,填充大小: p = (f-1)/2
VALID:是不填充,直接计算输出
- padding:和卷积类似,可以取’VALID’ 或者’SAME’
(四)全连接层(前向计算、反向传播)
- 全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。由于其全相连的特性,一般全连接层的参数也是最多的
- 连接层实际就是卷积核大小为上层特征大小的卷积运算,卷积后的结果为一个节点,就对应全连接层的一个点。
- 假设最后一个卷积层的输出为7×7×512,连接此卷积层的全连接层为1×1×4096。
(五)激活函数
- 神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数
- 缺点:
(1)在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大
(2)Sigmoid 的 output 不是0均值(即zero-centered)
(3)其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
tanh函数
解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在
- Relu函数是一个线性函数,它对负数取0,正数则为y=x(即输入等于输出)
- 优点:解决了梯度消失问题 (在正区间);计算速度非常快,只需要判断输入是否大于0;收敛速度远快于sigmoid和tanh
- 缺点:(1)ReLU的输出不是zero-centered
(2)Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新
relu的变体
ReLU可以被扩展以包括高斯噪声(Gaussian noise): 𝑓(𝑥)=max(0,𝑥+𝑌), 𝑌∼𝑁(0,𝜎(𝑥)) f(x)=max(0,x+Y),Y∼N(0,σ(x))
- 偏置向量的作用:由于经过Relu函数激活后的数据0值一下都变成0,而这部分数据难免有一些我们需要的数据被强制取消,所以为了尽可能的降低损失,我们就在激活层的前面,卷积层的后面加上一个偏置向量,对数据进行一次简单的线性加法,使得数据的值产生一个横向的偏移,避免被激活函数过滤掉更多的信息。
前向传播
前向传播过程其实就是将输入或上层输出左乘以一个W,然后加上一个b,最后使用合适的sigma函数进行激活的过程,结果便是下层的输入或是最终的输出,多层网络就不断重复这个过程。CNN中的parameters分为两种:W和b,注意这里W表示一个矩阵,也因此它相比b,既含有更多的信息,同时也是parameters的主要部分。
梯度
- 梯度:梯度是一个向量求导的导数,f的梯度是包含所有偏导数的向量。向量的导数还是一个向量,所以梯度既是导数又是向量。
- 梯度的方向:与这个函数在该点增长最快的方向一致。
- 梯度的大小:|梯度|=max(方向导数)
- 梯度下降法作用:求损失函数(loss function)最小值
- 沿着下坡走,找到局部最小值,下坡方向就是梯度反方向,最小值就是loss function
- 神经网络在进行方向误差传播时,各个层都要乘以激活函数的一阶导数,梯度每传递一层就会衰减一层,网络层数较多时,梯度G就会不停衰减直到消失