2019-05-27 14:08:31 Tao_758 阅读数 156
  • 深度学习中基础模型性能的思考和优化

    深度学习基础模型性能思考和优化教学视频,从基本图像模型出发,介绍模型优化的基本思路,使用并联模型和一般剪枝提高模型精确度,使用剪枝优化模型精确度,以及其他需要注意的问题。可以和图书《深度学习算法实践》中部分内容互相参看。

    1273 人正在学习 去看看 CSDN讲师

前言:从小白入门,通过这次比赛学到很多东西。现在把文档放到这里,希望能够帮助到需要的人。 特别感谢初赛排名第一的YaHei大佬。感谢他开源的代码把我带进了比赛的大门。附上大佬的项目链接:

https://github.com/hey-yahei/ZTE_Challenge2019_MOA

摘要: 本次模型压缩几乎无法重新训练,因此无法采用许多常用的模型压缩算法。针对主办方提供的已经训练完成的模型,主要使用了包括层融合、剪枝、奇异值分解等方法进行压缩。

一、 层融合

​   在神经网络训练的过程中,BN层能够加速网络收敛,并且能够控制过拟合。不过这样也增加了一些运算和参数,因此在推理过程中,可以通过将BN层与卷积层的参数融合的方式,来减少运算,并略微地实现一些模型的压缩。【1】

​   公式:

​   卷积层计算公式:
Y=WX+b Y = W*X + b

​   BN层计算公式:
Xbn=s(Xm)(σ+ϵ)+bbn X_{bn} = \frac{s(X - m)}{\sqrt(\sigma + \epsilon)} + b_{bn}
​   其中:m: 均值, $ \sigma$ : 方差, s: scale, $ b_{bn}$: 偏置, ϵ\epsilon : 滑动系数。

​   融合及将卷积层的输出作为BN层的输入,带入得到

​   融合公式:
Xbn=XsWσ+ϵ+s(bm)σ+ϵ+bbn X_{bn} = X * \frac{sW}{\sqrt{\sigma + \epsilon}} + \frac{s(b - m)}{\sqrt{\sigma + \epsilon}} + b_{bn}
​   得到融合之后的权值:
Wconv=Wsσ+ϵ W'_{conv} = W\frac{s}{\sqrt{\sigma + \epsilon}}

b_conv=(bconvm)sσ+ϵ+bbn b\_{conv} = (b_{conv} - m)\frac{s}{\sqrt{\sigma + \epsilon}} + b_{bn}

​   层融合对模型压缩的效果并不明显,对比赛所提供模型,层融合之后大小仅下降3KB。对于显存大小及推理时间的提升未做详细的量化分析。

二、 模型剪枝

​   对于一些权重极小的连接,将其去除几乎不会影响模型的准确性,反而在重训练过程中有助于避免过拟合现象的发生。本次针对该模型的剪枝以阈值修剪:去除绝对值低于$ 1*e^{-10}$的连接。关于阈值的设定,刚开始由于没有经验,不敢设很大。后来测试时发现,阈值设为小于1e61*e^{-6}以内剪枝的数量几乎一致。但是当阈值高到1e21*e^{-2}时就会对模型产生毁灭性的影响。本轮剪枝后模型大小下降也并不明显,大约有340KB左右的下降。而且由于在修剪时需要同时对权值和prototxt文件进行修改,未能做到很好地利用代码自动修剪,因此修剪体验一般。

avatar

三、 删除卷积层

   这个想法实在太过于简单粗暴,几乎不可能成为一个通用的压缩方法。幸运的是本次比赛的模型的conv5冗余较大,直接删除后边四层的影响不大,而且赛后其他同学讨论中提到甚至可以直接删除后边五层。必须承认这个方法来自QQ群中一位同学的分享,并非自己发现。我自己在这一部分的工作主要就是修改代码和prototxt文档。这一方式虽然简单粗暴,却十分有效,直接将我从弃赛的边缘拉到了前60名。该方法的主要提升在于对显存占用和推理计算量的降低。对于模型大小的压缩效果并没有很明显,该步使模型大小减少了大约8.4MB。

四、 奇异值分解

​   奇异值分解(Singular Value Decomposition, SVD)是本次比赛所使用的最主要的压缩手段,效果也是最明显的。

avatar

avatar

​   由于全连接层占据了模型中最大一部分的参数,对全连接层作奇异值分解可以得到极大的压缩收益。因此本次将SVD作为了模型压缩的重点。有几天的工作都花在了测试不同的r值对模型准确率的影响上。并且希望能够找到合适的r使得z恰好处于临界点(0.950或0.900)。最终,本次最好成绩对应的r值为136, 对应的z值为0.958。也许是由于服务器波动等因素,在r=130时,z取值为0.951,却并未得到更加理想的成绩。而使z接近0.9的r值为108,此时z值为0.901,但权值的下降并没能换来足够的显存使用及计算量的改善。这一部分对于运算速度和显存占用有着显著的优化,同时对模型的大小有着更为显著的压缩。在r=130时,模型大小下降了大约190MB, 比原来压缩了大约63%。

五、 其他未成功应用方法

(1)无需数据的卷积网络自动加速

