27

特征提取、分类网络、深度学习特征的基本概念总结

 4 years ago
source link: https://www.zoucz.com/blog/2020/05/30/63428a20-a22b-11ea-90b5-eb40e9720ed0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

这些年来,参与或了解了不少模式识别技术相关项目的诞生、成长与死亡。项目会死亡,但是知识不会,人的精力是有限的,如果不记录一下,多年后参与者也会变得和路人一样,忘了那些技术是咋实现的,用来干嘛的。所以这里零散的记录一下吧,不成体系,只做备忘索引。

特征

不管人还是计算机,识别图像都是依据图像整体和细节的一些特征。那么计算机如何识别图像呢,有很多特征提取的算法来找出图像的特征。

传统图像特征

是干啥的

传统算法根据图像的像素数据,用设计好的公式来检测图像的特征,包括角点、轮廓、颜色梯度等等。不同算法在检测这些特征的准确性不同,各个流派实验法也各有擅长特特征。现代的、更先进的算法在某些方面或者整体的准确性方面优于更老的算法。

当相同的图像发生一些线性或者非线性的变换时,会对特征提取造成一些干扰,例如缩放、旋转、平移、仿射变换、变形等等。

不同算法应对这些变换的能力也不同,应对能力越强称之鲁棒性越好。一般称尺度不变性、旋转不变性、仿射不变性等。

有哪些

  • Susan算子 边缘和角点特征检测
  • FAST算子 边缘和角点检测,基于Susan改进
  • BRIEF 特征描述子
  • ORB
  • DoG
  • RANSC特征点
  • Harris角点检测
  • SIFT特征

如何选择

如果要用到这些特征检测算法,需要在理解各个算法特点的基础上 ,根据实际业务场景,对各个检测算法做对比试验,最终选择最合适的算法。

检测的结果是什么

一般都能输出特征角点、轮廓的位置坐标;带特征描述的算法还能输出特征描述向量。

怎么用

AR跟踪

有的特征检测算法对线性变换的支持很好,这样对于同一个图像,其位置和姿态发生线性变化时,各个特征点的位置和姿态也会发生一致的线性变化。通过各个特征点的变化,使用姿态求解的算法,可以计算出图片的变换矩阵 —— 描述图片的平移、旋转、缩放特征。Marker based AR跟踪算法就是用这个做的。

图像检索

在一堆图片中检索一张图片, 将所有图片的特征点描述向量提取出来。待检索图用相同的特征提取算法提出来特征,用knn或者faiss等检索算法找出最相近的特征,计算特征匹配数目最多的几个图片,在加上特征点直接的几何关系校验,给出最相似的图片。

深度学习特征

理解

神经网络这块,目前我对分类网络了解的多一点,定位网络只是用过ssd和faster rcnn,没有学习其细节原理,这里先只记一下分类网络吧。

神经网络对输入数据,经过卷积层、激活函数、池化层、全连层,以及中间可能有的dropout、残差模块等等各种骚操作,最后得到一组输出的数据,这个过程称为前向运算;为了把输出结果映射到类别上,一般会在最后一层搞一个全连层,输出与类别数一样维度的向量,然后计算这一层的结果与标注结果的差异(loss),将loss的结果沿前向运算相反的方向一层层传递,每一层都会根据loss结果,向梯度下降最快的方向(求偏导)更新自己的参数,这个过程称为反向传播。

之前看过一些 说人话的CNN文章 ,这里也简单记录一下说人话系列理解吧。

  • 卷积层:用随机初始化的一个卷积核(滤波器),滑动窗口对输入数据做一次卷积(滤波)操作,输出的结果称为feature map
  • 激活函数:激活函数有很多种,引入一些非线性的操作,将feature map的每个元素过一遍激活函数,得到一个新的feature map
  • 池化层:减少数据量,突出重点特征,如将3*3的数据变成1*1,求均值或者取最大值
  • 全连层:将数据输出为一层1*k维度的数据,k可以是任意维度,而这k个维度上每一个点都与输出数据的每一个数据相关,即所谓的”全连接“
  • loss函数:对一通骚操作之后,得出的结果与真实标注结果之间的差距做一个量化的评估值,loss函数有很多种,可以根据场景选择,例如 人脸识别loss函数评估
  • 反向传播:拿着loss函数输出的差距值,反向传递给上一层,并且对上一层各个参数对loss的影响求偏导,找到梯度下降最快的方向更新参数

极简分类网络例子

假如我要实现一个10000个类别的分类网络,大致可以这样:

  1. 输入图:100*100*3
  2. 卷积层:3*3*3卷积核,随机初始化参数,输出100*100*3的feature map
  3. 激活函数:对100*100*3的每个元素用激活函数做处理,还是输出 100*100*3的feature map
  4. 池化层:均值/最大值池化,减少数据量提出突出特征,输出34*34*3的feature map
  5. 全连层:34*34*3*10000维度的参数向量,对上一层输入的每个数据做一次计算,输出1*10000的向量
  6. softmax:对上层1*10000的输出做softmax计算,将向量转换为类别概率分布,输出1*10000维度的概率分布
  7. softmax loss: 假如输入图是第237个类别,则正确的1*10000概率分布向量是[0,0,…1,…0,0,0],与上一步输出的概率分布结果计算交叉熵
  8. 上一层结果反向传播,更新卷积层、全连层参数

