目录
2. 深度学习在什么时候需要动用调参技巧,以及如何进行调参呢?
首先推荐一个很不错的学习网站:床长人工智能教程
样本不平衡
1. 什么是样本不平衡问题?
所谓的类别不平衡问题指的是数据集中各个类别的样本数量极不均衡。以二分类问题为例,假设正类的样本数量远大于负类的样本数量,通常情况下把样本类别比例超过4:1(也有说3:1)的数据就可以称为不平衡数据。
样本不平衡实际上是一种非常常见的现象。比如:在欺诈交易检测,欺诈交易的订单应该是占总交易数量极少部分;工厂中产品质量检测问题,合格产品的数量应该是远大于不合格产品的;信用卡的征信问题中往往就是正样本居多。
2. 样本不平衡会对我们模型的训练带来哪些影响呢?
简单来讲,样本不平衡会使得我们的分类模型存在很严重的偏向性,但是从一些常用的指标上又无法看出来。举一个极端一点的例子,如果正负样本比例为100:1,那岂不是把全部样本都判定为正样本就有99%+的分类准确率了。从测试结果上来看,就表现为有太多的False Positive。
在来看一个“恐怖”的例子,直观的感受一下样本不平衡问题:
你根据1000个正样本和1000个负样本正确训练出了一个准确率90%召回率90%的分类器,且通过实验验证没有欠采样过采样的问题哦~完美的样本,完美的模型,破费,你心里暗自得意。然后模型上线,正式预测每天的未知样本~。
开始一切都很美好,准确率召回率都很好。直到有一天,数据发生了一点变化,还是原来的数据类型和特征,只是每天新数据中正负样本变成了100个正样本,10000个负样本。注意,先前准确率90%的另一种表达是负样本有10%的概率被误检为正样本。好了,模型不变,现在误检的负样本数是10000*0.1=1000个,正样本被检出100*0.9(召回)=90个,好了,这个时候召回率不变仍为90%,但是新的准确率=90/(1000+90)=8.26% 。震惊吗!?恐怖吗!?
结论: 同一个模型仅仅是改变了验证集的正负样本比例,模型已经从可用退化成不可用了!!样本不平衡问题可怕就可怕在这,往往你的模型参数,训练,数据,特征都是对的!能做的都做了,但你的准确率就是上不去!!绝望吧。。。。。。
3. 在机器学习中解决样本不平衡问题有哪些通用的解决策略?
在机器学习中,处理样本不平衡问题,主要有2中策略:从数据角度和从算法层面。
从数据角度出发,通常的方法包括了:
扩大数据集
当遇到类别不均衡问题时,首先应该想到,是否可能再增加数据(一定要有小类样本数据),更多的数据往往战胜更好的算法。因为机器学习是使用现有的数据多整个数据的分布进行估计,因此更多的数据往往能够得到更多的分布信息,以及更好分布估计。即使再增加小类样本数据时,又增加了大类样本数据,也可以使用放弃一部分大类数据(即对大类数据进行欠采样)来解决。
数据集重采样
可以使用一些策略该减轻数据的不平衡程度。该策略便是采样(sampling),主要有两种采样方法来降低数据的不平衡性。
对小类的数据样本进行采样来增加小类的数据样本个数,即过采样(over-sampling ,采样的个数大于该类样本的个数)。
对大类的数据样本进行采样来减少该类数据样本的个数,即欠采样(under-sampling,采样的次数少于该类样本的个素)。
考虑对大类下的样本(超过1万、十万甚至更多)进行欠采样,即删除部分样本;
考虑对小类下的样本(不足1为甚至更少)进行过采样,即添加部分样本的副本;
考虑尝试随机采样与非随机采样两种采样方法;
考虑对各类别尝试不同的采样比例,比一定是1:1,有时候1:1反而不好,因为与现实情况相差甚远;
考虑同时使用过采样与欠采样。
人工产生数据样本
一种简单的人工样本数据产生的方法便是,对该类下的所有样本每个属性特征的取值空间中随机选取一个组成新的样本,即属性值随机采样。你可以使用基于经验对属性值进行随机采样而构造新的人工样本,或者使用类似朴素贝叶斯方法假设各属性之间互相独立进行采样,这样便可得到更多的数据,但是无法保证属性之前的线性关系(如果本身是存在的)。
有一个系统的构造人工数据样本的方法SMOTE(Synthetic Minority Over-sampling Technique)。SMOTE是一种过采样算法,它构造新的小类样本而不是产生小类中已有的样本的副本,即该算法构造的数据是新样本,原数据集中不存在的。该基于距离度量选择小类别下两个或者更多的相似样本,然后选择其中一个样本,并随机选择一定数量的邻居样本对选择的那个样本的一个属性增加噪声,每次处理一个属性。这样就构造了更多的新生数据。具体可以参见原始论文。 这里有SMOTE算法的多个不同语言的实现版本:
Python: UnbalancedDataset模块提供了SMOTE算法的多种不同实现版本,以及多种重采样算法。
R: DMwR package。
Weka: SMOTE supervised filter。
基于异常检测的方式
我们可以从不同于分类的角度去解决数据不均衡性问题,我们可以把那些小类的样本作为异常点(outliers),因此该问题便转化为异常点检测(anomaly detection)与变化趋势检测问题(change detection)。
异常点检测即是对那些罕见事件进行识别。如通过机器的部件的振动识别机器故障,又如通过系统调用序列识别恶意程序。这些事件相对于正常情况是很少见的。
变化趋势检测类似于异常点检测,不同在于其通过检测不寻常的变化趋势来识别。如通过观察用户模式或银行交易来检测用户行为的不寻常改变。
将小类样本作为异常点这种思维的转变,可以帮助考虑新的方法去分离或分类样本。这两种方法从不同的角度去思考,让你尝试新的方法去解决问题。
从算法角度出发,通常的方法包括了:
尝试不同的分类算法
强烈建议不要对待每一个分类都使用自己喜欢而熟悉的分类算法。应该使用不同的算法对其进行比较,因为不同的算法使用于不同的任务与数据。具体可以参见“Why you should be Spot-Checking Algorithms on your Machine Learning Problems”。
决策树往往在类别不均衡数据上表现不错。它使用基于类变量的划分规则去创建分类树,因此可以强制地将不同类别的样本分开。目前流行的决策树算法有:C4.5、C5.0、CART和Random Forest等。
对小类错分进行加权惩罚
对分类器的小类样本数据增加权值,降低大类样本的权值(这种方法其实是产生了新的数据分布,即产生了新的数据集,译者注),从而使得分类器将重点集中在小类样本身上。一个具体做法就是,在训练分类器时,若分类器将小类样本分错时额外增加分类器一个小类样本分错代价,这个额外的代价可以使得分类器更加“关心”小类样本。如penalized-SVM和penalized-LDA算法。
对小样本进行过采样(例如含L倍的重复数据),其实在计算小样本错分cost functions时会累加L倍的惩罚分数。
从重构分类器的角度出发
仔细对你的问题进行分析与挖掘,是否可以将你的问题划分成多个更小的问题,而这些小问题更容易解决。你可以从这篇文章In classification, how do you handle an unbalanced training set?中得到灵感。例如:
将你的大类压缩成小类;
使用One Class分类器(将小类作为异常点);
使用集成方式,训练多个分类器,然后联合这些分类器进行分类;
将二分类问题改成多分类问题
4. 在深度学习中,有哪些解决样本不平衡的方法?
深度学习同样属于机器学习中的一种典型方法,所以在机器学习中适用的方法在深度学习中同样适用。比如说:扩大数据集、类别均衡采样、人工产生数据样本,添加少类别样本的来loss惩罚项等。
对于数据的方法,这里我们重点介绍:类别均衡采样
把样本按类别分组,每个类别生成一个样本列表,训练过程中先随机选择1个或几个类别,然后从各个类别所对应的样本列表里选择随机样本。这样可以保证每个类别参与训练的机会比较均等。
上述方法需要对于样本类别较多任务首先定义与类别相等数量的列表,对于海量类别任务如ImageNet数据集等此举极其繁琐。海康威视研究院提出类别重组的平衡方法。
类别重组法只需要原始图像列表即可完成同样的均匀采样任务,步骤如下:
1. 首先按照类别顺序对原始样本进行排序,之后计算每个类别的样本数目,并记录样本最多那个类的样本数目。之后,根据这个最多样本数对每类样本产生一个随机排列的列表, 然后用此列表中的随机数对各自类别的样本数取余,得到对应的索引值。接着,根据索引从该类的图像中提取图像,生成该类的图像随机列表。之后将所有类的随机列表连在一起随机打乱次序,即可得到最终的图像列表,可以发现最终列表中每类样本数目均等。根据此列表训练模型,在训练时列表遍历完毕,则重头再做一遍上述操作即可进行第二轮训练,如此往复。 类别重组法的优点在于,只需要原始图像列表,且所有操作均在内存中在线完成,易于实现。
从图像和文本数据的角度出发,我们来看一下有哪些方法?
例如:对于图像数据,解决样本不平衡问题,在深度学习中会用到的方法包括了:类别均衡采样(上已经描述),可以用来解决分类问题。
另外,在笔者看来还值得介绍的方法包括了:OHEM和focal loss。
OHEM
OHEM(online hard example miniing)算法的核心思想是根据输入样本的损失进行筛选,筛选出hard example,表示对分类和检测影响较大的样本,然后将筛选得到的这些样本应用在随机梯度下降中训练。在实际操作中是将原来的一个ROI Network扩充为两个ROI Network,这两个ROI Network共享参数。其中前面一个ROI Network只有前向操作,主要用于计算损失;后面一个ROI Network包括前向和后向操作,以hard example作为输入,计算损失并回传梯度。作者将该算法应用在Fast RCNN中,网络结构还是采用VGG16和VGG_CNN_M_1024,数据集主要采用VOC2007,VOC2012和COCO数据集。
算法优点:1、对于数据的类别不平衡问题不需要采用设置正负样本比例的方式来解决,这种在线选择方式针对性更强。2、随着数据集的增大,算法的提升更加明显(作者是通过在COCO数据集上做实验和VOC数据集做对比,因为前者的数据集更大,而且提升更明显,所以有这个结论)。
算法的测试结果:在pascal VOC2007上的mAP为78.9%,在pascal VOC2012上的mAP为76.3%。注意,这些结果的得到包含了一些小tricks,比如multi-scale test(测试时候采用多尺度输入),bounding box的不断迭代回归。
代码的github地址:https://github.com/abhi2610/ohem
Focal Loss
Focal loss主要是为了解决one-stage目标检测中正负样本比例严重失衡的问题。主旨是:ssd按照ohem选出了loss较大的,但忽略了那些loss较小的easy的负样本,虽然这些easy负样本loss很小,但数量多,加起来的loss较大,对最终loss有一定贡献。作者想把这些loss较小的也融入到loss计算中。但如果直接计算所有的loss,loss会被那些easy的负样本主导,因为数量太多,加起来的loss就大了。也就是说,作者是想融入一些easy example,希望他们能有助于训练,但又不希望他们主导loss。这个时候就用了公式进行衰减那些easy example,让他们对loss做贡献,但又不至于主导loss,并且通过balanced crossentropy平衡类别。
OHEM是只取3:1的负样本去计算loss,之外的负样本权重置零,而focal loss取了所有负样本,根据难度给了不同的权重。
focal loss相比OHEM的提升点在于,3:1的比例比较粗暴,那些有些难度的负样本可能游离于3:1之外。之前实验中曾经调整过OHEM这个比例,发现是有好处的,现在可以试试focal loss了。
对于文本数据而言,怎样解决样本不平衡问题?
这里推荐阅读知乎相关问题:严重数据倾斜文本分类,比如正反比1:20~100,适合什么model,查准一般要做到多少可以上线?
比如新闻的广告色情低俗识别,这些小类别在实际分布中一定是占比极小1:20甚至不到百分之一。传统的词表权重组合规则,只能预防一小部分(召回会非常低,但是准确率不会特别低)。而模型如果训练时候用1:1配平(个人觉得不能超过1:3,也做过大量实验),即使使用了加权惩罚,或者类似smote或者组合的上下采样方法,模型在1:1测试时即使达到90%的查准,放到1:20的环境查准也会大幅度降低到30%(试过xgboost,libsvm,libliner,fasttext等,近乎线性成比例降低,cnn目前效果和前面类似,加了earlystop,dropout最合适的还是原始论文参数)。
像这种正反比严重数据倾斜的分类识别问题,有没有更合适的方法呢?
答案:
是的,这类问题在文本分类中大量存在,而且很棘手。比如垃圾邮件分类就是一个典型的例子。原因是文本分类往往是以全部可能的自然语言作为采样空间的,这个空间极其巨大,而我们所关心的问题往往只是其中一个非常小的子集。自然的,在这样的情况下,模型非常难以学到正确的决策边界。
完全消除数据不平衡带来的问题是非常困难的,但是有一些办法可以进行缓解。对应这样的问题,我觉得可以从以下几点来考虑。
首先,我们要明确对于precision和recall,我们的需求是怎样的。对于数据极其不平衡的情况,precision和recall的trade-off尤其显著。通过under-sampling/over-sampling来配平正反例是可以提升recall,但是一定会出现大量的false positive。如果我们认为错杀的成本很高,可以适当地降低对于precision的要求。反之,如果我们追求precision,那么可以采用基于规则的方式,通过对关键词的特征进行过滤,当然这样recall就会很惨。这是一个必须接受的现实。如果将这两种策略结合,最起码可以做这样的尝试:对于高precision的分类器,采取比较高信心的策略,譬如探测出来就直接报告这个用户甚至屏蔽;对于高recall的分类器,可以采取一些warning的措施,不强制做影响用户的操作。
可以再深度的挖掘一下为什么over-sampling在这种情况下工作得不好。以smote为例,我们希望从样本及其最近邻的点的连线上选一个随机点将其作为新的样本来合成。但是文本数据(无论是用n-gram feature还是distributed representation)都是很高维度的。在高维空间的一个事实就是数据倾向于接近互相正交,故而两两不相近,所以采用NN的思想来做up-sampling,效果是不会太好的。
并且,我们在分布式语义表示中所假定的“连续语义空间”,也许并不能很好地反应语言的现实状况。诚然,如果是语义离得很远,一般而言很难意思相近。但是有时候,对于特定的应用来说,譬如题主提到的色情低俗识别,边界是很模糊的,就像“色情”和“情色”之间的界定,实际上相当暧昧。但是这在词向量上是很难体现出来的。
直观一点的体现,就是可以想像,如果你对一幅照片进行高斯模糊,那么多半我们还是能看得出这幅图的大概,只是细节变得不清晰了。
但是如果对一个句子的tensor做类似的操作,再decode出来,估计就面目全非了。
所以呢,我觉得题主可以考察一下以下几个点:
-正样本的数据,是否能够公正地代表正样本的分布?是否有明显的属于正样本但是没有包括进来的例子?很大可能,需要补数据。如果真的是缺乏正样本数据的话,用什么办法都很难了。
-针对正样本产生一些较为相似/易于混淆的负样本,并利用这些样本来训练一个分类器(在决策边界附近填充一些数据)。
-做一次聚类分析。可以考察,其中是否有一些cluster明显的不包含正样本。我们是否可以先做一个粗的分类器,将这一些样本分开,然后再看剩下来的数据是否不均衡的状况会减轻很多。在剩余的数据上再做一个分类器。
-如果是采用DNN,有一些tricks可以一定程度地缓解数据不平衡的问题:1) 在随机选择mini batch的时候,每个batch中正负样本配平;2)对于正样本,给予更高的学习率
-训练一个生成模型,仅仅是针对正样本,这样可以最大限度地学习到正样本的特征,在开放域的效果往往优于判定模型。
5. 从模型评价指标的角度,重新审视训练好的模型性能。
从前面的分析可以看出,准确度这个评价指标在类别不均衡的分类任务中并不能work,甚至进行误导(分类器不work,但是从这个指标来看,该分类器有着很好的评价指标得分)。因此在类别不均衡分类任务中,需要使用更有说服力的评价指标来对分类器进行评价。这里推荐指标:
混淆矩阵(Confusion Matrix):使用一个表格对分类器所预测的类别与其真实的类别的样本统计,分别为:TP、FN、FP与TN。
精确度(Precision)
召回率(Recall)
F1得分(F1 Score):精确度与找召回率的加权平均。
Kappa (Cohen kappa)
ROC曲线(ROC Curves):见Assessing and Comparing Classifier Performance with ROC Curves
数据清洗
1.什么是数据清洗?
数据清洗从名字上也看的出就是把“脏”的“洗掉”,指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。通俗点来讲,就是去掉或者修复掉影响后续模型训练的“脏样本”。
2.如何进行数据清洗?
关于数据挖掘时,如何清洗数据,请看《数据清洗的一些梳理》关于Excel大数据工程师,如何清洗数据,请看《清理数据的十大方法》
我们重点谈一谈,深度学习中的图像+文本数据,如何清洗数据。
图像数据应该如何清洗?
图像数据需要清洗的一个主要原因就是,数据标注存在问题(通常很大,已经影像到模型训练效果了)。我们同样可以从数据和模型设计的角度来考虑,如果解决在“脏数据”的情况下,正常炼丹。推荐一个图像数据爬虫的代码:https://github.com/kong36088/BaiduImageSpider
从数据的角度来看,常用的方法可以有以下几种:
随机抽样,查看标注样本质量。首先,我们需要观察样本的标注情况,如果样本标注情况,问题不大可以暂时不做处理。
去掉难的样本。以ADAS场景为例,实际上在视频图像中,存在非常多的小目标和遮挡目标,这个时候,我们需要明确定义,当前模型能够处理的边界在哪里,检出目标的尺寸多大?遮挡程度什么样子?
利用训练好的模型,做样本分析。利用训练好的模型,在测试集上进行测试,分析测试结果。在哪一类样本上存在明显问题。产生这个问题的原因是模型还是数据?如果是数据,需要重新明确标注规范。并采用适当的方法进行修正处理。
从模型的角度来看,主要的方法就是将其作为一个“弱标签”问题来进行处理。更大的方向,就是不确定问题。
弱标签:南京大学周志华教授综述论文:弱监督学习 - 知乎
不确定性:http://wemedia.ifeng.com/72003766/wemedia.shtml
以上仅仅是一些概念的介绍。更多内容还是推荐Google学习去检索,关键词推荐“ uncertainty、weak supervision、weak label、 deep learning ”
文本数据应该如何清洗?
文本数据相比于图像数据而言,数据类型更加复杂。对于一些偏统计和日志类数据,推荐参考上述的数据挖掘中数据清晰方法。这里我们主要以自然语言处理为主。对于NLP数据,首先需要的就是抓取海量的训练数据。
在抓取到海量数据以后,下一步就是数据清洗。
中文首先需要分词,可以采用结巴分词、HanNLP、刨丁解牛等分词工具;
数据规范化处理(Normalization):比如通常会把文本中的大写转成小写,清除文本中的句号、问号、感叹号等特殊字符,并且仅保留字母表中的字母和数字。小写转换和标点移除是两个最常见的文本 Normalization 步骤。是否需要以及在哪个阶段使用这两个步骤取决于你的最终目标。
Tokenization,Token 是“符号”的高级表达。一般指具有某种意义,无法再分拆的符号。在英文自然语言处理中,Tokens 通常是单独的词。因此,Tokenization 就是将每个句子分拆成一系列词。可以使用NLTK工具箱来完成相关操作。
Stop Word 是无含义的词,例如'is'/'our'/'the'/'in'/'at'等。它们不会给句子增加太多含义,单停止词是频率非常多的词。 为了减少我们要处理的词汇量,从而降低后续程序的复杂度,需要清除停止词。
Part-of-Speech Tagging:还记得在学校学过的词性吗?名词、代词、动词、副词等等。识别词在句子中的用途有助于我们更好理解句子内容。并且,标注词性还可以明确词之间的关系,并识别出交叉引用。同样地,NLTK 给我们带来了很多便利。你可以将词传入 PoS tag 函数。然后对每个词返回一个标签,并注明不同的词性。
Named Entity 一般是名词短语,又来指代某些特定对象、人、或地点 可以使用 ne_chunk()方法标注文本中的命名实体。在进行这一步前,必须先进行 Tokenization 并进行 PoS Tagging。
Stemming and Lemmatization:为了进一步简化文本数据,我们可以将词的不同变化和变形标准化。Stemming 提取是将词还原成词干或词根的过程。
一些词在句首句尾句中出现的概率不一样,统计N-GRAM特征的时候要在句首加上BOS,句尾加上EOS作标记。
把长文本分成句子和单词这些fine granularity会比较有用。
一般会有一个dictionary,不在dictionary以内的单词就用UNK取代。
单词会被转成数字(它对应的index,从0开始,一般0就是UNK)。
做机器翻译的时候会把单词转成subword units。
数据增强
1.什么是数据增强(data augmentation)?
数据增强是扩充数据样本规模的一种有效地方法。深度学习是基于大数据的一种方法,我们当前希望数据的规模越大、质量越高越好。模型才能够有着更好的泛化能力,然而实际采集数据的时候,往往很难覆盖掉全部的场景,比如:对于光照条件,在采集图像数据时,我们很难控制光线的比例,因此在训练模型的时候,就需要加入光照变化方面的数据增强。再有一方面就是数据的获取也需要大量的成本,如果能够自动化的生成各种训练数据,就能做到更好的开源节流。
2.如何进行数据增强?
数据增强可以分为两类,一类是离线增强,一类是在线增强。
离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个 batch 的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用 GPU 优化计算。
我们具体来看一下在不同领域,有哪些常见的数据增强的方法。
先聊聊图像中的数据增强问题:
如何对图像数据进行有效的数据增强?
空间几何变换:翻转(水平和垂直)、随机裁剪、旋转、放射变换、视觉变换(四点透视变换)、分段放射
像素颜色变换类:噪声(高斯、椒盐)、CoarseDropout(在面积大小可选定、位置随机的矩形区域上丢失信息实现转换,所有通道的信息丢失产生黑色矩形块,部分通道的信息丢失产生彩色噪声)、SimplexNoiseAlpha(产生连续单一噪声的掩模后,将掩模与原图像混合)、FrequencyNoiseAlpha(在频域中用随机指数对噪声映射进行加权,再转换到空间域。在不同图像中,随着指数值逐渐增大,依次出现平滑的大斑点、多云模式、重复出现的小斑块)
模糊类:高斯模糊、ElasticTransformation
HSV对比度变换
RGB颜色扰动
随机擦除
超像素法
转化法
边界检测
Grayscale
锐化与浮雕
多样本合成:SMOTE、SamplePairing、Mixup
具体解释,可参考博客:【技术综述】 一文道尽深度学习中的数据增强方法(上),https://www.jianshu.com/p/99450dbdadcf
在使用图像数据进行数据增强的时候需要注意哪些问题?
首先需要注意的一点是,引入数据增强并不一定会带来模型性能上的提升,尤其是在数据增强的时候,需要考虑如何设置恰当的增强比例因子。实际上,只有当我们增强后的样本,理论上和我们的实际业务场景最接近的时候,才会达到性能最好。也就是所谓的训练集和测试集样本分布一致的时候。 因此,在进行增强的时候不要盲目增强,需要看一下看数据集增强之后的效果如何?
如何查看数据增强后的效果?对于离线数据,保存图片以后就能够看到,但是对于在线的数据,则需要借助工具了。这一点tensorflow做的就很好,可以直接使用tensorboard来进行实时训练图片查看。
再来看看文本中的数据增强问题:
NLP中小的扰动可能会对含义造成比较大的影响,比如:去掉或改变某个词,会导致整个句子的含义或情感发生巨大偏差。
如何文本数据进行数据增强?
随机drop和shuffle
drop:对于标题和描述中的字或词,随机的进行删除,用空格代替。另一种是 shuffle, 即打乱词序。
对于"如何评价 2017 知乎看山杯机器学习比赛?" 这个问题,使用 drop 对词层面进行处理之后,可能变成"如何 2017 看山杯机器学习 “. 如果使用 shuffle 进行处理,数据就 可能变成"2017 机器学习?如何比赛知乎评价看山杯”。 数据 增强对于提升训练数据量,抑制模型过拟合等十分有效.code:https://github.com/dupanfei1/deeplearning-util/blob/master/nlp/augment.py
同义词替换
随机的选一些词并用它们的同义词来替换这些词,例如,我们将句子“我非常喜欢这部电影”改为“我非常喜欢这个影片”,这样句子仍具有相同的含义,很有可能具有相同的标签。但这种方法对我的任务来说没什么用,因为同义词具有非常相似的词向量,因此模型会将这两个句子当作相同的句子,而在实际上并没有对数据集进行扩充。
回译
在这个方法中,我们用机器翻译把一段英语翻译成另一种语言,然后再翻译回英语。这个方法已经成功的被用在Kaggle恶意评论分类竞赛中。反向翻译是NLP在机器翻译中经常使用的一个数据增强的方法。。其本质就是快速产生一些不那么准确的翻译结果达到增加数据的目的。
例如,如果我们把“I like this movie very much”翻译成俄语,就会得到“Мне очень нравится этот фильм”,当我们再译回英语就会得到“I really like this movie”。回译的方法不仅有类似同义词替换的能力,它还具有在保持原意的前提下增加或移除单词并重新组织句子的能力。
回译可使用python translate包和textblob包(少量翻译),或者使用百度翻译或谷歌翻译的api通过python实现。
参考:https://github.com/dupanfei1/deeplearning-util/tree/master/nlp
文档裁剪
新闻文章通常很长,在查看数据时,对于分类来说并不需要整篇文章。 文章的主要想法通常会重复出现。将文章裁剪为几个子文章来实现数据增强,这样将获得更多的数据。
生成对抗网络
GAN是深度学习领域中最令人兴奋的最新进展之一,它们通常用来生成新的图像,但它的一些方法或许也可以适用于文本数据。
预训练模型
最近很多论文运用大量语料库预训练语言模型来处理自然语言任务得到了惊人的结果,如ULMFIT,Open-AI transformer和BERT。语言模型是通过前面的单词预测句子中会出现的下一个单词。
预先训练的词向量
NLP深度学习架构通常以嵌入层开始,该嵌入层将一个热编码字转换为数字矢量表示。我们可以从头开始训练嵌入层,但我们也可以使用预训练的单词向量,如Word2Vec,FastText或Glove,这些词向量使用无监督学习方法训练大量数据或训练我们域中的数据。预训练的词向量非常有效,因为它们为基于大量数据的单词提供模型上下文,并减少模型的参数数量,从而显着降低过度拟合的可能性。
预先训练的句子向量
我们可以将模型的输入从单词更改为句子,这样我们可以使用较少的模型,其中参数数量较少,仍然具有足够的表达能力。为了做到这一点,我们可以使用预先训练好的句子编码器,如Facebook的InferSent或谷歌的通用句子编码器。我们还可以使用跳过思维向量或语言模型等方法训练未标记数据的句子编码器。
预先训练的语言模型
最近的论文如ULMFIT、Open-AI变换器和BERT通过在非常大的语料库中预训练语言模型,为许多NLP任务获得了惊人的结果。语言模型是使用前面的单词预测句子中的下一个单词的任务。对我来说,这种预训练并没有真正帮助获得更好的结果,但文章已经展示了一些方法来帮助我更好地微调,我还没有尝试过。
无人监督或自我监督学习的预训练
如果我们有一个来自未标记数据的大型数据集,我们可以使用无监督的方法,如自动编码器或掩码语言模型,仅使用文本本身预训我们的模型。对我来说更好的另一个选择是使用自我监督。自我监督模型是在没有人类注释的情况下自动提取标签的模型。一个很好的例子是Deepmoji项目,在Deepmoji中,作者训练了一个模型,用于从推文中预测表情符号,在表情符号预测中获得良好结果之后,他们使用他们的网络预先训练了一个获得最新结果的高音扬声器情绪分析模型。表情符号预测和情绪分析显然非常相关,因此它作为预训练任务表现得非常好。新闻数据的自我监督任务可以预测标题、报纸、评论数量、转推的数量等等。自我监督可以是一种非常好的预训方法,但通常很难分辨出哪个代理标签将与你的真实标签相关联。
小样本问题
1.什么是小样本问题?
小样本问题是指研究如何从少量的样本中去学习。众所周知,深度学习的训练需要大量的数据,然而,在实际的生产生活中,可能由于数据采集困难,样本标注代价高等问题,使得训练样本的规模不大,因此,小样本问题就成为了机器学习领域中重要的研究方向之一。本。
小样本会对模型训练带来什么影响?
小样本训练模型时,容易产生过拟合现象。具体以分类问题为例:
对于classification model,有如下结论:
训练样本N,h为Vc维数,详见https://www.cnblogs.com/HappyAngel/p/3633989.html
如果现在训练模型的算法能使得training error很小,而model complexity penalty又很小,就能保证test error也很小的概率是 1-η。所以要使得模型的generalization比较好,要保证training error和model complexity penalty都能比较小。观察model complexity penalty项,可以看到,h越大,model complexity penalty就会越大。N越大,model complexity penalty则会越小。大致上讲,越复杂的模型有着越大的h(VC dimension),所以为了使得模型有着好的generalization,需要有较大的N来压低model complexity penalty。 这就是为什么深度学习的模型需要大量的数据来训练,否则模型的generalization会比较差,也就是过拟合。
目前关于小样本问题,有哪些研究进展?
对于小样本问题的研究主要有:
1. zero-shot learning(零样本学习),即要识别训练集中没有出现过的类别样本,虽然类别不存在,但是我们可以学习到一个映射X->Y。如果这个映射足够好的话,我们就可以处理没有看到的类了。 比如,我们在训练时没有看见过狮子的图像,但是我们可以用这个映射得到狮子的特征。一个好的狮子特征,可能就和猫,老虎等等比较接近,和汽车,飞机比较远离。
2. one-shot learning/few shot learning,即在训练集中,每一类都有一张或者几张样,主要方法可以关注迁移学习、meta-learning,metric-learning的相关研究进展。单例学习是迁移学习/Domain Adaptation的一个特例。模型在source domain训练好之后,迁移到target domain,target domain只用一个标记样本去训练模型的参数就可以了。
比如识别平衡车。训练时,source domain有大量标记样本,比如自行车、独行车、摩托车和轿车等类别,模型可以从source domain学到表示车的有效特征,比如有轮子、轮子尺寸大小、有踏板、方向盘或龙头等。测试时,在target domian,只需要一个或很少一些target domain的标记样本,比如只需要在模型可以准确识别车的条件下,给模型一张平衡车的标记图片就可以了。
实际上,Zero/One-shot learning都属于transfer learning,要点在于先学到好的X->Y的关系,希望能应用到其他问题上。
3. 从数据增强的角度来看,也可以用来解决one-shot,zero-shot的相关问题
第一,利用流信息学习one-shot模型,常见的有半监督学习和transductive learning,探讨的是如何用无标签数据去做one-shot learning。
第二,在有预训练模型时,用这些预训练模型进行数据增强。
第三,从相近的类别借用数据,来增强训练数据集。
第四,合成新的有标签训练数据,用一些遥感里的方法,可以合成一些图像,或者3d物体。
第五,用GAN来学习合成模型,比如最近用GAN来做personal ID和人脸相关研究。
第六,属性引导的增强方法。具体大家可以在文章里进行详细了解。
几个小样本问题的数据集
1. 提供几个最常用的Zero-Shot Learning的数据集,均为GoogleNet提取的图片特征,引用相应数据时,请注意对应作者的引用说明。
AwA:http://pan.baidu.com/s/1nvPzsXb
CUB:http://pan.baidu.com/s/1nv3KCYH
aPaY:http://pan.baidu.com/s/1hseSzVe
SUN:http://pan.baidu.com/s/1gfAc33X
ImageNet2:http://pan.baidu.com/s/1pLfZYQ3
2. one-shot learning 数据集
Omniglot
行人Reid数据集:Viper/CUHK01
数据标注
1.什么是数据标注?
在谈数据标注是什么之前,我们首先来了解一下什么是数据。如果把人工智能比作金字塔,最顶端的是人工智能应用(比如无人车、机器人等),而最低端则是数据服务。人工智能的最终目标使计算机能够模拟人的思维方式和行为。若想达到这个目标,则需要大量优质的训练数据使人工智能可以通过学习从而形成更好的模型,变得更加智能化。所以简单来说,数据标注就是使用自动化工具通过分类、画框、注释等等对收集来的数据进行标记以形成可供计算机识别分析的优质数据的过程。
2.哪些数据需要标注以及标记什么?
数据标注的对象主要分为文本、图片、音频、视频四个种类:
文本标注主要包括情感分析、知识库、关键词提取、文字翻译、搜索引擎优化等。就比如,识别一句话蕴含的情感,翻译等等;
图片标注主要包括图像分割 、物体检测 、图像语义理解、图像生成 、图片加注等服务;
音频标注主要包括对全球主要语言和语料、包括方言、特殊情景语音进行识别标注,语音识别等等;
视频标注主要包括对视频中出现的物体、文字、语音、情景等进行标注。
3.工程管理中,数据标注需要哪些角色?
1)一般来说,数据标注部分可以有三个角色
A)标注员:标注员负责标记数据。
B)审核员:审核员负责审核被标记数据的质量。
C)管理员:管理人员、发放任务、统计工资。
只有在数据被审核员审核通过后,这批数据才能够被算法同事利用。
4.数据标注的基本流程?
只要是跟“监督学习”沾边的产品/技术,比如图像识别、人脸识别、自然语言理解等等,他们都有一个必走的流程——数据标注,模型训练,模型测试,反馈测试结果,重新训练或重新选择数据,测试结果通过,产品评估,产品完成。
不断地用标注后的数据去训练模型,不断调整模型参数,得到指标数值更高的模型。
A)任务分配:假设标注员每次标记的数据为一次任务,则每次任务可由管理员分批发放记录,也可将整个流程做成“抢单式”的,由后台直接分发。
B)标记程序设计:需要考虑到如何提升效率,比如快捷键的设置、边标记及边存等等功能都有利于提高标记效率。
3)进度跟踪:程序对标注员、审核员的工作分别进行跟踪,可利用“规定截止日期”的方式淘汰怠惰的人。
4)质量跟踪:通过计算标注人员的标注正确率和被审核通过率,对人员标注质量进行跟踪,可利用“末位淘汰”制提高标注人员质量。
5)数据优化:这部分基本交由算法同事跟进,但产品可依据需求,向算法同事提出需要注意的方面;举个栗子——背景:一个识别车辆的产品对大众车某系列的识别效果非常不理想,经过跟踪发现,是因为该车系和另外一个品牌的车型十分相似。那么,为了达到某个目标(比如,将精确率提高5%),可以采用的方式包括:A)补充数据:针对大众车系的数据做补充。值得注意的是,不仅是补充正例(“XXX”应该被识别为该大众车系),还可以提供负例(“XXX”不应该被识别为该大众车系),这样可以提高差异度的识别。B)优化数据:修改大批以往的错误标注。
5.数据标注工具有哪些?
(工具很多,推荐使用labelMe/labelImg)
1)NLP标注工具:
Stanford CoreNLP – Natural language software
NLP标注工具BRAT
通用文本标注工具 labelme
doccano
2)图像标注工具:
LabelImg
数据标注的一些经验之谈
标注数据时,要考虑数据的扩展性,比如:目标检测可以考虑标注四个点,而不是一个矩形框;
数据标注时如何处理不确定样本,可以考虑引入置信度,或者dont care;
数据标注规范根据实际状况需要及时更新;
数据需要频繁的check有没有问题,这些都是管理上的问题;
算法要及时验证数据是够合理,以及需要补充哪些数据。
调参技巧
1. 深度学习有哪些需要们关注的参数呢?
大家记住一点:需要用到调参技巧的参数都是超参数!!因此,这个问题还可以换成更专业一点:神经网络中有哪些超参数?主要从两个方面来看:
和网络设计相关的参数:神经网络的网络层数、不同层的类别和搭建顺序、隐藏层神经元的参数设置、LOSS层的选择、正则化参数
和训练过程相关的参数:网络权重初始化方法、学习率使用策略、迭代次数、小批量数据 minibatch的大小、输入数据相关
2. 深度学习在什么时候需要动用调参技巧,以及如何进行调参呢?
通常网络训练的结果一般表现为以下五种情况:过拟合、欠拟合、恰好拟合,趋于收敛但一直在震荡以及完全不收敛。关于过拟合、欠拟合和恰好拟和,在机器学习中的定义描述如下:(不知道的可以移步此博客:https://www.imooc.com/article/44090 )
过拟合、欠拟合、恰好拟合的现象:
过拟合就是完全学习了数据的信息,偏差小但是方差很大,分割边缘或拟合曲线看起来会因为过度追求全部数据都正确,而看起来比较曲折;
欠拟合就是没有完全学习到数据的信息,方差小但是偏差很大,分割边缘或者拟合曲线看起来会比较规则,这是因为对数据信息学习和提取的不充分;
恰好拟合就是学习的刚刚好,提取出了主要的数据信息,方差小,偏差也小。
我们分别来看一下,在这几种种情况下,需要考虑调整哪些参数?
首先来看恰好拟合的情况!
恰好拟合:从LOSS曲线上看,训练集和测试集的LOSS都已经收敛,且很接近!模型能够拟合训练样本和测试样本的分布,且是一致的!这样的优点就是模型的泛化能力强,简单来讲就是在训练集和测试集上效果都很好。通常表现如A图所示。
这个时候还需要调参??效果都这么好。需要调参! 主要集中在网络结构设计方面的参数,在工程项目上,同样的效果。我们需要考虑更小、更轻量型的网络结构,计算量=====功耗,网络大小=======内存!!!一定要学会减少计算量、较小网络大小,当然如果说你的算力随便用,后面的内容可以忽略了。这时候可以考虑:
减少网络层数
减少不同的层的参数,主要是卷积核的数量
考虑深度可分离这样的轻量型卷积结构
还有一种情况,就是虽然训练集和测试集都已经完美收敛,拟合。
但是测试集的LOSS没办法达到训练集的LOSS,这时候也是考验丹师的实力的时候了!
别急,我们在后面聊!
再来看欠拟合的情况!
欠拟合:从LOSS曲线上看,训练集和测试集从趋势上还没有收敛!如图B所示。(不要告诉我不知道什么是收敛,好吧..就是loss曲线变平了,如A所示)
当然,欠拟合也有可能表现在训练集和测试集上效果都一般,在训练集上的精度也不高。
这个时候,怎么办?需要调整哪些参数?通常考虑以下几个方面的参数调整:
加大训练迭代次数,有可能是网络还没训练完!!这种低级错误千万不能犯
加大迭代次数的同时可以考虑进一步衰减调小学习率
添加更多的层,也有可能是网络容量不够!
去掉正则化约束的部分,l1\l2正则(正则主要是为了防止过拟合)
加入BN层加快收敛速度
增加网络的非线性度(ReLu),
优化数据集,进行数据清洗,参考博客《炼丹笔记之数据清洗》https://mp.weixin.qq.com/s/W8angaDewLTY_YniN8JmeQ
再来看过拟合的情况!
过拟合:从样本曲线上看,从看都趋向收敛,但是测试集上的LOSS很高,甚至出现回升的现象。如D图所示。说明模型的泛化能力很差,有可能训练集和测试集数据分布不一致,更加可能的是模型太复杂。
其实,过拟合才是困扰丹师们最大的痛!怎么解决呢?通常有以下策略:
增加样本数量,训练样本太少或者说小样本问题,很容易导致过拟合。推荐阅读博主的另一篇文章,关于小样本问题的博客:《炼丹笔记之小样本学习》,链接地址:https://mp.weixin.qq.com/s/6hzGMOMrG2w-54c4zyRj5g
数据增强,可以参考博主的另一篇博客《炼丹笔记之数据增强》https://mp.weixin.qq.com/s/KfiggFTzDRMjQWzvFd_C_g
早停法(Early stopping),从LOSS不在下降的地方拿到模型,作为训练好的模型
增加网络的稀疏度,
降低网络的复杂度(深度)
L1 regularization,
L2 regulariztion,
添加Dropout,
适当降低Learning rate,
适当减少epoch的次数,
再来看,趋于收敛但是震荡的情况!
还有一种情况,就是网络在训练集上已经趋于收敛,但是在测试集上存在很严重的LOSS震荡的情况,怎么办?这时候,可以从以下几个角度考虑:
训练集和测试集分布是否存在较大的差异?
是否由于数据增强做的太过分了?
学习率是不是还很高?如果是,降低学习率,或者在等等,等到学习率到 10e-6/10e-7这样的大小
测试集LOSS的计算是基于单个batch还是整个测试集?(一定要基于整个测试集来看)
网络是否存在欠拟合的可能,如果欠拟合参考上面欠拟合的方法
再来看,完全不收敛的情况!
在上面,我们并没有给出完全不收敛的情况曲线图。
那这要怎么判断网络有没有完全没收敛?一个是LOSS一直都很高,自己按照自己定义的LOSS函数估计下,全部为0的时候LOSS是多少,就可以大致估计出LOSS要低于多少网络才能算作是收敛了。
如果网络不收敛怎么办?考虑以下几点:
数据错误,先检查数据!输入数据是不是有问题?预处理是不是有问题?数据增强是不是有问题?标签是不是有问题!避免低级错误啊!!
网络设计或者参数使用错误,一定要确保网络层的设计和参数设置正确,确保没有问题啊!!
考虑LOSS设计是否存在问题,优化函数是否合理?
设计的算法本身是够存在问题,是否存在正负样本严重失衡的问题? 推荐阅读博客,《炼丹笔记之样本不平衡问题》:https://mp.weixin.qq.com/s/R7z-mtgr4XiOVAYwP2SBIw
最后,我们再来考虑,在已经收敛的情况下,如何进一步提高模型的精度!
优化网络结构,使用更好的backbone
使用更好的LOSS函数,比如:回归问题可以考虑smooth-l1等
考虑使用难例挖掘的方法
有条件的话,加大batchsize
考虑预训练模型
观察测试样本,查找case,针对Case来,补充样本+数据增强
以上方法都试过发现,依然不行,可以重新开始阅读论文了。推荐arxiv、各大顶会系列、trans系列
当然,也可能遇到算法极限了,要么自己创新,要么多烧香拜佛等着大牛提出新方法吧。
尝试不同的优化函数,交替训练,fine-tuning
不同的权重初始化方法
尝试不同的学习率初始值和衰减值
考虑在梯度上做文章,可以是梯度裁剪、梯度校验、梯度归一化等方法
再来聊一聊,关于自动调参的问题。
目前正处于研究阶段,有一些方法,但是不通用。
Gird Search. 这个是最常见的。具体说,就是每种参数确定好几个要尝试的值,然后像一个网格一样,把所有参数值的组合遍历一下。优点是实现简单暴力,如果能全部遍历的话,结果比较可靠。缺点是太费时间了,特别像神经网络,一般尝试不了太多的参数组合。
Random Search。Bengio在Random Search for Hyper-Parameter Optimization中指出,Random Search比Gird Search更有效。实际操作的时候,一般也是先用Gird Search的方法,得到所有候选参数,然后每次从中随机选择进行训练。
Bayesian Optimization. 贝叶斯优化,考虑到了不同参数对应的实验结果值,因此更节省时间。和网络搜索相比简直就是老牛和跑车的区别。具体原理可以参考这个论文:Practical Bayesian Optimization of Machine Learning Algorithms,这里同时推荐两个实现了贝叶斯调参的Python库,可以上手即用:1)jaberg/hyperopt, 比较简单。2)fmfn/BayesianOptimization, 比较复杂,支持并行调参。
3. 调参的一般过程是什么?
基本上遵循从粗到细,先易后难的顺序,具体给出炼丹流程如下:
1. 首先是搭建模型:
如果有源码,先直接把源码跑通,没有源码考虑自己的搭建模型;
主干网络可以直接考虑:resnet(后续网络优化部分在考虑裁剪或者其他网络结构)
loss根据相应的任务来进行选择,可能是交叉熵损失(分类任务)、smooth-l1(回归任务)等
优化函数,采用Adam或者SGD都可以。先随便选一个常用的优化方法就可以
学习率可以从0.1或者0.01开始
batchsize:32或者64
2. 准备小规模样本,比如存在100w数据,可以先打包1w数据或者几千样本,可以暂时先不考虑数据增强,正常打包后直接训练网络,用小批量样本来测试网络搭建中可能存在的bug,直到网络可以收敛,确保网络搭建的准确性,方便后续出现问题时,问题的定位。
3. 小规模样本训练收敛之后,则可以确定模型框架没有问题。开始加大样本规模到100W,使用大规模样本训练;
4. 训练后,分析训练集和测试集LOSS的变化情况,考虑上述过拟合、欠拟合、收敛不稳定等不同情况,优化相应的参数;
5. 在LOSS出现较为理想的结果之后,基本上网络训练也趋于稳定。接下来则是重点排查难点问题,尝试创新性的调整网络架构,尝试新的loss,调整数据增强策略,不同优化函数,不同学习率,不同batchsize等等,通过各种手段,来提高准确度。其中,最关键的一定是“数据清洗”。推荐阅读博客《炼丹笔记之数据清洗》:https://mp.weixin.qq.com/s/W8angaDewLTY_YniN8JmeQ
6. 另外,丹师应该对业界内的baseline方法有一个大概的了解,方法能够调到什么程度,也要做到心里有数。这样,才能在上面的这些操作,都完成的差不多了,算法没办法调优的时候,有一个借口,告诉自己:业界也就这个水平了~~~哈哈。
聊一聊深度学习中的模型设计。
主要从以下几个方面来看:
1. 如何去设计一个神经网络?
2. 如何去优化一个神经网络?
3. 在设计网络的时候,我们需要注意那几点问题?
如何去设计一个神经网络?
这里我们主要关注baseline方法的搭建,如果想要更好的设计,需要在去针对任务做调优。
比较常见的思路,就是直接采用已经设计好的backbone。选择最多的应该是就Inception结构或者ResNet结构。
以tensorflow为例,标准的网络结构目前google已经开源出来,所以我们直接使用就可以。
下载链接:
https://github.com/tensorflow/models/tree/master/research/slim/nets
这里包括了非常多的网络结构。可以挑选我们需要的模型,通常使用inception-v3/v4或者resnet-50。
模型如何调用呢?
我们只需要添加,该文件到我们项目中,然后:
from resnet_v2 import * (粗暴一点)
直接调用函数就可以正常使用,不过需要注意的是,输出结构为Feature Map,也就是一个四维的张量。在后续使用的时候,需要在加FC层等其他的层或者以及LOSS层。
这个主干网络可以用于分类、检测、分割等不同任务的主干网络,在框架结构不变的前提下,我们就能够得到针对不同主干网络的baseline方法的效果。
2. 如何去优化一个神经网络?
在上述过程中,我们拿到了baseline方法。但是这离我们最终的目标还有些差距,主要体现在以下两个方面:
我们需要从backbone的角度来提高模型的性能
我们需要减少模型的计算量,压缩模型的大小
通常的做法有哪些呢?
(1)从backbone角度来优化模型的性能主要有以下几点可以考虑:
考虑更大的channel数量(增大了计算量)
考虑使用空洞卷积增大感受野
考虑resnet + inception结构
考虑FPN结构(检测、分割网络中)
考虑attention结构,比如: SENet
(2)如何去较少backbone的网络参数/网络计算量呢?
多个小卷积核代替大卷积核
考虑轻量型卷积,也就是使用深度可分离卷积来代替常规卷积,比如:mobilenet系列、shuffleNet系列等
考虑stride=2代替掉pooling层
计算每一层参数量和计算量,对参数量规模叫大的层调整channel
使用1*1的卷积核来进行channel降维和升维
模型剪枝
模型定点化/量化
教师网络
3. 在设计网络的时候,我们需要注意那几点问题?
除去第一层会采用大卷积核一般也不会超过7*7,其它层均使用3*3或者1*1卷积核
学会巧妙的使用1*1的卷积核来进行通道降维和升维
使用batchnorm层,加快收敛速度(在tensorflow,注意设置batchnorm参数,在caffe中,bn层要和scale配合使用)
网络通常为block堆叠,每一个block都是一个最小重复单元(由多个卷积组成)
通常在进行下采样的时候会进行 channel数量的翻倍
在shuffleNet V2中,作者也给出CNN 网络结构设计的准则来帮助神经网络可以更高效。下面先贴出文中观点:
a. 输入通道数与输出通道数保持相等可以最小化内存访问成本(memory access cost,MAC)。
b. 分组卷积中使用过多的分组数会增加内存访问成本(MAC)
c. 网络结构太复杂(分支和基本单元过多)会降低网络的并行程度
e. Element-wise 的操作消耗也不可忽略(包括ReLU,Tensor的相加,偏置的相加等等操作)
主干网络优先考虑resnet+FPN网络结构作为baseline在进行额外的优化。