​   无需数据的卷积网络数据加速(Data-free Automatic Acceleration of Convolutional Networks, DAC)是由Xin Li 等人与2018年提出的一种无需重新训练模型的压缩方式【2】。将卷积核分解为Depthwise 及 Pointwise两种,分解运算的核心其实还是奇异值分解。最终可以实现对已训练完成的模型的卷积核分解与替换,以及权值的迁移,而无需重新训练。原文作者在CIFAR-VGG模型上测试,发现替换靠后的卷积层可以在减少较多参数的同时只造成很小的精度损失,而处理较为靠前的卷积层则代价较大。
附上自己实现DAC的代码

https://github.com/baizhenmao95/2019-ZTE-Algorithm-Competition/blob/master/DAC_AGAIN.py

avatar

​   由于论文中给出了该算法的详细步骤,因此我尝试用代码复现了该算法,并对卷积层conv4_5_2进行了替换。虽然最终确实可以得到压缩后的模型,将r取为5时大约能够减少该层一半的参数。但是也许是我的程序实现有误,也许是该算法并不适用于该类模型的压缩,甚至也许是所选的用于替换的卷积层并不合适,总之最终得到的模型与原模型相比,所提取的特征图的余弦距离出现了负数。最后一天我压宝压在了这一算法上,却最终没能实现突破,也是一大遗憾。

(2) Octave Conv

​   OctaveConv是前几天刚出现的一个新的方法。一出现就得到了许多深度学习相关的学者和媒体的大力推荐。而其简单有效的思想也让我印象深刻。因此十分希望能够复现其中的结果,并在此次比赛中为我所用。作为一个新的方法,使用它的优势在于我可能会是比赛中为数不多的使用者,也就有可能得到几乎独一无二的改善。但是劣势在于,过于新鲜的方法意味着对其的解读与代码的实现方面可能很有限。因此在将近一周的时间内我只能对照着论文原文【3】和某个MXnet版本的第三方复现代码【4】学习。它即插即用、无需更改网络结构的特性非常吸引人,而其通俗易懂的比喻也降低了对算法的原理及其效果的理解难度。可惜最终我还是意识到它似乎是一个需要重新训练的算法,最终只能遗憾放弃。但是在之后的科研工作中也许能够真正地用到。因此也算是一项不错的收获。

avatar

(3)DEEP COMPRESSION

​   这一压缩操作来自于一篇很经典的模型压缩论文【5】以及一个caffe版本的第三方复现代码。主要做了基于Kmeans聚类的量化来压缩卷积和全连接层的权重。经过压缩后得到了一个大约只有8MB的numpy模型文件。这对于嵌入式设备的使用非常友好。但是也许由于参数选取不合适等原因造成了z值的大幅下降,最终只能弃用。但该算法的实用意义也许要大于比赛意义。

附参考资料:
【1】 https://blog.csdn.net/u013597931/article/details/85697008
【2】https://arxiv.org/pdf/1812.08374.pdf
【3】https://export.arxiv.org/pdf/1904.05049
【4】https://github.com/terrychenism/OctaveConv
【5】https://arxiv.org/pdf/1510.00149v5.pdf

2019-04-02 23:25:30 wills798 阅读数 239
  • 深度学习中基础模型性能的思考和优化

    深度学习基础模型性能思考和优化教学视频,从基本图像模型出发,介绍模型优化的基本思路,使用并联模型和一般剪枝提高模型精确度,使用剪枝优化模型精确度,以及其他需要注意的问题。可以和图书《深度学习算法实践》中部分内容互相参看。

    1273 人正在学习 去看看 CSDN讲师

原文链接: https://mp.weixin.qq.com/s/I5XgYrPCCGyfV2qTI0sJhQ

深度神经网络自出现以来,已经成为计算机视觉领域一项举足轻重的技术。其中,ImageNet 图像分类竞赛极大地推动着这项新技术的发展。精确计算水平取得了稳步的增长,但颇具吸引力的模型应用尚未得到合理的利用。

本文将综合分析实际应用中的几项重要指标:准确度、内存占用、参数、操作时间、操作次数、推理时间、功耗,并得出了以下几项主要研究结论:

  1. 功耗与批量大小、体系结构无关;

  2. 准确度与推理时间呈双曲线关系;

  3. 能量限制是最大可达准确度和模式复杂度的上限;

  4. 操作次数可以有效评估推理时间。

ImageNet 历届冠军架构评析指标

自从2012年的 ImageNet 竞赛上,Alexnet取得突破发展,成为第一个应用深度神经网络的应用,其他关于DNN的更复杂的应用也陆续出现。

图像处理软件分类挑战赛的终极目标是,在考虑实际推理时间的情况下,提高多层分类框架的准确度。为了达到这个目标,就要解决以下三方面的问题。第一,一般情况下,我们会在每个验证图像的多个类似实例中运行一个给定模型的多个训练实例。这种方法叫做模型平均或DNN集成,可以极大提高推理所需的计算量,以获得published准确度。第二,不同研究报告中对验证图像做的预估模型(集合)的操作次数不一样,模型选择会受到影响,因此不同的抽样方法(以及取样集合的大小不同)得出的报告准确度结果就会有所偏差。第三,加速推理过程是模型实际应用的关键,影响着资源利用、功耗以及推理延迟等因素,而目前尚无方法使推理时间缩短。

本文旨在对过去4年图像处理软件分类挑战赛上出现的不同种类的先进的DNN架构做对比,从计算需要和准确度两个角度做分析,主要比较这些架构与资源利用实际部署相关的多个指标,即准确度、内存占用、参数、操作时间、操作次数、推理时间、功耗。

文章主要目的是通过分析,强调这些指标的重要性,因为这些指标是优化神经网络实际部署与应用的基本硬性限制条件。

评析方法

为了比较不同模型的质量,我们收集了文献中的一些数据,分析发现不同的抽样方法得出的结论也不一样。比如,VGG-16和GoogleNet 的central-crop误差分别是8.7%和10.07%,表明VGG-16性能优于googleNet,而用10-crop抽样,则误差分别是9.33%和9.15%,VGG-16又比GoogleNet差了。于是,我们决定基于分析,对所有网络重新评估,使用单个central-crop抽样方法。

图1: Top1 vs. 网络.  Single-crop top-1 用最高评分体系检测准确度。上图中不同的配色方案表示不同的架构和作者。注意,同组网络共享相同的色相,比如所有的ResNet系列都是用粉色系表示的。


图 2: Top1 vs. 操作、数量大小、参数  Top-1 one-crop 准确度与单向前进传递所需操作次数的对比。图中气泡大小与网络参数数量成正比;右下角记录的是从5*106 到155*106参数值的历史最大值;所有数据都共享一个y轴,灰色点表示气泡中心的值。

我们使用 cuDNN-v5和CUDA-v8配置的Torch 7来做推理时间和内存占用测算。所有的试验都使用的是JstPack-2.3 NVIDIA Jetson TX1,内置视觉计算系统,64-bit ARM  A57 CPU。

使用这种限量级的设备是为了更好地强调网络架构的不同,主要是因为使用现存的大多数GPU,比如NVIDIA K40或者Titan X得出的结果基本都一样。为了测算功耗,我们使用的是Keysight 1146B Hall电流探头,内置Keysight MSO-X 2024A 200MHz 数字显波器,抽样周期2s,采样率50kSa/s。该系统由 Keysight E3645A GPIB数控直流电源供电。

具体结果

比较了以下 DDN:

  • AlexNet (Krizhevsky et al., 2012);batch normalised AlexNet (Zagoruyko, 2016);batch normalised Network In Network (NIN) (Lin et al., 2013);

  • ENet (Paszke et al., 2016) for ImageNet (Culurciello, 2016);

  • GoogLeNet (Szegedy et al., 2014);

  • VGG-16 and -19 (Simonyan & Zisserman, 2014);

  • ResNet-18, -34, -50, -101 and -152 (He et al., 2015);

  • Inception-v3 (Szegedy et al., 2015) 以及 Inception-v4 (Szegedy et al., 2016)。

1. 准确率(Accuracy)

图 1 展示了提交给 ImageNet 挑战赛的架构的 1-crop 准确率,最左边的是 AlexNet,最右边的是 Inception -v4。最新的 ResNet 和 Inception 架构相比其他架构准确率至少高 7%。本文中,我们使用不同的颜色区分不同的架构和他们的作者,同一个网络的色系相同,例如粉色系的都是 ResNet。

图2 则提供了各网络更详细的准确率值,将计算成本和网络参数的数量可视化呈现。首先非常明显的是,VGG 不管从计算需求还是参数数量方面来说,都是迄今为止最昂贵的架构,尽管它已经被广泛应用于许多应用程序。VGG 的16层和19层的实现实际上与其他所有网络都是隔绝的。其他的架构形成了一条斜线,到 Inception 和 ResNet 时,这条线开始变平缓。这表明这些模型在该数据集上到达一个拐点。在这个拐点上,计算成本(复杂性)开始超过准确率上的好处。

2. 推理时间(Inference Time)

上图(图3)显示了各架构在每个图像上的推理时间,作为一个图像批大小(从1到64)函数。我们注意到 VGG 处理一张图像所需时间约1/5秒,这使它在 NVIDIA TX1 上实时应用的可能性较小。AlexNet 的批大小从1到64的变化中,处理速度提升了3倍,这是由于它的完全连接层的弱优化,这个发现令人惊讶。

3. 功耗(Power)

由于电流消耗的高频率波动,功耗的测量相当复杂,需要高采样电流读出以避免混淆。在本研究中,我们使用的测量工具是带电流探头的 200 MHz 数字示波器。如上图所示,功耗多数情况下与批大小无关。由图3可见,AlexNet (批大小为1)和 VGG(批大小为2)的低功耗与较慢的推理时间相关。

4 内存(Memory)

分析使用 CPU 和 GPU 共享内存的 TX1 设备的系统内存消耗得到的结果由下图可见,最初最大系统内存使用情况是不变的,随着批大小增加,内存消耗增大。这是由于网络模型的初始内存分配以及批处理时的内存需求随着图像数量的增加而成比例地增加。

   

从上图中我们注意到,对规模小于 100 MB的网络,初始内存分配不会小于 200 MB,而且随后呈现为一条斜率为1.3的线性函数。

5 运算(Operations)

在神经网络加速器的自定义实现中,运算量(operation count)对于预估推理时间和硬件电路体积是必要的。

分析发现,对批大小为16的图像,每个图像的运算量和推理时间之间存在线性关系。因此,在设计网络时,可以控制运算量,以使处理速度保持在实时应用或资源有限的应用的可接受范围内。

6. 运算和功耗

分析功耗和给定模型所需的运算次数之间的关系后,我们发现不同架构之间没有特定的 power footprint(见上图)。当达到完全的资源利用时,通常批大小较大,所有网络的额外消耗大致为 11.8 W,标准偏差为 0.7 W,空闲功率为 1.30 W。这是资源完全利用时的最大系统功耗。因此,如果功耗是我们要关注的点之一,例如电池设备限制,可以简单地选择满足最低功耗要求的最慢的架构。

7 准确率和吞吐量

我们注意到,在单位时间里,准确率和推理数量之间存在非平凡的线性上限。下图显示,对于给定的帧速率,可以实现的最大准确率与帧速率本身形成线性比例。这里分析的所有网络均来自公开出版论文,并且已经得到其他研究团队的独立训练。准确率的线性拟合显示了所有架构的准确率与速度之间的关系。

此外,选定一个推理时间,可以得出资源充分利用条件下理论上的最大准确率。由于功耗固定,我们甚至可以进一步得出能耗限制下的最大准确率,这可以作为需要在嵌入式系统上运行的网络的基本设计因素。由于没有了扰流器,考虑前向推理时间时,准确率与吞吐量之间的线性关系转变为双曲线关系。那么,假设运算量与推理时间是线性关系,准确率对网络需要的运算量则具有双曲线依赖性(hyperbolical dependency)。

8 参数使用

我们已经知道,DNN 在利用全部学习能力(参数数量/自由度)方面非常低效。Han et al., 2015 的研究利用 DNN 的这个缺陷,使用权重剪枝(weights pruning)、量化(quantisation)和变长编码(variable-length symbol encoding)将网络规模减小了50倍。值得注意的是,使用更高效的架构能够产生更紧凑的呈现。如上图所示,虽然 VGG 比 AlexNet 的准确率更高(图1),但其信息密度不如 AlexNet。这意味着在 VGG 架构中引入的自由度带来的准确率上的提高不大。

结语

本文从准确性、内存占用、参数、运算量、推理时间和功耗方面,对 ImageNet 竞赛中多个先进深层神经网络进行了分析,从而对设计用于实际应用的高效神经网络提供参考并优化资源,因为在实际部署中我们能使用的资源往往十分有限。从上文可知,神经网络的精度和推理时间呈双曲关系:准确度的微量增加也会花费大量的计算时间。此外,网络模型的运算量能有效估计推理所需要的时间。

这也是我们为 ImageNet 创建 ENet(Efficient-Network)的原因。ENet 是当前对参数空间利用率最好的架构。

论文下载地址:https://arxiv.org/pdf/1605.07678v3.pdf

2018-11-14 11:23:21 alicelmx 阅读数 768
  • 深度学习中基础模型性能的思考和优化

    深度学习基础模型性能思考和优化教学视频,从基本图像模型出发,介绍模型优化的基本思路,使用并联模型和一般剪枝提高模型精确度,使用剪枝优化模型精确度,以及其他需要注意的问题。可以和图书《深度学习算法实践》中部分内容互相参看。

    1273 人正在学习 去看看 CSDN讲师

摘要

最近又开始混乱且忙碌的科研学习,双十一过后,钱包空了,就再不想买买买了,打比赛的议程又提上来了,首先给大家分享两个非常非常非常好的repo,昨天晚上才发现的,又请教了一个博士点经验,踏踏实实准备,浮躁的心就能沉淀下来~

更新最新最全的算法比赛信息:https://github.com/iphysresearch/DataSciComp
各种比赛的top解决方案:https://github.com/Smilexuhc/Data-Competition-TopSolution

一定要多交流多交流,算法岗没有想想的这么难的!
这个就相当于作文模板,稍微改改就能拿来使用啦~

Preprocess

# 通用的预处理框架

import pandas as pd
import numpy as np
import scipy as sp

# 文件读取
def read_csv_file(f, logging=False):
    print("==========读取数据=========")
    data =  pd.read_csv(f)
    if logging:
        print(data.head(5))
        print(f, "包含以下列")
        print(data.columns.values)
        print(data.describe())
        print(data.info())
    return data

Logistic Regression

# 通用的LogisticRegression框架

import pandas as pd
import numpy as np
from scipy import sparse
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

# 1. load data
df_train = pd.DataFrame()
df_test  = pd.DataFrame()
y_train = df_train['label'].values

# 2. process data
ss = StandardScaler()


# 3. feature engineering/encoding
# 3.1 For Labeled Feature
enc = OneHotEncoder()
feats = ["creativeID", "adID", "campaignID"]
for i, feat in enumerate(feats):
    x_train = enc.fit_transform(df_train[feat].values.reshape(-1, 1))
    x_test = enc.fit_transform(df_test[feat].values.reshape(-1, 1))
    if i == 0:
        X_train, X_test = x_train, x_test
    else:
        X_train, X_test = sparse.hstack((X_train, x_train)), sparse.hstack((X_test, x_test))

# 3.2 For Numerical Feature
# It must be a 2-D Data for StandardScalar, otherwise reshape(-1, len(feats)) is required
feats = ["price", "age"]
x_train = ss.fit_transform(df_train[feats].values)
x_test  = ss.fit_transform(df_test[feats].values)
X_train, X_test = sparse.hstack((X_train, x_train)), sparse.hstack((X_test, x_test))

# model training
lr = LogisticRegression()
lr.fit(X_train, y_train)
proba_test = lr.predict_proba(X_test)[:, 1]

LightGBM

1. 二分类

import lightgbm as lgb
import pandas as pd
import numpy as np
import pickle
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split

print("Loading Data ... ")

# 导入数据
train_x, train_y, test_x = load_data()

# 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置
X, val_X, y, val_y = train_test_split(
    train_x,
    train_y,
    test_size=0.05,
    random_state=1,
    stratify=train_y ## 这里保证分割后y的比例分布与原数据一致
)

X_train = X
y_train = y
X_test = val_X
y_test = val_y


# create dataset for lightgbm
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
# specify your configurations as a dict
params = {
    'boosting_type': 'gbdt',
    'objective': 'binary',
    'metric': {'binary_logloss', 'auc'},
    'num_leaves': 5,
    'max_depth': 6,
    'min_data_in_leaf': 450,
    'learning_rate': 0.1,
    'feature_fraction': 0.9,
    'bagging_fraction': 0.95,
    'bagging_freq': 5,
    'lambda_l1': 1,  
    'lambda_l2': 0.001,  # 越小l2正则程度越高
    'min_gain_to_split': 0.2,
    'verbose': 5,
    'is_unbalance': True
}

# train
print('Start training...')
gbm = lgb.train(params,
                lgb_train,
                num_boost_round=10000,
                valid_sets=lgb_eval,
                early_stopping_rounds=500)

print('Start predicting...')

preds = gbm.predict(test_x, num_iteration=gbm.best_iteration)  # 输出的是概率结果

# 导出结果
threshold = 0.5
for pred in preds:
    result = 1 if pred > threshold else 0

# 导出特征重要性
importance = gbm.feature_importance()
names = gbm.feature_name()
with open('./feature_importance.txt', 'w+') as file:
    for index, im in enumerate(importance):
        string = names[index] + ', ' + str(im) + '\n'
        file.write(string)

2. 多分类

import lightgbm as lgb
import pandas as pd
import numpy as np
import pickle
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split

print("Loading Data ... ")

# 导入数据
train_x, train_y, test_x = load_data()

# 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置
X, val_X, y, val_y = train_test_split(
    train_x,
    train_y,
    test_size=0.05,
    random_state=1,
    stratify=train_y ## 这里保证分割后y的比例分布与原数据一致
)

X_train = X
y_train = y
X_test = val_X
y_test = val_y


# create dataset for lightgbm
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
# specify your configurations as a dict
params = {
    'boosting_type': 'gbdt',
    'objective': 'multiclass',
    'num_class': 9,
    'metric': 'multi_error',
    'num_leaves': 300,
    'min_data_in_leaf': 100,
    'learning_rate': 0.01,
    'feature_fraction': 0.8,
    'bagging_fraction': 0.8,
    'bagging_freq': 5,
    'lambda_l1': 0.4,
    'lambda_l2': 0.5,
    'min_gain_to_split': 0.2,
    'verbose': 5,
    'is_unbalance': True
}

# train
print('Start training...')
gbm = lgb.train(params,
                lgb_train,
                num_boost_round=10000,
                valid_sets=lgb_eval,
                early_stopping_rounds=500)

print('Start predicting...')

preds = gbm.predict(test_x, num_iteration=gbm.best_iteration)  # 输出的是概率结果

# 导出结果
for pred in preds:
    result = prediction = int(np.argmax(pred))

# 导出特征重要性
importance = gbm.feature_importance()
names = gbm.feature_name()
with open('./feature_importance.txt', 'w+') as file:
    for index, im in enumerate(importance):
        string = names[index] + ', ' + str(im) + '\n'
        file.write(string)

XGBoost

1. 二分类

import numpy as np
import pandas as pd
import xgboost as xgb
import time
from sklearn.model_selection import StratifiedKFold


from sklearn.model_selection import train_test_split
train_x, train_y, test_x = load_data()

# 构建特征


# 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置
X, val_X, y, val_y = train_test_split(
    train_x,
    train_y,
    test_size=0.01,
    random_state=1,
    stratify=train_y
)

# xgb矩阵赋值
xgb_val = xgb.DMatrix(val_X, label=val_y)
xgb_train = xgb.DMatrix(X, label=y)
xgb_test = xgb.DMatrix(test_x)

# xgboost模型 #####################

params = {
    'booster': 'gbtree',
    # 'objective': 'multi:softmax',  # 多分类的问题、
    # 'objective': 'multi:softprob',   # 多分类概率
    'objective': 'binary:logistic',
    'eval_metric': 'logloss',
    # 'num_class': 9,  # 类别数,与 multisoftmax 并用
    'gamma': 0.1,  # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。
    'max_depth': 8,  # 构建树的深度,越大越容易过拟合
    'alpha': 0,   # L1正则化系数
    'lambda': 10,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
    'subsample': 0.7,  # 随机采样训练样本
    'colsample_bytree': 0.5,  # 生成树时进行的列采样
    'min_child_weight': 3,
    # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
    # ,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
    # 这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
    'silent': 0,  # 设置成1则没有运行信息输出,最好是设置为0.
    'eta': 0.03,  # 如同学习率
    'seed': 1000,
    'nthread': -1,  # cpu 线程数
    'missing': 1,
    'scale_pos_weight': (np.sum(y==0)/np.sum(y==1))  # 用来处理正负样本不均衡的问题,通常取:sum(negative cases) / sum(positive cases)
    # 'eval_metric': 'auc'
}
plst = list(params.items())
num_rounds = 2000  # 迭代次数
watchlist = [(xgb_train, 'train'), (xgb_val, 'val')]

# 交叉验证
result = xgb.cv(plst, xgb_train, num_boost_round=200, nfold=4, early_stopping_rounds=200, verbose_eval=True, folds=StratifiedKFold(n_splits=4).split(X, y))

# 训练模型并保存
# early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练
model = xgb.train(plst, xgb_train, num_rounds, watchlist, early_stopping_rounds=200)
model.save_model('../data/model/xgb.model')  # 用于存储训练出的模型

preds = model.predict(xgb_test)

# 导出结果
threshold = 0.5
for pred in preds:
    result = 1 if pred > threshold else 0

Keras

1. 二分类

import numpy as np
import pandas as pd
import time
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as plt

from keras.models import Sequential
from keras.layers import Dropout
from keras.layers import Dense, Activation
from keras.utils.np_utils import to_categorical

# coding=utf-8
from model.util import load_data as load_data_1
from model.util_combine_train_test import load_data as load_data_2
from sklearn.preprocessing import StandardScaler # 用于特征的标准化
from sklearn.preprocessing import Imputer

print("Loading Data ... ")
# 导入数据
train_x, train_y, test_x = load_data()

# 构建特征
X_train = train_x.values
X_test  = test_x.values
y = train_y

imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
X_train = imp.fit_transform(X_train)

sc = StandardScaler()
sc.fit(X_train)
X_train = sc.transform(X_train)
X_test  = sc.transform(X_test)


model = Sequential()
model.add(Dense(256, input_shape=(X_train.shape[1],)))
model.add(Activation('tanh'))
model.add(Dropout(0.3))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.3))
model.add(Dense(512))
model.add(Activation('tanh'))
model.add(Dropout(0.3))
model.add(Dense(256))
model.add(Activation('linear'))
model.add(Dense(1)) # 这里需要和输出的维度一致
model.add(Activation('sigmoid'))

# For a multi-class classification problem
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

epochs = 100
model.fit(X_train, y, epochs=epochs, batch_size=2000, validation_split=0.1, shuffle=True)

# 导出结果
threshold = 0.5
for index, case in enumerate(X_test):
    case =np.array([case])
    prediction_prob = model.predict(case)
    prediction = 1 if prediction_prob[0][0] > threshold else 0

2. 多分类

import numpy as np
import pandas as pd
import time
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as plt

from keras.models import Sequential
from keras.layers import Dropout
from keras.layers import Dense, Activation
from keras.utils.np_utils import to_categorical

# coding=utf-8
from model.util import load_data as load_data_1
from model.util_combine_train_test import load_data as load_data_2
from sklearn.preprocessing import StandardScaler # 用于特征的标准化
from sklearn.preprocessing import Imputer

print("Loading Data ... ")
# 导入数据
train_x, train_y, test_x = load_data()

# 构建特征
X_train = train_x.values
X_test  = test_x.values
y = train_y

# 特征处理
sc = StandardScaler()
sc.fit(X_train)
X_train = sc.transform(X_train)
X_test  = sc.transform(X_test)
y = to_categorical(y) ## 这一步很重要,一定要将多类别的标签进行one-hot编码


model = Sequential()
model.add(Dense(256, input_shape=(X_train.shape[1],)))
model.add(Activation('tanh'))
model.add(Dropout(0.3))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.3))
model.add(Dense(512))
model.add(Activation('tanh'))
model.add(Dropout(0.3))
model.add(Dense(256))
model.add(Activation('linear'))
model.add(Dense(9)) # 这里需要和输出的维度一致
model.add(Activation('softmax'))

# For a multi-class classification problem
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

epochs = 200
model.fit(X_train, y, epochs=epochs, batch_size=200, validation_split=0.1, shuffle=True)

# 导出结果
for index, case in enumerate(X_test):
    case = np.array([case])
    prediction_prob = model.predict(case)
    prediction = np.argmax(prediction_prob)

处理正负样本不均匀的案例

有些案例中,正负样本数量相差非常大,数据严重unbalanced,这里提供几个解决的思路

# 计算正负样本比例
positive_num = df_train[df_train['label']==1].values.shape[0]
negative_num = df_train[df_train['label']==0].values.shape[0]
print(float(positive_num)/float(negative_num))

主要思路

1. 手动调整正负样本比例
2. 过采样 Over-Sampling

对训练集里面样本数量较少的类别(少数类)进行过采样,合成新的样本来缓解类不平衡,比如SMOTE算法

3. 欠采样 Under-Sampling
4. 将样本按比例一一组合进行训练,训练出多个弱分类器,最后进行集成

框架推荐

Github上大神写的相关框架,专门用来处理此类问题:
https://github.com/scikit-learn-contrib/imbalanced-learn

2018-10-03 21:56:07 weixin_42749767 阅读数 5113
  • 深度学习中基础模型性能的思考和优化

    深度学习基础模型性能思考和优化教学视频,从基本图像模型出发,介绍模型优化的基本思路,使用并联模型和一般剪枝提高模型精确度,使用剪枝优化模型精确度,以及其他需要注意的问题。可以和图书《深度学习算法实践》中部分内容互相参看。

    1273 人正在学习 去看看 CSDN讲师

背景


最近实验室要参加一个目标检测的比赛,这段时间一直在跑ssd模型,最开始根据作者给的文档成功编译后,可以在VOC数据集上进行训练。由于要用比赛官方的数据集,因此做了几天的数据集,然后拿自己的数据集训练的时候,出现了以下报错:Check failed: a <= b (0 vs. -1.192093-07)

在这里插入图片描述

去网上搜了相关的解决方法,全都是说把math_functions.cpp第250行注释掉,重新编译,这种方案一看就不靠谱,而且也没人说个所以然,但是还是抱着试一试的心态照做了,果然又出现了新的bug。查了几天的资料也没找到解决方案,一开始我怀疑可能是我的数据集做的有问题,然后我又重新在VOC数据集上训练,结果会出现同样的问题,联想到前两天实验室服务器重装了系统,然后cuda从8.0换到了9.1版本,会不会是这个原因导致了现在的报错呢?但是因为实验室服务器是大家共用的,把cuda改回到8.0版本可能给其他人带来困扰,刚好实验室有其他同学在搞nvidia docker,干脆直接用nvidia docker来跑模型,就不用考虑环境问题了。

什么是nvidia docker


介绍nvidia docker之前,首先要了解什么是docker。

Docker 是一个开源的应用容器引擎,基于 GO语言并遵从Apache2.0协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,可以实现虚拟化。

Docker所代表的容器虚拟化技术属于操作系统级虚拟化:内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。并且传统虚拟化技术是在硬件层面实现虚拟化,增加了系统调用链路的环节,有性能损耗;容器虚拟化技术以共享Kernel的方式实现,几乎没有性能损耗。

这里可以将容器理解为一种沙盒。每个容器内运行一个应用,不同的容器相互隔离,容器之间可以建立通信机制。容器的创建和停止都十分快速(秒级),容器自身对资源的需求十分有限,远比虚拟机本身占用的资源少。

关于Docker更详细的介绍,请参照几张图帮你理解docker基本原理及快速入门,感觉介绍的很不错

docker一般服务于基于cpu 的应用,而我们的深度学习模型是跑在gpu上面的,因此需要用nvidia docker。nvidia docker的运行需要基于一定的硬件环境,需要安装nvidia driver,docker容器本身并不支持nvidia gpu。最开始的解决方法是在容器内部安装nvidia driver,然后通过设置相应的设备参数来启动container,但是这样做带来一个弊端就是可能导致image无法共享,因为宿主机的driver的版本必须完全匹配容器内的driver版本,很可能本地机器的不一致导致每台机器都需要去重复操作,这很大的违背了docker的初衷。nvidia docker实际上是一个docker plugin,它在docker上做了一层封装,对docker进行调用,类似一个守护进程,发现宿主机驱动文件以及gpu 设备,并且将这些挂载到来自docker守护进程的请求中,以此来支持docker gpu的使用。

安装docker


  1. GPU driver安装

nvidia官网下载安装对应型号的显卡驱动:链接
如果安装成功,在终端中输入 lspci | grep -i nvidia ,会显示自己的NVIDIA GPU版本信息

  1. CUDA安装

实验室服务器是ubuntu 18.04版本,可以直接sudo apt install nvidia-cuda-toolkit安装

  1. docker安装
  • 安装必要的一些系统工具
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
  • 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  • 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  • 更新并安装 docker-ce
sudo apt-get -y update
sudo apt-get -y install docker-ce
  • 验证
sudo service docker status 			#或者sudo systemctl status service.docker 检查Docker服务的状态 
sudo docker run hello-world			#测试Docker安装是否成功

在这里插入图片描述
在这里插入图片描述

  1. nvidia-docker安装
  • 如果之前安装过docker1.0版本,需要先删掉该版本和之前创建的容器
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker
  • 添加代码仓库
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
  • 安装docker 2
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd
  • 测试
docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
  1. 安装过程中遇到的问题

网上有的教程会设置阿里云加速器,是因为官方Docker Hub网络速度较慢,所以使用阿里云提供的Docker Hub,然后需要配置阿里云加速器。具体步骤如下:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’ 
{ 
   “registry-mirrors”: [“https://fird1mfg.mirror.aliyuncs.com“] 
} 
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

结果我在重启docker服务的时候,产生了如下报错:

docker.service - LSB: Create lightweight, portable, self-sufficient containers
Loaded: loaded (/etc/init.d/docker; generated)
Active: failed (Result: exit-code) since Wed 2018-09-26 10:11:16 CST; 28s ago
Docs: man:systemd-sysv-generator(8)
Process: 18639 ExecStart=/etc/init.d/docker start (code=exited, status=1/FAILULURE)
Main PID: 15621 (code=exited, status=1/FAILURE)

9月 26 10:11:16 archlab-X10DRG systemd[1]: Starting LSB: Create lightweight, portable, self-sufficient containers....
9月 26 10:11:16 archlab-X10DRG docker[18639]:  * /usr/bin/dockerd not present or not executable
9月 26 10:11:16 archlab-X10DRG systemd[1]: docker.service: Control process exited, code=exited status=1
9月 26 10:11:16 archlab-X10DRG systemd[1]: docker.service: Failed with result 'exit-code'.
9月 26 10:11:16 archlab-X10DRG systemd[1]: Failed to start LSB: Create lightweight, portable, self-sufficient containers

根绝报错的第二行,发现是dockerd除了问题,dockerd是docker的守护进程,现在提示不存在或不可用,然后我执行了sudo dockerd,打印出了以下报错信息

unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character ‘h’ after object key

这说明docker的配置文件除了问题,打开daemon.json文件,果然发现刚才设置阿里云加速器的时候,写入的语句有问题,应该是我直接复制粘贴导致的问题,改正之后docker服务可以正常启动了。

用nvidia docker进行训练


  1. 拉取镜像(这里拉取了阿里云的一个镜像,里面自带了编译好的caffe,不过由于在实验室的宿主机上已经有编译好的caffe,可以直接将宿主机的目录挂载到容器中,这个后面有说)
sudo nvidia-docker pull registry.cn-hangzhou.aliyuncs.com/docker_learning_aliyun/caffe:v1
  1. 查看拉取的镜像信息
sudo nvidia-docker images

在这里插入图片描述

  1. 利用拉取的镜像启动容器,并把宿主机的caffe目录挂载到容器上
sudo nvidia-docker run -it –v $CAFFE_ROOT:/workspace 4e33(镜像id前4位即可)/bin/bash

这样就启动了一个容器,并且把caffe目录挂载到了容器的/workspace下。这样操作的好处是,训练完的数据可以直接存放在宿主机,省略了从容器中拷贝的繁琐步骤。

剩下的就是将caffe模型跑起来等待结果就可以了。

2019-12-06 12:58:45 weixin_42137700 阅读数 16
  • 深度学习中基础模型性能的思考和优化

    深度学习基础模型性能思考和优化教学视频,从基本图像模型出发,介绍模型优化的基本思路,使用并联模型和一般剪枝提高模型精确度,使用剪枝优化模型精确度,以及其他需要注意的问题。可以和图书《深度学习算法实践》中部分内容互相参看。

    1273 人正在学习 去看看 CSDN讲师

文/编辑 | 言有三

自从Google提出AutoML技术以来,已经过去了好几年了,如今在学术界和工业界都是热点。AutoML在网络结构的搜索上已经取得了非常多的突破,相关的文章,技术博客都已经广为流传,那么除了在网络结构本身的搜索上,AutoML技术对于深度学习模型的优化还有哪些贡献呢?本文就来简要总结这个问题。

1 数据增强

数据增强是深度学习模型训练的必备良药,写论文刷比赛提指标的大杀器。传统的数据增强方法以各类通过参数控制的预设几何变换和颜色变换为主,如果让模型针对具体的任务自动学习数据增强,理论上会更加智能,这便是基于AutoML的数据增强技术,它主要是用于自动学习数据增强策略,包括选择哪一个操作,什么时候应用该操作。

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与数据增强

「AutoML」如何选择最合适的数据增强操作

2 激活函数

激活机制是一个网络非线性表达能力的来源,早期研究人员已经设计出了不少的激活函数,从sigmoid到relu系列,随着AutoML技术的发展,现在研究人员开始使用搜索技术来进行设计,提出了Swish及更多的变种

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与激活函数

「AutoML」激活函数如何进行自动学习和配置

3 归一化方法

数据经过归一化和标准化后可以加快梯度下降的求解速度,这是Batch Normalization等技术非常流行的原因,它使得可以使用更大的学习率更稳定地进行梯度传播,甚至增加网络的泛化能力。当前归一化方法非常多,那怎么选择呢?每一个网络层中都使用同样的归一化,这是最优的配置吗?不如交给AutoML来自动配置。

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与归一化

「AutoML」归一化(Normalization)方法如何进行自动学习和配置

4 优化方法

要成功训练一个深度学习模型,正确的优化策略是非常重要的,如果使用不当结果会产生很大的差异,然而要熟练使用,需要大量的工程经验和深厚的理论基础,那么能不能使用AutoML来减轻这个负担呢?

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与优化方法

「AutoML」优化方法可以进行自动搜索学习吗?

5 优化目标

一个有效的损失函数在深度学习任务中起了关键作用,然而损失函数都是人为设定,不仅需要有经验的人员进行反复尝试,也往往只能获得次优的方案,如果可以让模型自动对优化目标进行学习,将有望以更低的成本学习到更优的模型。

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与优化目标

「AutoML」损失函数也可以进行自动搜索学习吗?

6 模型剪枝

我们给大家介绍过各种各样的模型压缩技巧,其中模型剪枝是一个研究已久,也非常考验工程素质的方向,那能否使用AutoML技术来进行剪枝呢?

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与模型剪枝

「AutoML」如何使用强化学习进行模型剪枝?

7 模型量化

模型量化是深度学习模型压缩的大杀器,当前大部分框架对整个模型采用同样的位宽进行量化,以HAQ(Hardware-Aware Automated Quantization with Mixed Precision)为代表的方法则是一个自动化的混合精度量化框架,使用AutoML技术让每一层都学习到了适合该层的量化位宽,又有什么优势呢?

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

AutoML与模型量化

「AutoML」强化学习如何用于模型量化?

8 更多模型设计与优化内容

我们公众号最多的就是模型设计相关的内容,包括主流的模型设计思想,三次长达一个小时的阿里天池模型设计直播,知识星球的网络结构1000变板块,感兴趣的粉丝可以自取。

除了网络搜索(NAS),AutoML对深度学习模型优化还有哪些贡献?

主流模型设计

没有更多推荐了,返回首页