训练网络,即是用大量标注样本训练网络中的参数,使其对特征的表达能力达到最优,这个过程叫监督学习。

训练完成得到该网络最优的参数后,将待预测样本走一遍上面前向运算的过程,得到第6步输出来的结果,然后按概率排个序,得到topK,即是置信度最高的K个类别。

说到分类网络,就不得不说大名鼎鼎的ImageNet和resnet残差网络,各种高大上的操作使得现在神经网络在很多场景下的泛化特征的表达能力方面已经超越传统特征了(亲测,牛逼的很)。

细节的详细介绍,各种高大上的网络结构和优化策略理解: CNN 入门讲解专栏阅读顺序以及论文研读视频集合

深度学习特征

说了半天是不是跑题了? 说好的特征呢?

深度学习也是可以表达特征的,不过它能高度抽象对象的特征描述,得到一个对象的特征描述向量,而不是基于图像像素分布特点来描述一个个细节的特征。

那么假如想用上面的分类网络来提取对象的特征,咋搞呢?

假设我们想用一个1*128维度的向量来描述对象特征,那么改一下网络结构:

  1. 输入图:100*100*3
  2. 卷积层:3*3*3卷积核,随机初始化参数,输出100*100*3的feature map
  3. 激活函数:对100*100*3的每个元素用激活函数做处理,还是输出 100*100*3的feature map
  4. 池化层:均值/最大值池化,减少数据量提出突出特征,输出34*34*3的feature map
  5. 全连层:34*34*3*128参数向量维度的,输出1*128维度的向量(即我们要的特征向量)
  6. 全连层:1*128*10000维度的向量,对上一层输入的每个数据做一次计算,输出1*10000的向量
  7. softmax:对上层1*10000的输出做softmax计算,将向量转换为类别概率分布,输出1*10000维度的概率分布
  8. softmax loss: 假如输入图是第237个类别,则正确的1*10000概率分布向量是[0,0,…1,…0,0,0],与上一步输出的概率分布结果计算交叉熵
  9. 上一层结果反向传播,更新卷积层、全连层参数

一般特征向量维度越高,描述性能会越强,不过效果随维度增加会有个极限;而维度越高,训练难度就越大,特征大小也会越大(在工程实现里边往往还需要考虑特征大小问题)

假设已经训练好了10000类的分类网络,又来了50个类别要识别,咋办呢?再训练一个10050类别的网络?可能要哭,数据量大的话,训练一次得好久。

这个时候特征层就派上用场了。如果模型的特征描述能力够好,把新增的50类整一批标注过的数据,标好,提好128维的特征,存起来。有数据过来的时候,也用模型提一个128维的特征,先分类跑一把,然后拿去和之前提好的50类的特征们做knn,找出最大的几个类,就能快速上线了。

后面的过程,至于用分类的结果,还是用knn的结果,就看阈值怎么设置了。等到10050新分类模型训练好,就可以去掉这50类的特征匹配了。

分类从0到1的一般步骤

  1. 确定分类类别(SKU)
  2. 检测&定位方案确定,有的领域已经有比较成熟的网络和模型,如文本检测定位的CTPN,人脸检测定位的mtcnn等;更多的领域的需要自己构造网络或者使用开源的ssd/faster-rcnn训练定位模型。
  3. 大力整语料,通过线上数据收集、爬虫爬取、浏览器插件、寻找开源数据集等手段,弄到大量原始数据
  4. 预处理,对上一步弄到的数据,做比如检测定位分割、聚类、现有模型初筛、外包标注、数据增强等手段,将数据调整到最佳状态
  5. 训练网络
  6. 用独立数据集测试出准确率、召回率等
  7. 模型满足要求后,发布上线

聚类算法

给一组混合起来的向量,按参数把距离相近的分成N类,当拥有了良好的特征提取器,能比较好的描述一个对象的特征时,用聚类算法可以快速的将不同特征类型的对象区分开来。

深度学习项目中需要收集大量语料时,可以用聚类算法预处理,分成多类后再人工接入,或者用后续的算法接入,提高效率。

数据科学家需要了解的5种聚类算法

特征检索

特征相似性评估

机器学习样本特征之间的相似性度量总结

knn k近邻算法

《机器学习实战》学习总结(一)——k近邻算法(kNN)

开源项目faiss

github-faiss

开源项目、应用原理等

mtcnn

一个效果很好的人脸检测定位开源项目

FZ3mAr7.jpg!web

声纹识别

怎么识别声纹呢?

其实经过一通骚操作,识别声纹和识别图像还挺像的。

把声音的时域信息通过傅里叶变换转换为频域信息,频域信息输入分类网络来训练,和训练图像分类是一个道理。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK