1、卷积过程的理解
假定当前输入图片大小为224x224x3(rgb三通道),输出是32位深度,卷积核尺寸为5x5。
那么我们需要32个卷积核,每一个卷积核的尺寸为5x5x3(最后的3就是原图的rgb位深3),每一个卷积核的每一层(5x5)与原图的每一层(224x224)相乘,然后将得到的三层结果叠加(算术求和),就得到这个点对应的卷积结果了。所有的点卷积完成之后则可以得到一张新的feature map。
对32个卷积核的每一个卷都这样操作,就可以得到32张新的feature map了。
简单来说就是不管输入图像的深度为多少,经过一个卷积核(filter),最后都通过卷积公式变成一个深度为1的特征图。不同的filter可以卷积得到不同的特征,也就是得到不同的feature map。
此部分是小米二面要求写的卷积代码实现过程,可惜自己完成的不好。
def convolution(k, data):
n,m = data.shape
img_new = []
for i in range(n-3):
line = []
for j in range(m-3):
a = data[i:i+3,j:j+3]
line.append(np.sum(np.multiply(k, a)))
img_new.append(line)
return np.array(img_new)
2、卷积核大小1*1的理解
1、增加网络的深度
这个就比较好理解了,1x1 的卷积核虽小,但也是卷积核,加 1 层卷积,网络深度自然会增加。
其实问题往下挖掘,应该是增加网络深度有什么好处?为什么非要用 1x1 来增加深度呢?其它的不可以吗?
其实,这涉及到感受野的问题,我们知道卷积核越大,它生成的 featuremap 上单个节点的感受野就越大,随着网络深度的增加,越靠后的 featuremap 上的节点感受野也越大。因此特征也越来越抽象。
但有的时候,我们想在不增加感受野的情况下,让网络加深,为的就是引入更多的非线性。而 1x1 卷积核,恰巧可以办到。
我们知道,卷积后生成图片的尺寸受卷积核的大小和跨度影响,但如果卷积核是 1x1 ,跨度也是 1,那么生成后的图像大小就并没有变化。
但通常一个卷积过程包括一个激活函数,比如 Sigmoid 和 Relu。所以,在输入不发生尺寸的变化下,却引入了更多的非线性,这将增强神经网络的表达能力。
2、升降维
卷积过程形成的 featuremap 通道数/维数是与卷积核的个数相同的
所以,如果输入图片通道是 3,卷积核的数量是 6 ,那么生成的 feature map 通道就是 6,这就是升维;如果卷积核的数量是 1,那么生成的 feature map 只有 1 个通道,这就是降维度。
值得注意的是,所有尺寸的卷积核都可以达到这样的目的。
那为什么要用 1x1 呢?原因就是数据量的大小,我们知道在训练的时候,卷积核里面的值就是要训练的权重,3x3 的尺寸是 1x1 所需要内存的 9 倍,其它的类似。所以,有时根据实际情况只想单纯的去提升或者降低 feature map 的通道,1x1 无疑是一个值得考虑的选项。
3、二维卷积核与三维卷积核
深度学习网络中常用的卷积神经网络包括一维CNN、二维CNN、三维CNN,相对应的卷积核有一维卷积核、二维卷积核和三维卷积核;卷积核的维度由该数据类型的滑动总维度数确定,数据类型向几个方向滑动则称为几维。
顾名思义,n维卷积核(filters/kernel)对应着n维的数据形式,卷积核的个数对应着最终输出结果的层数。
一维CNN:多用于处理序列类的数据处理
二维CNN:多用于图像类的识别任务
三维CNN:多用于医学影像以及视频数据识别
一般而言,Channel或者说通道数不涉及到卷积核size的变化,因为不同通道计算结果只是同一个卷积核在不同通道内重复计算的过程,并不涉及到卷积核在第三个维度的滑动。
4、patch size的确定
深度学习中,训练时虽然输入的是一整张图片,但是真实的网络input可能会对图片做切割,即选取一整张图片的patch进行训练。
例如在CT图像的学习中,当训练阶段的输入patch尺寸较小(32×32)或较大(即完整图像尺寸为128×128)时,CNN在语义分割任务中表现不佳,因为它们包含的不足或过多的背景信息。虽然小斑块可以帮助区分病变与正常组织,从而将假阴性减少到最小,但网络难以区分伪影和真实病变,结果引入了大量误报。在输入是完整图像切片的另一种极端情况下,包括伪像和损伤在内的小物体很容易被许多卷积和聚集消除,因此引入的假阳性很少,但有更多的假阴性。与此同时,CNN忽略了许多真阳性,使检测率下降。所以中等大小(64×64和96×96)的patch能够实现假阳性和假阴性数量之间的权衡,因此整体上的网络性能达到最优。
5、Warp 与 Crop
Warp与Crop均是深度学习中常用的数据处理trick,个人理解是crop裁剪结果一般是正方形,warp的裁剪结果则是矩阵,需要经过resize操作后得到正方形。
右图是 SPP-net,由MSRA何恺明等人提出的,其主要思想是去掉了原始图像上的crop/warp等操作,替换为在卷积特征上的空间金字塔池化层(Spatial Pyramid Pooling,SPP)。CNN的全连接层要求输入图片是大小一致的,而实际中的输入图片往往大小不一,如果直接缩放到同一尺寸,很可能有的物体会充满整个图片,而有的物体可能只能占到图片的一角。
传统的解决方案是进行不同位置的裁剪,但是这些裁剪技术都可能会导致一些问题出现,crop会导致物体不全,warp导致物体被拉伸后形变严重,SPP就是为了解决这种问题的。SPP对整图提取固定维度的特征,再把图片均分成4份,每份提取相同维度的特征,再把图片均分为16份,以此类推。达到目的是无论输入图片的大小,提取的特征维度相同,这样就可以统一送至全连接层了。SPP思想在后来的R-CNN模型中也被广泛用到。
![](https://i-blog.csdnimg.cn/blog_migrate/5758b6d60917bde0498c52bedab427c8.png)
在光流中,warp有新的概念,指的是将某一张reference图片分根据光流扭正到某一个新的时刻。
6、Epoch/Iteration/Batch
非常常见的概念,但是在调试SOF-VSR代码的过程中发现自己对于这些基本概念掌握的不牢靠,万丈高楼起于平地!
![](https://i-blog.csdnimg.cn/blog_migrate/b05e2ed615ec661d7cc42bba8dcea0c5.png)
这个就是吃了SOF-VSR的苦,如果batch size设定为16,iteration设置为1000,那么trainset size应该设置为16*1000。样本size在Pytorch中是由dataloader决定的,在函数中是可以进行定义的。一般而言在__init__ 中进行定义,在__getitem__ 中进行训练数据的生成与收集。
而实际上梯度下降的几种方式本质区别就是batch size不同,Mini-Batch中最后一项+1是因为无法整除,如果可以整除则可以不需要执行+1的操作。
![](https://i-blog.csdnimg.cn/blog_migrate/20f53ed1b1e8604d7f51946cce2b8f09.png)
适当的增加Batch_Size的优点:
1.通过并行化提高内存利用率。
2.单次epoch的迭代次数减少,提高运行速度。(单次epoch=(全部训练样本/batchsize)/iteration=1)
3.适当的增加Batch_Size,梯度下降方向准确度增加,训练震动的幅度减小。
其中第三项也是SOF-VSR的作者所说的 ‘视频超分训练确实不像单帧SR一样平稳,loss在训练过程有一些抖动,可以试着把平滑窗加大一点’ ;适当加大batch-size可以稳定梯度下降的方向。
详细的解释:
(1)batchsize:一次Forword运算以及BP运算中所需要的训练样本数目,其实深度学习每一次参数的更新所需要损失函数并不是由一个{data:label}获得的,而是由一组数据加权得到的,这一组数据的数量就是[batch size]。当然batch size越大,所需的内存就越大,要量力而行。
(2)iteration:每一次迭代都是一次权重更新,每一次权重更新需要batch size个数据进行Forward运算得到损失函数,再BP算法更新参数。
(3)one epoch:所有的训练样本完成一次Forword运算以及一次BP运算
最后可以得到一个公式one epoch 所需要的 numbers of iterations = 训练样本的数量/batch size
举个例子,训练集有1000个样本,batchsize=10,那么训练完整个样本集需要:100次iteration,1次epoch。
7、全连接层(fully connected layers,FC)
卷积神经网络通过卷积和池化操作来学习图像在各个层次上的特征,这符合我们理解图像的常识。人在认知图像时是分层抽象的,首先理解的是颜色和亮度,然后是边缘、角点、直线等局部细节特征,接下来是纹理、几何形状等更复杂的信息和结构,最后形成整个物体的概念。
典型的卷积神经网络通常由以下三种层结构共同组成:
卷积层(Convolution)、下采样池化层(Pooling)、全连接层(Fully connected layer),其中对于全连接层的掌握不是非常牢固,本条对全连接层进行进一步阐述。
以VGG-16举例:对224x224x3的输入,最后一层卷积可得输出为7x7x512,如后层是一层含4096个神经元的FC,则可用卷积核为7x7x512x4096的全局卷积来实现这一全连接运算过程。每一次全连接的过程类似于把特征representation整合到一起,输出为一个值。
连接层实际就是卷积核大小为上层特征大小的卷积运算,卷积后的结果为一个节点,就对应全连接层的一个点。如果将这个全连接层转化为卷积层:
1.共有4096组滤波器
2.每组滤波器含有512个卷积核
3.每个卷积核的大小为7×7
4.则输出为1×1×4096
若后面再连接一个1×1×4096全连接层。则其对应的转换后的卷积层的参数为:
1.共有4096组滤波器
2.每组滤波器含有4096个卷积核
3.每个卷积核的大小为1×1
4.输出为1X1X4096
相当于就是将特征组合起来进行4096个分类分数的计算,得分最高的就是划到的正确的类别。
一句话总结:全连接层(fully connected layers,FC)在整个卷积神经网络中起到“分类器”的作用。如果说卷积层、池化层和激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。
8、add与concat操作之间的区别
之前不太关注这方面工作,但是发现这块的操作自己不太了解,因此对其进行重点关注。
在网络结构的设计上,经常说DenseNet和Inception中更多采用的是concatenate操作,而ResNet更多采用的add操作(虽然做了笔记,但是没什么印象;果然知识常看常新)。concatenate操作是网络结构设计中很重要的一种操作,经常用于将特征联合,多个卷积特征提取框架提取的特征融合或者是将输出层的信息进行融合,而add层更像是信息之间的算术叠加。
Resnet是做值的叠加,通道数是不变的;DenseNet是做通道的合并,通道数有叠加。常规的理解是:add是描述图像的特征下的信息量增多,但是描述图像的维度本身并没有增加,add周再进行下一步卷积操作,相当于加了一个先验。而concatenate是通道数的合并,也就是说描述图像本身的特征数量增加,而每一特征下的信息是没有增加。对于两路输入来说,如果是通道数相同且后面带卷积的话,add等价于concat之后对应通道共享同一个卷积核。
通过看keras的源码,发现add操作:
def _merge_function(self, inputs):
output = inputs[0]
for i in range(1, len(inputs)):
output += inputs[i]
return output
9、图像的高频成分与低频成分
低频分量(低频信号)代表着图像中亮度或者灰度值变化缓慢的区域,也就是图像中大片平坦的区域,描述了图像的主要部分。高频分量(高频信号)对应着图像变化剧烈的部分,也就是图像的边缘(轮廓)、噪声以及细节部分。
图像频率的物理意义:图像可以看做是一个定义为二维平面上的信号,该信号的幅值对应于像素的灰度(对于彩色图像则是RGB三个分量),如果我们仅仅考虑图像上某一行像素,则可以将之视为一个定义在一维空间上信号,这个信号在形式上与传统的信号处理领域的时变信号是相似的。不过是一个是定义在空间域上的,而另一个是定义在时间域上的。所以图像的频率又称为空间频率,它反映了图像的像素灰度在空间中变化的情况。例如,一面墙壁的图像,由于灰度值分布平坦,其低频成分就较强,而高频成分较弱;而对于国际象棋棋盘或者沟壑纵横的卫星图片这类具有快速空间变化的图像来说,其高频成分会相对较强,低频则较弱(注意,是相对而言)。
10、网络channel数的意义
在一定的程度上,网络越深越宽,性能越好。宽度,即通道(channel)的数量。注意我们这里说的和宽度学习一类的模型没有关系,而是特指深度卷积神经网络的宽度。
网络更深带来的一个非常大的好处,就是逐层的抽象,不断精炼提取知识。比如在一个网络中,第一层学习到了边缘,第二层学习到了简单的形状,第三层开始学习到了目标的形状,更深的网络层能学习到更加复杂的表达;而宽度就起到了另外一个作用,那就是让每一层学习到更加丰富的特征,比如不同方向,不同频率的纹理特征。
太窄的网络,每一层能捕获的模式有限,此时网络再深都不可能提取到足够的信息往下层传递。但是从另一个角度说就算一个网络越宽越好,我们也希望效率越高越好,因为宽度带来的计算量是成平方数增长的。我们知道对于一个模型来说,浅层的特征非常重要,因此网络浅层的宽度是一个非常敏感的系数,那么发展了这么久,那些经典的网络第一个卷积层的宽度都是多少呢?
关于网络深度的相关理解来自于最近做语义信息添加的实践过程中,将添加语义信息的网络与原图进行concat之后,进行了24到3的卷积,这样的卷积可能会丢失较多的信息;整个网络结构的设计不是特别合理,细节值得商榷。
同样在贝壳面试中提到的densenet就属于此类情形下宽度变形,与resnet以深度求性能的网络特点形成鲜明反差。
11、网络的非线性
什么是网络的非线性?为什么激活函数可以提升网络的非线性?
这个问题确实很简单,只是有的时候理解不够透彻。
什么是线性,y=kx+b,就是线性;所以一句话,k值可变非固定值就是引入了非线性。