FaceNet

宏观理解 我们之前说过的算法都是人脸检测,比如Faster R-CNN和MTCNN。可以在一张图片中找出人脸的位置,但是我们常见的人脸识别系统并不能只依赖于人脸检测,我们还需要一个步骤就是人脸识别。 人脸识别大致有两种,第一种是给出一张人脸来对比是否和另一张一样,第二种是给出一张人脸来判断是否在一个数据库里。这样我们把人脸检测和识别的算法结合在一起就是一个完整的人脸识别系统了,这个流程类似这样: 现在我们就介绍一种可以识别的算法FaceNet。FaceNet的作用在于给出两张照片,它用欧式距离来判断这两张照片的人是不是同一个人。比如下面这个图中,我们规定两张照片的欧式距离小于1.05的判断为同一个人,所以左右都为同一个人但是上下都大于1.05判断为不同的两个人。 其实是一个很简单的过程,先把人脸embedding然后计算两个编码的欧式距离就好,那么这篇论文贡献的就是一个新的loss function来使相同的人脸距离越来越近,不同的越来越远。 (注:那么为什么要用欧式距离而不是用cos距离来做呢?因为如果用cos的话进行N:N的比对需要O^2的复杂度,但是如果用欧式距离的KD-TREE之类的数据结构可以很大的提高效率。)   微观分析 这种新颖的loss叫triplet loss。我们先随机拿出一张照片叫anchor。然后我们再随机从标注好的同一个人的照片中再拿出一个叫positive(可能翻译成正样本?),最后从不是同一个人脸的数据中随机拿一个叫做negative(就叫负样本吧)。然后这三张照片通过embedding之后,交给triplet loss计算出一个损失。整个过程就是这样的。 这个损失在优化完我们当然希望anchor和positive的距离越来越近,anchor和negative的距离越来越远。所以我们的目标就像这张图: 为了更好的应用,我们还可以在这个loss上加上一个超参数α当作margin,就像SVM一样,不仅要找出一个答案,我们还要这个答案变得尽量最好。我们定义一下anchor为A,negative为N, positive为P。所以我们写成 ||F(A) – F(P)|| + α < || F(A) – F(N) || 。F我们可以理解为embedding的函数。这样在训练完可以让我们的算法更加有鲁棒性。 现在我们稍微移项一下就有了我们的loss = ||F(A) – F(P)|| – || F(A) – F(N) ||+ α 在训练过程中,因为每个样本都是由一个三元组组成的,如果我们把数据集中的所有三元组都先找出来再全部来做loss,这样的复杂度异常的高。所以我们选择在每次的一个batch中,寻找有哪些组合是满足||F(A) – F(P)|| + α < || F(A) – F(N) ||的,然后仅仅求出这些的loss进行反向传播。但是还有一个问题就是,为了更加的优化这个过程,即使在一个batch中也能选出很多种三元组,那么优化就落在了怎么选择这些三元组的问题上。我们可以把每个batch的数据平均一下,来保证每个batch中有P个人,每个人有K张图。接下来有两种方法来选择: 全生成:单纯的选择所有满足的三元组,也就是PK(K – 1)(PK – …

MTCNN

宏观理解 参考论文《Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks》 我们已经了解了Faster R-CNN的过程和目的,其主要成就在于加速了人脸检测的速度并且提升了bbox的准确率。2016年诞生的MTCNN做的事情也是类似。下面一张流程图展示了MTCNN的训练过程,最后会得到带有人脸的bounding box以用于人脸检测和人脸上的5个landmarks以用于人脸识别。 从上图我们可以看出整个算法有3个stage,这三个stage是以级联的方式运作的。stage 1,浅层的CNN快速产生候选框;stage 2,通过更复杂的CNN精炼候选框,丢弃大量的重叠框;stage 3,使用更加强大的CNN,实现候选框去留,同时显示五个面部关键点定位。 在MTCNN之前的一个很广泛应用的级联是Viola和Jones提出的级联人脸检测器,利用Harr特征结合AdaBoost去实现高性能的实时训练。但是这种方法有一个很大的缺陷就是因为图片中人脸的姿势、光照或遮挡等原因致使能力直线下降,但是来解决这些问题的一个很好的工具就是深度学习,所以接下来我们来看看MTCNN的原理。 微观分析 我们已经看到了整个网络是由三个stage级联而生的,这是整个MTCNN的三个级联网络的过程图: 我们把这三个级联的网络叫做P-Net, R-Net和O-Net,所代表的含义就是Proposal Net, Re-fine Net和Output Net。 我们首先把原图拿来做图像金字塔resize成不同尺度的图片,然后用一个12*12的sliding window在所有的不同尺度的图片中滑动来截取初始候选框,接下来把这些12*12的候选框送到级联网络的第一个网络P-Net。 P-Net 首先传进去的是一张12*12的图片,可以看出来很小,也就是144个像素。接着做了10个3*3*3的卷积操作,stride可以看出来是1 ,最后得到一个10*10*10的中间量feature map。然后做一个2*2的max pooling操作,stride为2,所以最后得出来5*5*10的feature map。 随后也接着经过另外两个3*3的卷积操作把图像整合成1*1*32的特征向量。 最后在输出层中,我们可以得到3个结果。第一个是分类结果,通过2个1*1*32的卷积得到两个数字,然后把这两个数字送给softmax来做分类得到是人脸的概率和不是人脸的概率。第二个是人脸的位置回归,用4个1*1*32的卷积得到的4个位置信息。第三个是特征点信息,用10个1*1*32的卷积得到5个特征点位置(x,y)所以是10个值。这5个特征点分别是两个眼睛,鼻子和两个嘴角。 我们可以发现之前学过的网络中的全连接层在P-Net中没有用到,其实这种结构叫做全卷积网络,也就是全部都是用的卷积层来实现的。它是有好处的。想想我们之前讲神经网络的时候说过,因为后面有了全连接,所以参数量固定了,所以输入的图片的size也是要固定的。这也是为什么我们之前都需要在神经网络的输入前resize一下原图。但是全卷积网络就可以接受不同大小的图片,没有了后面参数量的局限。 R-Net R-Net就不再是全卷积网络了。它的输入是从P-Net中输出的bbox在原图中裁剪出来的24*24的RGB image。然后经过3个卷积和一个全连接变成一个128维的特征向量。然后照样我们有3个输出,都是用全连接生成2,4,10个对应的值。 O-Net O-Net同理,它的输入是从R-Net中输出的bbox在原图中裁剪出来的48*48的RGB image。然后经过4个卷积和一个全连接变成一个256维的特征向量。然后照样我们有3个输出,都是用全连接生成2,4,10个对应的值。 我们发现在stage的传递中,前面的landmark并没有被后面的网络应用,这是为什么?这是因为在multi-task学习中,我们希望landmark即使在前面没有应用到,也要作为一个约束力告诉前面的网络我们还有一个landmark用来考量,这样在计算损失的时候不至于让bbox回归和分类把landmark带的很偏。 现在我们了解完所有的结构之后,就要看一下优化的损失函数了。 loss functions 我们看到每个net都有3个输出,所以我们对应的也需要3个loss来计算。 对于face classification任务       我们用的就是交叉熵函数。p指的就是对应的yi的概率了。 对于bounding …

RNN

宏观理解 我们在CNN和R-CNN中学到了怎么来处理一张图片,但是我们默认的是图片和图片之间是没有任何联系的,但是递归神经网络(RNN)来处理的无论文字信息还是图像我们都默认为其间是存在关联的,这种关联的体现就是时间的顺序。比如我给你一张清晨的图片让你来预测再过几小时是什么样子,RNN就能知道按顺序的话输出就应该是中午1点半的图片。文字也是一样。曾经在github上见到一种可以自动填充代码的code,它做的就是根据你目前为止的输入,我推断你接下来应该会写些什么。当然还有我们大家应该都听过的技术叫做时间序列分析,股票预测,用的就是每天收盘的信息来预测这只股票未来走势如何。比如著名的RNN家族里的LSTM模型。 我们在计算机视觉的图片识别上机器已经超过了人类的能力,但是在机器翻译上或者说NLP中机器离人类还有一段距离,这段距离就是人们还没能很好的用机器来做到时间顺序的拟合。因为我们说过神经网络处理图片的时候是根据的人体生物学得到的启发,模拟的人类视觉接收图片到处理图片识别图片。但是RNN目前在生物学中没有找到很好的切合点,到目前为止的RNN设计思路是由1995年被证实和图灵机在数学意义上等价来的,所以RNN未来的发展势必有很大空间。 微观分析 我们先来看看RNN长什么样子:          绿色的箭头是我们的输入值,红色的箭头是我们的输出值。RNN很有意思,它有不止一次的输入也可以有不止一次的输出。我们可以把每次的输入对应到股票预测中的每天的收盘价,中间的灰色区域就是RNN网络,这个里面是一个神经网络就像我们以前见过的一样,下标(t-1)就是指的前一天,今天,和明天。中间的蓝色箭头代表神经网络之间的信息传递,既然时间顺序,那么第N天的神经网络就也一定要有第一天的输出结果。 右图中是我们把左边的网络折叠起来,这就说明了整个网络的RNN的共享权重的,在反向传播中也是照样往回传的。下面我们来推公式,假设我们有一个这样的RNN: 跟之前的展开和折叠的图像含义一样。我们假设有了这些参数U, W, V,一个输入值Xt和两个输出值St, Ot。 U, W, V是三个参数矩阵,也就是一开始我们先把输入值Xt和U点乘,然后加上前一个的输出值St-1和W点乘的和,过一个激活函数比如说f: 对于Ot,我们只需要用St点乘V然后过一个激活函数比如说g: 除了我们见过的这种结构的网络,还有很多的衍生品: 这些网络由于输入值和输出值的不同(输出值-to-输出值)可以针对不同的问题进行训练: one-to-one:我们管这种网络叫Vanilla Neural Networks,算是递归神经网络的基础型。 one-to-many:我们可以输入一张图片,然后生成描述这个图片的一句话一个自然段甚至是一篇文章,这叫Image Captioning many-to-one:我们可以输入一段话,输出关于这段话的评价比如说积极的还是消极的,这叫Sentiment Classification many-to-many:我们可以输入中文句子,输出英文的翻译,这叫Machine Translation many-to-many:另一种many-to-many的结构也可以做视频中每帧的分类,比如这一帧包不包含暴力情节,也可以针对一个1小时的视频来过滤无关的帧,精简到10分钟的内容。 我更觉得RNN是一种思想,基于这种思想我们有了很多的模型比如做机器翻译的NMT,比如可以时序分析的LSTM等等。当然还有大量的未被发掘的应用等待着我们。 希望结合代码的同学可以看这里  

Faster R-CNN

宏观理解 我们学完R-CNN后,想想它有什么地方可以改进的?有什么地方是拖累了整个算法的速度?在2015年同一个作者提出了Fast R-CNN算法,它是基于R-CNN在选取候选框时大量的重叠导致同一图片的特征被多次提取而改进的算法。它使用一个叫RoI(regions of interest) pooling层来将抠出来的候选框resize到统一的大小。 在提出Fast R-CNN后,又是同样的作者,在2015年提出来又一个新的改进叫Faster R-CNN 。我们在R-CNN选取候选框的时候用的是selective search,但是它无法在GPU上进行加速,所以为了实现算法的速度更快,作者终于把整个算法都用一个CNN来实现,借助CNN来生成候选框。 论文参考 《Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks》 微观分析 我们先看看faster R-CNN的整个流水线: 对于每一个图片,我们先经过conv layers来提取图片特征,生成一张feature map。然后通过一个叫做Region Proposal Network的网络结构来代替selective search生成候选框。然后把生成的proposal和feature map给到RoI pooling层来得到统一大小的候选框提取特征。最后给一个分类器来分类并且精修bounding box的位置。 再来看一个更加细节的图示: 大家可以对照上面的两个图对应一下每个网络的位置。 我们分成3个部分来学习整个pipeline。 对于蓝色框 对于我们的每个卷积层,作者设置kernel size = 3,padding = 1,stride = 1 。这意味着什么?意味着一个M*N的原图经过卷积后的feature map还是M*N,卷积层并没有改变图片的大小。 对于我们的每个max池化层,作者设置kernel size = 2,padding = 0,stride = …

R-CNN

宏观理解 相关论文见《Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation》by Ross Girshick, Jeff Donahue, Trevor Darrell, Jitendra Malik 学习R-CNN算法之前我们要知道他是干什么的。计算机视觉领域里有一个很重要很基础的分支是物体检测,它做的就是把一张图片的前景和背景区分开,然后给所有的前景进行分类。比如下图中的前景包括car,dog,horse和person。物体检测也就是得到一张如图一样的结果。这也是监督学习的一种,但是在数据集中他们经常是包含这张图片、人工标注的前景bounding box和对应的分类。在传统的机器学习算法中要做到这样的结果分为两步,也就是对应着我们之前说过的HOG + SVM类似,首先是要找到一个函数(HOG)可以输入一张图片输出一些特征,然后再有一个函数(SVM)输入这些特征再输出分类类别label。那么R-CNN则是基于深度学习来完成这个任务的方法。它的全名是Region CNN,我们知道CNN可以帮助我们分类图片,那么Region也就可以帮助我们找到图片中的特征。当然除了R-CNN还有很多比如YOLO, SSD,还有人尽皆知的Fast R-CNN, Faster R-CNN等等。这些以后都会依次介绍。 微观分析 下图是论文中给出的步骤,第二步中的region proposals代表我们要在图片中找到的前景,然后把这些候选框(大概1~2千个)抠出来,交给CNN来特征提取,最后交给分类器SVM分类。 总结一下,我们可以把整个R-CNN算法分成4个步骤: 生成候选框(使用selective search) 对每个候选框用CNN进行特征提取 把提取出来的特征送到分类器(默认SVM)中进行分类 使用回归器对候选框的位置进行修正 我们对以上4个步骤进行逐一讨论。   生成候选框(使用selective search) selective search方法做的事情是把一张图分割成很多很多很细节的小区域,举个例子,假如图片中有五星红旗🇨🇳,那么使用selective search后,不仅仅整个五星红旗会被框出来,连里面的5颗星星也会被框出来。这种手段叫做过分割。我们不妨把分出来的所有小区域存进一个集合R中。下一步则是在集合R中循环所有的区域,把他们两个的相似度存进另外一个集合S中。然后我们在集合S中排序,找到相似度最高的两个区域,我们把这两个区域合并(集合S中也就对应删除掉相应信息),然后放到集合R,形成新的候选框。随后因为有了新的候选框,我们要计算新的候选框和其余子集的相似度,然后重复以上过程每次两两合并最终直到整张图像合并成一个区域为止,这时集合S也就空了。伪代码如下: 那么我们怎么直到两个小区域的相似度呢?我们可以按照以下的顺序进行合并,如果颜色全部类似,那么就往下一步来按纹理合并,以此类推: 通过颜色直方图中颜色相近的 通过梯度直方图中梯度相近的(梯度可以理解为图片的条纹走势类似) 合并之后总面积小 合并之后总面积在bounding boxes中所占比例大 整个这个过程完成之后,我们把所有在集合R中的候选框全部拿来用,这就完成了第一步通过selective search选取候选框。   2. 对每个候选框用CNN进行特征提取 我们拿到了集合R中的候选框后,发现什么玩意都有,而且乱的一逼。这种东西怎么能直接送给CNN呢,我们在CNN中提到过,它的输入都是一定的不能变化。所以在送之前,我们需要对所有的候选框进行resize,那么怎么resize也是有讲究的,论文中提到了两种方式: 各向异性缩放:如图(D)所示,也就是平民玩家的愣resize,啥都不用管,大小弄成一样就好。但是这种方法对CNN的特征提取肯定不好。 各向同性缩放: 先扩充再裁剪:如图(B)所示,vip玩家,先把原图扩展成正方形,然后再裁剪 …

LBP feature

宏观理解 我们处理图片多了,就会发现其实计算机看图片就是通过当前像素点和旁边像素点的差异,就比如之前讲的HOG特征,就是找出像素点之前的梯度变化。万变不离其宗,LBP特征也是根据一个像素点和其他像素点的比较来锁定物体位置。 微观分析 这个理解起来比HOG要简单很多。我们把一个block定义在一个3*3的像素网格内,然后计算中心的像素点与其周围8个像素点的差异,如果大于中心点,标记为1,小于则标记为0。所以大概结果是这样的: 然后我们就得到来LBP编码:11010011 。 除了这样的3*3网格为一个LBP算子,还有圆形的算子,并且大小任意: 但是细心的同学会发现一个问题,我们的LBP编码,不是唯一的啊,这要看你读的起点在哪里,11010011可以,11110100就不可以吗?既然可以的话那不就会产生很大变化? 对的。这确实是LBP特征存在的问题,为了解决这个问题,Maenpaa等人将其进行了拓展,保证了一个像素点仅有唯一的编码。方法实在简单,就是在旋转的过程中我们可以得到8组变换,那么我们就规定好,我们只要这8组二进制编码中最小的那个。。(就是这么随性) 所以像上图一样,无论怎么旋转,最终输出的都是最小的二进制编码。 好了,现在我们把所有的像素点的LBP编码都求出来之后他们又可以组成一个图片,叫做LBP图谱: 原图   —->   LBP图谱 但是我们并不能用图谱来进行分类,我们还是需要转化成直方图的形式。但是问题是,如果我们按照上面的程序做下来我们只能得到一个直方图。这个对于描述一个图片的信息显然是不够的。 那么我们可以把一张图片分成n等份,每一份去做一个直方图出来,最后我们就有n个直方图。 最后我们把直方图归一化并且把所有的直方图进行拼接,就得到了这一张照片的LBP纹理特征向量,最后用它去做分类就好。

HOG features

宏观理解 在计算机视觉里有很多方法去处理图片搞分类和物体检测,比如现如今的CNN, RNN,R-CNN一类,当然在他们被证实更有效果之前,还有很多处理特征的方法,其中一个鼻祖就是HOG。HOG特征的全名叫histogram of oriented gradient。可以从名字看出来他是从图片的梯度入手来做图片物体检测的,在行人检测中获得了极大的成功。 这些传统的物体检测方法一般都有相似的流程: 选取候选窗口 提取候选窗口的图像特征 对特征进行分类 HOG特征的主要思想就是既然我们人类观察一个物体进行物体检测和分类是从物体的轮廓开始的,那么它也可以。那么怎么来通过物体的轮廓来锁定物体呢,那就是物体边缘的颜色呗,一片绿色的草原上插着一朵红色的花,是不是很容易发现?那么怎么看边缘颜色呢?梯度呗。所以HOG在做的正是利用图片的梯度来检测物体的位置,是不是有点像夜间的红外线探测仪,你看到一个颜色深的轮廓你能直觉出可能那是个物体。 背景知识介绍 之前提到了物体检测的第一步就是选取候选窗口,那么这一步怎么做呢?首先能想起来的就是暴力的方法,把截取的窗口的坐标循环一遍。但是显而易见这种方法时间复杂度太大,更别说做成实时的模型了。所以前人提出了一种叫做图像金字塔的方法,如下图。我们把每张图片缩放到不同的几种大小,然后仅仅用一种固定大小的框,像CNN中的kernel一样去扫一遍这个图片,然后把每次扫到的片段进行特征提取和分类。特征提取就是HOG的事情了。 微观分析 用梯度来检测物体就很简单,听起来就不是什么复杂的算法,无非就是提取图片所有像素点梯度,然后把有规则的归在一起,再用分类器进行分类呗。总结一下HOG处理过程: 论文Histograms of Oriented Gradients for Human Detection中的流程1. 对输入的图片进行预处理,比如裁剪或者resize。 2. 对预处理完的图片进行灰度处理 因为HOG特征注意的是边缘特征而不是颜色,可以用opencv库来转化:sample_image = cv2.cvtColor(sample_image,cv2.COLOR_RGB2GRAY) 3. 归一化图片 用Gamma校正法对输入图像进行颜色空间归一化,意义在于去除噪声,降低图片光度造成的影响。所谓的gamma校正就是在原图中开根号即可。 4. 计算出梯度图像 我们怎么得到梯度呢,需要用两个卷积核对原图进行卷积。 通过卷积之后我们可以得到两个梯度,分别是GX和GY: GX = translate(sample_image,1,0) – translate(sample_image,-1,0) GY = translate(sample_image,0,1) – translate(sample_image,0,-1) 然后通过GX,GY计算出幅值delta_G和方向angle得到梯度图: delta_G = np.sqrt(GX ** 2 + GY ** 2) …

Conv Network (2)

Case Study 我们这里主要介绍几种常见常听说的模型,既是对之前讲的概念进行更深的理解,也是在以后我们可以有思路怎么搭建自己的模型更好。这里主要是讲 LeNet-5 AlexNet ZFNet VGGNet googLeNet ResNet 我们在分别讲5个模型之前先看一下他们的丰功伟绩,这些模型都出自ILSVRC竞赛。为了更好的膜拜这些模型,我一定要说人类识别这些图片的错误率在5%左右,可见最后的ResNet已经达到了超过人类的识别能力。 Year Ranking Top 5 error rate LeNet-5 1998 1st 18.2% AlexNet 2012 1st 15.4% ZFNet 2013 1st 14.8% VGGNet 2014 2nd 11.2% googLeNet 2014 1st 6.7% ResNet 2015 1st 3.6% LeNet-5 这是Yann LeCun在1998年ILSVRC构建的卷积网络,名列第一,也是convnet投入重点研究的开端。它的架构如下图所示: 输入一张32*32的图片,经过C1卷积层得到28*28*6的feature map。feature map就是在输入经过卷积后的结果。我们可以推算出来他的kernel用的是5*5*6并且步长为1。然后一个S2下采样的池化层把纬度降到14*14*6,也可以推算出来pooling用的2*2并且步长为2。接着就又是一层卷积C3和一层池化S4。最后连着两层的全连接层把纬度降到120和84,最后用高斯连接输出10个分类概率。 所以总结起来就是CONV-POOL-CONV-POOL-FC-FC-GAUSSIAN AlexNet Alex Krizhevsky, Ilya Sutskever and Geoff Hinton在2012年参加ILSVRC竞赛的冠军模型,其实很像LeNet但是比它更深更大一些,这也是随着硬件的发展的必然趋势。 …

Conv Network (1)

宏观理解 卷积神经网络我们主要用在图片的处理上,它是在神经网络的思想基础上,把神经网络的weight组合成了一层过滤网,把原图一遍遍的过滤来提取出来最主要的特征。现在的图片分类几乎都是在用卷积网络来做,神经网络更多的还是在一些像年龄、价格、所属层级的一些分类和回归问题上。 下图左边就是我们说过的神经网络的架构,右边是卷积神经网络的架构。能看出来还是有很大区别的,但是这种区别在掌握了神经网络之后就很好理解了。 微观分析 卷积网络主要是由几种不同操作的layer组成,他们是convolutional layer(卷积层),pooling layer(池化层)和fully connection layer(全连接层)组成。 下面对这几种layer分别介绍一下。 convolutional layer 卷积层是卷积网络最核心的提取信息的layer,他的作用是在已有的输入后,把和输入具有信息等价的输出传给下一层。可以理解为卷积层做了一个信息的重构。 对输入信息进行卷积操作的是一个叫filter或者kernel的矩阵。我们以后就统一叫kernel。kernel中的值就是这个卷积网络的参数,在反向传播中我们会不断优化这些值,一开始我们可以随机初始化这些值。   第一张图中左边为输入矩阵,比如说rgb色道中的一个,然后中间的就是卷积核kernel,右边为输出。kernel会一步一步的扫一遍输入,每次到达一个位置时计算这两个3*3矩阵的乘积加和,给到输出。所以每次计算后的输出都是一个值。下面是一个动图更好的理解一下kernel是怎么扫的输入矩阵。 在动图中四周的白色边框叫padding,因为我们可以看出来当kernel进行卷积操作的时候,输出会比输入的矩阵小。如果我有一个上百层的卷积网络,那么矩阵会缩小的很快。在第一张图中输入为5*5,经过3*3的kernel后输出就是3*3 。但是在卷积层我们并不想损失任何信息,我们还想得到相同大小的输出。这时候就像动图中的我们可以在原图上pad一圈0,这样长和宽都扩大了2,最后输出的矩阵大小就和我们输入矩阵大小相同了。关于padding其实有也有很多方法,可以pad 0,也可以pad相邻的数字。但是为了让padding更小的对输出产生影响,一般默认都是pad 0 。 那么我们在pad的时候怎么知道要pad几圈呢?有一个公式可以计算出来:padding = (kernel_size – 1)/ 2  。比如第一张图中,kernel_size等于3,那么我们就需要(3 – 1)/ 2 = 1圈的padding。 除了padding算是一个超参数以外,还有步长(stride)。顾名思义,就是kernel在扫描input的时候是每次往右或者下走一步还是更多。比如在下图中,步长stride就不再是1了而是等于2,所以横竖都只能扫描3次,得到3*3的output。 以上介绍的都是二维矩阵,但是我们知道在处理图片的时候都是rgb三个色道来表示一张图。所以我们接下来让input和kernel变得更复杂一点。 上图就是标准的3色道输入size = 7*7*3,然后两个kernel size = 2*3*3*3,输出是一个3*3*2三维矩阵,步长stride = 2 。输入矩阵先用第一个kernel相乘,得到一层output,再和第二个kernel相乘得到第二层output。因为我们可以看出来input的第一层和kernel的第一层相乘,input的第二层和kernel的第二层相乘,input的第三层和kernel的第三层相乘,所以我们在初始化kernel的时候要遵守的就是input和kernel深度相同。 我们有公式可以计算出来output的大小:size = (input_size – kernel_size)/ stride + 1 。例如上图中size = (7 …

Neural network(2)

接着之前的神经网络第一篇。 这篇文章我们来了解一下更多更专业的细节,来帮助我们更好的训练出神经网络。 Data preprocessing 对于神经网络来说,一般的分类回归问题和普通机器学习模型的数据预处理基本相同。但是对于图像特征的处理,就是重点了。 我们知道一个图像分RGB三个色道,每一个像素值都是0-255。那么我们对图像数据的预处理可以做mean subtraction,比如像AlexNet对每个像素值减去整张图的像素值mean;也可以像VGGNet一样减去每个色道的mean。 归一化也是预处理很重要的一步,目的是把所有的特征点都归一到同一个scale里。一般我们有两种方法,第一种是把整个数据集除以它自己的标准差,第二种就是min-max归一化。流程见下图: 左图是我们拿到的raw data,经过减去整个数据集的mean值,我们可以得到原点对称的数据,就是中间的图。最后再经过归一化得到右图。当然如果像图片的输入,就已经是0-255,就不再需要归一化处理了。 PCA和whitening白化也是我们预处理的方法,因为我们拿到的数据大部分都是特征之间相关性很高,所以自带很多冗余信息,这样会加大训练的难度。经过PCA降维之后,我们可以找到一个新的特征矩阵,这个新矩阵满足1. 特征之间独立。2. 新矩阵和原矩阵的方差一样。也就是说,我们在不损失信息的前提下,降低了数据维度,让数据特征之间增强了独立性。PCA不细说了前面有文章讲过。所谓的白化就是在PCA得到的新矩阵上进行归一化处理。这个过程见下图: 在PCA处理后我们根据所选取的top 144个新特征向量组成新的数据集,也就是图3,然后在新的数据集中进行归一化。最终得到的白化结果如图4。 weight / bias 初始化 权重的初始化也对神经网络的性能产生一定影响,如果倒霉初始化的不好,会发现怎么优化都得不到好的结果。 有的教科书中在讲解神经网络的时候用的都是把权重全部初始化成0,首先肯定是不能用0来初始化的,因为一旦所有的weight都设置成一个权重,在反向传播的过程中所有权重的更新值也都会一样,毫无意义。 我们一般会用的初始化有高斯分布随机初始化,还有Xavier初始化(w = np.random.randn(in, out) / np.sqrt(in)),in和out是前一层和下一层的node数量。还有如果你想用ReLU作为激活函数的时候,需要在Xavier初始化中改变一下分母(w = np.random.randn(in, out) / np.sqrt(in/2.0))。 对于bias我们可以初始化为0或者一个很小的数值比如0.01用于ReLU作为激活函数的时候。 Batch Normalization 这是一个近几年才刚发的论文提到的方法。由于我们的反向传播过程中改变weight改变激活函数输出值,我们一开始标准化完的数据集可能会产生偏移,会导致训练越来越慢。Batch Normalization做的就是在神经网络中添加一些层,在这些层中,我们把传过来的神经元强行拉回到高斯分布的状态。 在我们从前一层得到输出之后,输出值会传给下一层做,然后a = g(z)做非线性激活。我们的Batch Normalization就卡在得到了z之后在激活函数运算之前进行。变换方法也很简单,就是把一个输入值标准化到高斯分布一样: 经过这个还不算完,因为强行的标准化,会导致表达能力下降,所以论文作者也提出了一种防止办法,那就是在得到新的x后,对x进行一个转化,这个转化过程叫scale and shift:。所以总结一下,整个Batch Normalization的过程就是先计算mean和variance用来标准化,然后把标准化的x值进行转化: Regularization 正则化 正则化不多说了,为了防止过拟合增大数据variance。用的多的不过L1和L2。 在神经网络中,还有一种防止过拟合的方法叫dropout。简单易懂易实行,就是强行的扔掉一些神经元,强行让神经网络丧失一些信息。一般dropout都是随机drop20%左右的神经元,下图中打叉的神经元就是被drop掉的。 loss function 损失函数 我们之前介绍反向传播的时候一直说求出loss对于一些值的偏导,还没介绍过神经网络的损失函数。 对于分类问题来说,我们知道最后一层经常用的softmax层,所以损失函数就用cross-entropy loss: …