精华内容
下载资源
问答
  • 最近在学习cs231n相关的...文章目录优化网络方法框图数据预处理部分权重初始化部分批量归一化部分优化方法部分激活函数部分正则化和超参设置部分 优化网络方法框图 数据预处理部分 权重初始化部分 批量归一化部...

    最近在学习cs231n相关的课程,在进入下一阶段前,想对学习进行一下归纳整理。一方面强制让自己进行回忆和复习,另一方面从全局上换个角度来学习这些知识,也方便以后查阅。由于思维导图比较大,后文会拆分成不同的部分依次放出。

    优化网络方法框图

    在这里插入图片描述

    数据预处理部分

    在这里插入图片描述

    权重初始化部分

    在这里插入图片描述

    批量归一化部分

    在这里插入图片描述

    优化方法部分

    在这里插入图片描述

    激活函数部分

    在这里插入图片描述

    正则化和超参设置部分

    在这里插入图片描述

    展开全文
  • 机器学习的目标是给出一个模型(一般是映射函数),然后定义对这个模型好坏的...第三个问题是纯数学问题,即最优化方法。 机器学习要求解的数学模型 1.监督学习:目标函数的极值 对于监督学习,我们要找到一...

    机器学习的目标是给出一个模型(一般是映射函数),然后定义对这个模型好坏的评价函数(目标函数),求解目标函数的极大值或者极小值,以确定模型的参数,从而得到我们想要的模型。

    在这三个关键步骤(定义模型,目标函数,求解极值)中,前两个是机器学习要研究的问题,建立数学模型。第三个问题是纯数学问题,即最优化方法。

    机器学习要求解的数学模型

    1.有监督学习:目标函数的极值

    对于有监督学习,我们要找到一个最佳的映射函数f(x),使得对训练样本的损失函数最小化。

    N为训练样本数,L是对单个样本的损失函数,w是要求解的模型参数,是映射函数的参数, [公式] 为样本的特征向量, [公式] 为样本的标签值。

    2.有监督学习:最大似然估计

    或是找到一个最优的概率密度函数p(x),使得对训练样本的对数似然函数极大化(最大似然估计):

     [公式] 是要求解的模型参数,是概率密度函数的参数。

    3.无监督学习

    以聚类算法为例,算法求解每个类的样本离类中心的距离之和最小化:

    在这里k为类型数,x为样本向量, [公式] 为类中心向量, [公式] 为第i个类的样本集合。

    4.强化学习

    找到一个最优的策略,即状态s到动作a的映射函数(确定性策略,对于非确定性策略,是执行每个动作的概率):

    使得任意给定一个状态,执行这个策略函数所确定的动作a之后,得到的累计回报最大化:

    这里使用的是状态价值函数。

    最优化算法的分类

    好的优化算法需要满足:能正确的找到各种情况下的极值点,并且速度快。优化算法分成两种类型:公式解,数值优化。前者给出一个最优化问题精确的公式解,也称为解析解,一般是理论结果。后者是在要给出极值点的精确计算公式非常困难的情况下,用数值计算方法近似求解得到最优点。

    下图给出了这些算法的分类与它们之间的关系:

    公式解算法

    费马定理

    对于一个可导函数,寻找其极值的统一做法是寻找导数为0的点,即费马定理。

    对于多元函数,则是梯度为0:

    导数为0只是函数取得极值的必要条件而不是充分条件,它只是疑似极值点。是不是极值,是极大值还是极小值,还需要看更高阶导数。

    对于一元函数,假设x是驻点:

    1.如果 [公式] (x)>0,则在该点处去极小值

    2.如果 [公式] (x)<0,则在该点处去极大值

    3.如果 [公式] (x)=0,还要看更高阶导数

    对于多元函数,假设x是驻点:

    1.如果Hessian矩阵所有特征值均大于0,矩阵正定,函数在该点有极小值

    2.如果Hessian矩阵所有特征值均小于0,矩阵负定,函数在该点有极大值

    3.如果Hessian矩阵所有特征值均等于0,矩阵不定,则不是极值点

    注意:

    1.鞍点:在导数为0的点,函数可能不取极值

    2.局部极值:一个驻点是极值点,但不是全局极值

    如果我们对最优化问题加以限定,可以有效的避免这两种问题。典型的是凸优化,它要求优化变量的可行域是凸集,目标函数是凸函数。

    拉格朗日乘数法

    对于带等式约束的极值问题,经典的解决方案是拉格朗日乘数法。

    构造拉格朗日乘子函数:

    在最优点处对x和乘子变量 [公式] 的导数都必须为0:

    机器学习中用到拉格朗日乘数法的地方有:主成分分析、线性判别分析、流形学习中的拉普拉斯特征映射、隐马尔可夫模型。

    KKT条件

    KKT条件是拉格朗日乘数法的推广,用于求解既带有等式约束,又带有不等式约束的函数极值。对于如下优化问题:

    KKT条件构如下乘子函数:

    [公式][公式] 称为KKT乘子。在最优解处 [公式] 应该满足如下条件:

    等式约束 [公式] ( [公式] )=0和不等式约束 [公式] ( [公式] ) [公式] 0是本身应该满足的约束, [公式]L( [公式] )=0和之前的拉格朗日乘数法一样。唯一多了关于 [公式] (x)的条件:

    在机器学习中用到KKT条件的地方有:支持向量机(SVM)。

     

    数值优化算法:一阶优化算法

    对绝大多数函数来说,梯度等于0的方程组是没法直接解出来的,如方程里面含有指数函数、对数函数之类的超越函数,我们只能求解近似解。如果采用目标函数的一阶导数,则称为一阶优化算法。如果使用了目标函数的二阶导数,则称为二阶优化算法。

    工程上实现时通常采用的是迭代法,它从一个初始点 [公式] 开始,反复使用某种规则从 [公式] 移动到下一个点 [公式] ,构造这样一个数列,直到收敛到梯度为0的点处。即有下面的极限成立:

    利用一阶导数信息即梯度,或者二阶导数信息即Hessian矩阵。这样迭代法的核心是得到这样的由上一个点确定下一个点的迭代公式:

    梯度下降法(又称为最速下降法)

    梯度下降法的优化思想是用当前位置负梯度方向作为搜索方向,因为该方向为当前位置的最快下降方向,所以也被称为是”最速下降法“。最速下降法越接近目标值,步长越小,前进越慢。利用了函数的一阶导数信息:

    学习率 [公式] 设置为一个非常小的正数,保证迭代之后的 [公式] 位于迭代之前的值 [公式] 的邻域内,从而可以忽略泰勒展开中的高次项,保证迭代时函数值下降。

    缺点:梯度下降法的收敛取决于设置的学习率的大小,太小则收敛慢,太大则不收敛。

    梯度下降法及其变种的应用:深度学习。

    动量项

    优点:加快梯度下降法的收敛速度,减少震荡。

    动量项累积了之前迭代时的梯度值,迭代时沿着之前的惯性方向向前走,加上此项之后的参数更新公式为:

    其中 [公式] 是动量项,它取代了之前的梯度项。动量项的计算公式为:

    其中 [公式] 是学习率, [公式] 是动量项系数,t时刻的动量项与t+1时刻的梯度值的加权平均值。按照时间t进行展开,则第t次迭代时使用了从1到t次迭代时的所有梯度值, [公式] 系数呈指数级衰减:

    AdaGrad算法

    AdaGrad算法是梯度下降法最直接的改进。

    AdaGrad算法根据前几轮迭代时的历史梯度值动态调整学习率,且优化变量向量x的每一个分量 [公式] 都有自己的学习率。参数更新公式为:

    [公式] 是学习率, [公式] 是第t次迭代时参数的梯度向量, [公式] 是一个很小的正数,为了避免除0操作,下标i表示向量的分量。

    和标准梯度下降法唯一不同的是多了分母中的这一项,它累积了到本次迭代为止梯度的历史值信息用于生成梯度下降的系数值。历史导数值的绝对值越大,分量学习率越小。

    优点:自动变更学习率,(学习率)与(以往参数模和的开方)成反比

    缺点:需要人工指定的全局学习率 [公式],长期累积梯度值,分母会越来越大,导致学习率趋向于0,参数无法有效更新。

    RMSProp算法

    RMSProp算法是对AdaGrad的改进。

    由梯度值构造一个向量RMS,初始化为0,按照衰减系数累积了历史的梯度平方值。更新公式为:

    AdaGrad直接累加所有历史梯度的平方和,而这里将历史梯度平方值按照 [公式] 衰减之后再累加。参数更新公式为:

    其中 [公式] 是人工设定的参数,与AdaGrad一样,这里也需要人工指定的全局学习率 [公式]

    优点:缓解学习率下降较快(AdaGrad)

    缺点:需要人工指定的全局学习率 [公式]

    AdaDelta算法

    AdaDelta算法也是对AdaGrad的改进,避免了长期累积梯度值所导致的学习率趋向于0的问题,另外,还去掉了对人工设置的全局学习率的依赖。

    假设要优化的参数为x,梯度下降法第t次迭代时计算出来的参数梯度值为 [公式] 。算法首先初始化如下两个向量为0向量:

    其中E[ [公式] ]是梯度平方(对每个分量分别平分)的累计值,更新公式为:

    [公式] 是向量每个元素分别计算平方,后面所有的计算公式都是对向量的每个分量进行。接下来计算如下RMS量:

    计算参数的更新值:

    RMS [公式] 的计算公式和这个类似。这个更新值同样通过梯度来构造,只不过学习率是通过梯度的历史值确定的。更新公式为:

    参数更新的迭代公式为:

    优点:避免了长期累积梯度值所导致的学习率趋向于0的问题,去掉了人工设置的全局学习率的依赖。

    Adam算法

    Adam算法整合了自适应学习率v(累积了梯度的平方和)与动量项m。它们的初始值为0,更新公式为:

    其中 [公式][公式] 是人工指定的参数,i为向量的分量下标。依靠这两个值构造参数的更新值,参数的更新公式为:

    优点:利用一阶矩估计和二阶矩估计来动态调整每个参数的学习率,偏置校正后,学习率的迭代有范围,较为平稳。

    随机梯度下降法、批量梯度下降

    基于梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。

    为了降低计算成本,批量随机梯度下降法在每次迭代中使用随机逼近值,即只使用M个随机选择的样本来近似计算损失函数。在每次迭代时要优化的目标函数为:

    L(w, [公式] , [公式] )是对单个训练样本( [公式] , [公式] )的损失函数,w是需要学习的参数,r(w)是正则化项, [公式] 是正则化项的权重。

    随机梯度下降法在概率意义下收敛。

     

    数值优化算法:二阶优化算法

    牛顿法

    牛顿法利用了函数的一阶和二阶导数信息,直接寻找梯度为0的点。牛顿法的迭代公式为:

    其中H为Hessian矩阵,g为梯度向量。学习率 [公式] 设置为一个非常小的正数,通常采用直线搜索(line search)技术,保证迭代之后的 [公式] 位于迭代之前的值 [公式] 的邻域内,从而可以忽略泰勒展开中的高次项,保证迭代时函数值下降。

    在实现时,一般不直接求Hessian矩阵的逆矩阵,而是求解下面的线性方程组:

    其解d称为牛顿方向。迭代终止的判定依据是梯度值充分接近于0,或者达到最大指定迭代次数。

    应用:logistic回归,AdaBoost算法

    优点:比梯度下降法有更快的收敛速度,收敛速度快,迭代次数少

    缺点:不能保证每次迭代时函数值下降;也不能保证收敛到极小值点;靠近极小值时收敛速度减慢,可能会“之字形”地下降;需要设置学习率(line search);Hessian矩阵很稠密时,每次迭代计算Hessian矩阵的计算量很大,随着数据规模增大,Hessian矩阵也会变大,需要更多的存储空间以及计算量;Hessian矩阵不可逆则该方法失效。

     

    拟牛顿法

    构造一个近似Hessian矩阵或其逆矩阵的正定对称矩阵,用该矩阵进行牛顿法的迭代。

    引入了Hessian矩阵的近似矩阵,避免了每次都计算Hessian矩阵的逆,在拟牛顿法中搜索,用Hessian矩阵的逆矩阵来代替Hessian矩阵,虽然不能像牛顿法那样保证最优化的方向,但其逆矩阵始终是正定的,因此算法始终朝最优化的方向。

    优点:构造近似Hessian矩阵逆的矩阵

    可信域牛顿法

    调整牛顿方向的步长来实现收敛到最优解和序列递减,目前常用的方法有两种:直线搜索和可信区域法。可信域牛顿法是截断牛顿法的一个变种,用于求解带界限约束的最优化问题。在可信域牛顿法的每一步迭代中,有一个迭代序列 [公式] ,一个可信域的大小 [公式] ,以及一个二次目标函数:

    这个式子可以通过泰勒展开得到,忽略二次以上的项,这是对函数下降值的近似:

    算法寻找一个 [公式] ,在满足约束条件丨丨s丨丨 [公式][公式] 下近似最小化 [公式] (s)。接下来检查比值以更新 [公式][公式]

    [公式][公式] 是函数值的实际减少量和二次近似模型预测方向导致的函数减少量的比值。根据之前的计算结果,再动态调整可信域的大小。

    应用:logistic回归,线性支持向量的求解(liblinear开源库)。

     

    求解思想:分治法

    分治法是一种算法设计思想,它将一个大的问题分解成子问题进行求解。根据子问题解构造出整个问题的解。在最优化方法中,具体做法是每次迭代时只调整优化向量x的一部分分量,其他的分量固定住不动。

    坐标下降法

    坐标下降法的基本思想是每次对一个变量进行优化,这是一种分治法。假设要求解的优化问题为:

    坐标下降法求解流程为每次选择一个分量 [公式] 进行优化,将其他分量固定住不动,这样将一个多元函数的极值问题转换为一元函数的极值问题。如果要求解的问题规模很大,这种做法能有效的加快速度。

    应用:logistic回归,线性支持向量的求解(liblinear开源库)。

    SMO算法

    SMO算法也是一种分治法,用于求解支持向量机的对偶问题。加上松弛变量和核函数后的对偶问题为:

    SMO算法的核心思想是每次在优化变量中挑出两个分量 [公式][公式] 进行优化,让其他分量固定即当成常数,这样能保证满足等式约束条件。之所以要选择两个变量进行优化而不是选择一个变量,是因为这里有等式约束,如果只调整一个变量的值,将会破坏等式约束。

    分阶段优化

    分阶段优化的做法是在每次迭代时,先固定住优化变量x一部分分量a不动,对另外一部分变量b进行优化;然后再固定住b不动,对b进行优化。如此反复,直至收敛到最优解处。

    AdaBoost算法是这种方法的典型代表。AdaBoost算法在训练时采用了指数损失函数:

    由于强分类器是多个弱分类器f的加权和,代入上面的损失函数中,得到算法训练时要优化的目标函数为:

    指数损失函数包含已有的强分类器 [公式] 和当前弱分类器f对训练样本的损失函数。把强分类器看作常数,目标函数简化为:

    分两步求解,首先将弱分类器权重 [公式] 看成常数,得到最优的弱分类器f。得到弱分类器之后,再优化它的权重系数 [公式]

    动态规划算法

    将一个问题分解成子问题求解,如果整个问题的某个解是最优的,则这个解的任意一部分也是子问题的最优解。这样通过求解子问题,得到最优解,逐步扩展,最后得到整个问题的最优解。

    应用:隐马尔可夫模型的解码算法(维特比算法),强化学习中的动态规划算法。

    展开全文
  • Android性能优化常用方法

    千次阅读 2016-01-23 14:28:43
    本篇博客主要介绍关于性能优化的一些方法,以及性能分析工具的使用。     一 性能优化的常用方法 主要内容包括布局优化,绘制...布局优化思想很简单,就是尽量减少布局文件的层级。 如何进行优化呢?首先删


     

    本篇博客主要介绍关于性能优化的一些方法,以及性能分析工具的使用。

     

     

    一 性能优化的常用方法

    主要内容包括布局优化,绘制优化,内存泄露优化,相应速度优化,ListView优化,Bitmap优化,线程优化,以及一些性能优化建议,在介绍相应速度优化的同时,还介绍了ANR的日志分析方法。

     

    (1).布局优化

    布局优化的思想很简单,就是尽量减少布局文件的层级。

    如何进行优化呢?首先删除布局中无用的控件和层级,其次有选择地使用性能较低的ViewGroup,比如LinearLayout。如果布局中有的布局既可以用LinearLayout也可以用RelativeLayout,那就用LinearLayout,这是因为RelativeLayout比较复杂,他的布局过程花费更多的CPU时间。FrameLayoutLinearLayout一样都是一种简单高效的ViewGroup,因此可以考虑使用他们,但是很多时候,单纯的通过一个LinearLayout或者FrameLayout无法实现产品的效果,需要通过嵌套的方式来完成,这种情况建议采用RelativeLayout,因为ViewGroup的嵌套就相当于增加了布局的层级,同样会降低程序的性能。

     布局优化的另一种手段是采用<include>标枪,<merge>标签和ViewStub<include>标签主要用于布局重用,<merge>标签一般和<include>配合使用,它可以减少布局的层级。而ViewStub则提供了按需加载功能,当需要时才将ViewStub中的布局加载到内存,这提高了程序的初始化效率。

     

    (2).绘制方法

    绘制优化是指ViewonDraw方法避免执行大量的操作,这主要有两方面。

    首先,onDraw中不要创建新的布局对象,这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁的gc,降低了程序的执行效率。

    另一方面,onDraw方法中不要做耗时的任务,也不能执行成千上万次循环操作,尽管每次循环都很轻量级,但是大量的循环仍然十分抢占CPU的时间片,这会造成View的绘制过程不流畅。

     

    (3).内存泄露优化

    内存泄露在开发过程中是一个需要重视的问题,但是由于内存泄露问题对开发人员的经验和开发意识要求比较高,因此这是开发人员最容易犯的错误之一。内存泄露的优化分为两个方面,一方面是在开发过程中避免写出内存泄露的代码,另一方面通过一些分析工具比如MAT来找出潜在的内存泄露继而解决。

    常见的内存泄露举例:

    1.静态变量导致内存泄露

    如果我们将activitycontext对象赋值给activity的全局的静态变量。那么就会造成activity无法正常销毁,因为静态变量在引用它。

    2.单例模式导致的内存泄漏

    如果我们再单例模式中实现了观察者模式,监听实现了接口的对象,当我们在Activity中注册了监听方法以后,而没有进行解注册,就会引起内存泄漏。

    3.属性动画导致的内存泄露

    属性动画中有一类无限循环的动画,如果在Activity中播放此类动画而没有在onDestory中停止动画,那么动画会一直播放下去,尽管无法在界面上看到动画效果了,而且这个时候,ActivityView会被动画持有,而View有持有了Activity,最终导致Activity无法释放。

     

    (4).响应速度优化和ANR日志分析

    相应速度优化的核心是避免在主线程中做耗时操作,但是有时候的确有很多耗时操作怎么办?可以将这些好事操作放在线程中去执行,即采用一部的方式去执行。相应速度过慢地体现在Activity的启动画面上,如果在主线程中做太多的事情,会导致Activity启动时出现黑屏的现象,甚至出现ANR。当发生了ANR以后。系统会在/data/anr目录创建一个文件traces.txt,通过分析这个文件,就可以定位ANR的原因。

    (5).ListViewBitmap优化

    ListView的优化很简单,主要分为三个方面:首先采用ViewHolder并避免在getView中执行耗时操作;其次要根据列表的滑动状态来控制任务的执行频率,比如当列表快速滑动时显然是不太适合开启大量的一部任务;最后,可以尝试开启硬件加速来使ListView的滑动更加流畅。

     

     

    Bitmap优化同样比较简单,主要通过BitMapFactory.Options来根据需要对图片进行采样,采样过程主要用到了BitmapFactory.OptionsinSampleSize参数。

     

    (6). 线程优化

    线程优化的思想是采用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销。同时线程池还能有效的控制线程池的最大并发数,避免大量的线程互相抢占系统资源从而导致阻塞现象发生。

     

    (7).关于性能优化的建议

    1.避免黄健过多对象;

    2.不要过多使用枚举,枚举占用的内存空间比整型大一些。

    3.常量使用static final 来修饰。

    4.使用一些Android特有的数据结构,比如SpareArrayPair等,他们都具有更好的性能。

    5.适当使用软引用和弱引用。

    6.采用内存缓存和磁盘缓存

    7.尽量采用静态内部类,这样可以避免潜在的内部类而导致的内存泄漏。

     

     

    二 内存泄露分析之MAT工具

    MAT的全称是Eclipse Memory Analyzer,它是一款强大的内存泄漏分析工具,关于这部分,我不详述了,请自行查找相关文章。

     

     

     

    写了十多篇博客了,以后还该写什么,怎么写,还在考虑,更新进度可能会慢一些。。。

    展开全文
  • 程序优化方法

    千次阅读 2017-05-04 14:05:16
    程序优化方法1.代码优化代码优化一般需要与算法优化同步进行,代码优化主要是涉及到具体的编码技巧。同样的算法与功能,不同的写法也可能让程序效率差异巨大。一般而言,代码优化主要是针对循环结构进行分析处理,...

    程序优化方法

    1.代码优化

    代码优化一般需要与算法优化同步进行,代码优化主要是涉及到具体的编码技巧。同样的算法与功能,不同的写法也可能让程序效率差异巨大。一般而言,代码优化主要是针对循环结构进行分析处理,目前想到的几条原则是:

    a.避免循环内部的乘(除)法以及冗余计算

    这一原则是能把运算放在循环外的尽量提出去放在外部,循环内部不必要的乘除法可使用加法来替代等。如下面的例子,灰度图像数据存在BYTE Img[MxN]的一个数组中,对其子块  (R1至R2行,C1到C2列)像素灰度求和,简单粗暴的写法是:

    int sum = 0; 
    for(int i = R1; i < R2; i++)
    {
        for(int j = C1; j < C2; j++)
        {
            sum += Image[i * N + j];
        }
    }

    但另一种写法:

    int sum = 0;
    BYTE *pTemp = Image + R1 * N;
    for(int i = R1; i < R2; i++, pTemp += N)
    {
        for(int j = C1; j < C2; j++)
        {
            sum += pTemp[j];
        }
    }

    可以分析一下两种写法的运算次数,假设R=R2-R1,C=C2-C1,前面一种写法i++执行了R次,j++和sum+=…这句执行了RC次,则总执行次数为3RC+R次加法,RC次乘法;同  样地可以分析后面一种写法执行了2RC+2R+1次加法,1次乘法。性能孰好孰坏显然可知。

    b.避免循环内部有过多依赖和跳转,使cpu能流水起来

    关于CPU流水线技术可google/baidu,循环结构内部计算或逻辑过于复杂,将导致cpu不能流水,那这个循环就相当于拆成了n段重复代码的效率。

    另外ii值是衡量循环结构的一个重要指标,ii值是指执行完1次循环所需的指令数,ii值越小,程序执行耗时越短。下图是关于cpu流水的简单示意图:

    简单而不严谨地说,cpu流水技术可以使得循环在一定程度上并行,即上次循环未完成时即可处理本次循环,这样总耗时自然也会降低。

    先看下面一段代码:

    for(int i = 0; i < N; i++)
    {
        if(i < 100) a[i] += 5;
        else if(i < 200) a[i] += 10;
        else a[i] += 20;
    }

    这段代码实现的功能很简单,对数组a的不同元素累加一个不同的值,但是在循环内部有3个分支需要每次判断,效率太低,有可能不能流水;可以改写为3个循环,这样循环内部就不  用进行判断,这样虽然代码量增多了,但当数组规模很大(N很大)时,其效率能有相当的优势。改写的代码为:

    for(int i = 0; i < 100; i++)
    {
        a[i] += 5;        
    }
    for(int i = 100; i < 200; i++)
    {
        a[i] += 10;        
    }
    for(int i = 200; i < N; i++)
    {
        a[i] += 20;
    }

    关于循环内部的依赖,见如下一段程序:

    for(int i = 0; i < N; i++)
    {
        int x = f(a[i]);
        int y = g(x);
        int z = h(x,y);
    }

    其中f,g,h都是一个函数,可以看到这段代码中x依赖于a[i],y依赖于x,z依赖于xy,每一步计算都需要等前面的都计算完成才能进行,这样对cpu的流水结构也是相当不利的,尽量避免此类写法。
    c.定点化

    定点化的思想是将浮点运算转换为整型运算,目前在PC上我个人感觉差别还不算大,但在很多性能一般的DSP上,其作用也不可小觑。定点化的做法是将数据乘上一个很大的数后,将  所有运算转换为整数计算。例如某个乘法我只关心小数点后3位,那把数据都乘上10000后,进行整型运算的结果也就满足所需的精度了。

    d.以空间换时间

    空间换时间最经典的就是查表法了,某些计算相当耗时,但其自变量的值域是比较有限的,这样的情况可以预先计算好每个自变量对应的函数值,存在一个表格中,每次根据自变量的  值去索引对应的函数值即可。如下例:

    //直接计算
    for(int i = 0 ; i < N; i++)
    {
        double z = sin(a[i]);
    }
    
    //查表计算
    double aSinTable[360] = {0, ..., 1,...,0,...,-1,...,0};
    for(int i = 0 ; i < N; i++)
    {
        double z = aSinTable[a[i]];
    }

    后面的查表法需要额外耗一个数组double aSinTable[360]的空间,但其运行效率却快了很多很多。

    e.预分配内存

    预分配内存主要是针对需要循环处理数据的情况的。比如视频处理,每帧图像的处理都需要一定的缓存,如果每帧申请释放,则势必会降低算法效率,如下所示:

    //处理一帧
    void Process(BYTE *pimg)
    {
        malloc
        ...
        free
    }
    
    //循环处理一个视频
    for(int i = 0; i < N; i++)
    {
        BYTE *pimg = readimage();
        Process(pimg);
    }
    //处理一帧
    void Process(BYTE *pimg, BYTE *pBuffer)
    {
        ...
    }
    
    //循环处理一个视频
    malloc pBuffer
    for(int i = 0; i < N; i++)
    {
        BYTE *pimg = readimage();
        Process(pimg, pBuffer);
    }
    free

    前一段代码在每帧处理都malloc和free,而后一段代码则是有上层传入缓存,这样内部就不需每次申请和释放了。当然上面只是一个简单说明,实际情况会比这复杂得多,但整体思想是一致的。

    2.算法优化

    算法上的优化是必须首要考虑的,也是最重要的一步。一般我们需要分析算法的时间复杂度,即处理时间与输入数据规模的一个量级关系,一个优秀的算法可以将算法复杂度降低若干量级,那么同样的实现,其平均耗时一般会比其他复杂度高的算法少(这里不代表任意输入都更快)。

    比如说排序算法,快速排序的时间复杂度为O(nlogn),而插入排序的时间复杂度为O(n*n),那么在统计意义下,快速排序会比插入排序快,而且随着输入序列长度n的增加,两者耗时相差会越来越大。但是,假如输入数据本身就已经是升序(或降序),那么实际运行下来,快速排序会更慢。

    3.指令优化

    对于经过前面算法和代码优化的程序,一般其效率已经比较不错了。对于某些特殊要求,还需要进一步降低程序耗时,那么指令优化就该上场了。指令优化一般是使用特定的指令集,可快速实现某些运算,同时指令优化的另一个核心思想是打包运算。目前PC上intel指令集有MMX,SSE和SSE2/3/4等,DSP则需要跟具体的型号相关,不同型号支持不同的指令集。intel指令集需要intel编译器才能编译,安装icc后,其中有帮助文档,有所有指令的详细说明。

    例如MMX里的指令 __m64 _mm_add_pi8(__m64 m1, __m64 m2),是将m1和m2中8个8bit的数对应相加,结果就存在返回值对应的比特段中。假设2个N数组相加,一般需要执行N个加法指令,但使用上述指令只需执行N/8个指令,因为其1个指令能处理8个数据。

    实现求2个BYTE数组的均值,即z[i]=(x[i]+y[i])/2,直接求均值和使用MMX指令实现2种方法如下程序所示:

    #define N 800
    BYTE x[N],Y[N], Z[N];
    inital x,y;...
    //直接求均值
    for(int i = 0; i < N; i++)
    {
        z[i] = (x[i] + y[i]) >> 1;
    }
    
    //使用MMX指令求均值,这里N为8的整数倍,不考虑剩余数据处理
    __m64 m64X, m64Y, m64Z;
    for(int i = 0; i < N; i+=8)
    {
        m64X = *(__m64 *)(x + i);
        m64Y = *(__m64 *)(y + i);
        m64Z = _mm_avg_pu8(m64X, m64Y);
        *(__m64 *)(x + i) = m64Z;
    }

    使用指令优化需要注意的问题有:

    • 关于值域,比如2个8bit数相加,其值可能会溢出;若能保证其不溢出,则可使用一次处理8个数据,否则,必须降低性能,使用其他指令一次处理4个数据了;
    • 剩余数据,使用打包处理的数据一般都是4、8或16的整数倍,若待处理数据长度不是其单次处理数据个数的整数倍,剩余数据需单独处理
    展开全文
  • TensorFlow优化方法

    千次阅读 2019-04-06 19:12:22
    目前加速训练的优化方法基本都是基于梯度下降的,只是细节上有些差异。梯度下降是求函数极值的一种方法,学习到最后就是求损失函数的极值问题。 TensorFlow提供了很多优化器(optimizer),我们重点介绍下面这8个:...
  • 优化-下降方法

    千次阅读 2019-07-22 13:03:49
    最近看的论文涉及到了下降方法,所以专门做一个总结,暂时先总结了随机梯度下降法,关于最速下降法和牛顿法以后时间慢慢总结 本文总结的方法包括: 梯度下降法 随机梯度下降法 1.梯度下降法 在机器学习算法中...
  • - 最优化方法及其应用/郭科,陈聆,魏友华.-北京:高等教育出版社,2007.7(2013.7重印) 在第四章中,我们解决了确定搜索步长的问题,现在解决确定搜索方向的问题。 1、最速下降法 基本思路 搜索方向总沿着f(X)f...
  • 优化方法:拉格朗日乘数法

    万次阅读 多人点赞 2016-08-18 14:34:38
    1. 拉格朗日乘数法的基本思想 作为一种优化算法,拉格朗日乘子法主要用于解决约束优化问题,它的基本思想就是通过引入拉格朗日乘子来将含有n个变量和k个约束条件的约束优化问题转化为含有(n+k)个变量的无约束优化...
  • 神经网络中的各种优化方法

    万次阅读 2018-10-17 17:48:27
    大家耳熟能详的优化方法有梯度下降法(Gradient Descent)、随机梯度下降法(Stochastic Gradient Descent)、Adam方法等等。虽然很多听过甚至用过这些方法,但是却未必能够说出他们的区别,已经什么时候改用什么样...
  • 几个优化方法

    千次阅读 2017-04-01 11:02:55
    常见的几类优化算法:梯度下降法(GD)、批量梯度下降法(BGD)、随机梯度下降法(SGD)、牛顿法、拟牛顿法、共轭梯度法、Momentum、Nesterov Momentum、Adagrad、Adadelta。接下来一一介绍。 一、梯度下降梯度下降...
  • 神经网络优化方法

    2019-03-15 20:46:49
    它的主要思想是让隐藏层的节点在每次迭代时(包括正向和反向传播)一定几率(keep-prob)失效。这样来预防过拟合。它主要避免对某个节点的强依赖,让反向传播的修正值可以更加平衡的分布到各个参数上 (1)Dropout只...
  • 常用最优化方法

    千次阅读 2018-05-18 14:14:15
    熟悉机器学习的童鞋都知道,优化方法是其中一个非常重要的话题,最常见的情形就是利用目标函数的导数通过多次迭代来求解无约束最优化问题。实现简单,coding方便,是训练模型的必备利器之一。 2. 几个数学概念 1)...
  • 掌握常用的优化方法对机器学习算法而言是必不可少的,本文只介绍无约束问题的优化,后续会介绍约束的情况。 主要介绍以下几个内容: 1 优化概述 2 无约束问题的优化方法 3 梯度下降法 4 牛顿法与拟牛顿法 5 梯度...
  • 无约束优化方法

    千次阅读 2018-09-15 20:50:17
    1.1问题定义 1.1.1优化问题定义 ...可行域这个东西,等式约束,也不等式约束,或者没有约束,这次的精力主要还是集中在无约束的优化问题上,如果精力,再讨论约束的。 1.1.2最优化方法定义 优化...
  • 最优化问题在机器学习/深度学习中是经常遇到的问题,也是很重要的一个问题。学习算法的本质都是建立优化模型,通过最优化方法...梯度下降法的优化思想是用当前位置负梯度方向作为搜索方向,因为该方向为当前位置的最...
  • 很多人表示Java运行速度慢,严重的性能问题,其实这与Java无关,而是涉及到Java应用的性能优化。接下来我就给大家分享Java性能优化的常用方法。 1、设计优化 设计优化处于性能优化手段的上层,它需要在软件开发...
  • OpenCV常见的优化方法和技巧总结

    万次阅读 多人点赞 2018-02-24 15:53:36
    OpenCV常见的优化方法和技巧总结 【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/78540206 目录 OpenCV常见的优化方法和技巧总结 一、OpenCV常见的优化方法总结 1.1 cv::...
  • 各种优化方法的比较

    千次阅读 2019-04-25 15:23:06
    GD: 每一个数据都要单独算一次梯度,每一个的梯度都会加进去下降,因此速度会很慢,而且容易陷入局部最...如果数据是稀疏的就选择自适应方法,它的好处是收敛快,如果需要更稳定就选择GD,但是它很容易掉入鞍点。
  • iSIGHT中优化方法种类

    千次阅读 2016-12-08 10:13:15
    iSIGHT中优化方法种类 iSIGHT里面的优化方法大致可分为三类: 1 数值优化方法 数值优化方法通常假设设计空间是单峰值的,凸性的,连续的。iSIGHT中以下几种: (1)外点罚函数法(EP):  外点罚函数法被...
  • 无约束最优化方法

    2017-10-01 21:17:25
    本文介绍了无约束最优化的两种常用方法,梯度法和牛顿法,拟牛顿法和BFGS,Broyden类算法
  • 优化问题——无约束优化方法(一)

    千次阅读 2020-06-02 16:01:37
    实际的优化问题一般都很多的约束,那么为什么还需要研究无约束的最优化方法呢?首先,我们从一个例子开始,相信大家在看到我的这篇文章之前,对于机器学习中的SVM算法已经了一定的了解,对于SVM的求解,同样也是...
  • 搜索引擎优化排名方法

    千次阅读 2007-05-11 23:24:00
    内容摘要:从几个方面...关键词:Google 搜索引擎优化 SEO 排名优化方法 正确的搜索引擎优化可以有效的帮助网站得到正确的排名,仅此而已,这也是我写这篇文章的目的。过度优化甚至作弊不但费时费力,而且对网站没有实
  • 掌握搜索引擎优化方法使关键词快速排名,在网站不同的阶段,使用的优化方法也是区别的,而且针对不同类型的网站,其采用的优化方法也是各不相同的,如刚接手一个网站,需要根据网站的建站时间、关键词排名等数据...
  • 优化方法——BGFS变尺度算法

    千次阅读 2019-04-18 22:07:29
    目录 ...最优化方法——最速下降法,阻尼牛顿法,共轭梯度法 1、不精确一维搜素 1.1 Wolfe-Powell 准则 2、不精确一维搜索算法计算步骤 1、BGFS基本思想 2、BGFS变尺度算法的计算公式 ...
  • 几种常见梯度优化方法

    千次阅读 2018-07-09 15:40:29
    优化算法是机器学习领域的重要内容,本文介绍几种常见的无约束的...关于无约束问题优化方法的一般讨论请参考此文。 梯度下降法 动量法 共轭梯度法 自然梯度法 梯度下降法 动量法 共轭梯度法 自然梯度法...
  • 损失函数优化方法

    千次阅读 2017-10-02 22:29:27
    梯度下降法梯度下降法是求解无约束最优化问题的一种最常用方法实现简单的优点。它是一种迭代算法,每一步需要求解的目标函数的梯度向量。假设 f(x)f(x) 是 Rn\mathbf R^n 上具有一阶连续偏导数的函数。要求解的...
  • 连续体结构拓扑优化方法介绍

    千次阅读 2021-03-15 18:27:43
    在航空和汽车制造行业,经常应用尺寸和形状优化技术设计结构和零件,形状优化方法也常被用来进行电磁、电化学和声学零件的设计,目前已经许多成功的算法可以处理这类非线性和有限维的问题[2,3]。 形状优化方法是以...
  • 优化方法-共轭梯度法

    千次阅读 2019-03-31 17:16:23
    优化方法-共轭梯度法 1.简介 共轭梯度法最初由Hesteness和Stiefel于1952年为求解线性方程组而提出的。其基本思想是把共轭性与最速下降方法相结合,利用已知点处的梯度构造一组共轭方向,并沿这组方向进行搜素,求...
  • CPU CACHE优化 性能优化方法和技巧

    千次阅读 2014-08-22 15:42:40
    Cache的容量决定了多少代码和数据可以放到Cache里面,了Cache才了竞争,才 了替换,才优化的空间。如果一个程序的热点(hotspot)已经完全填充了整个Cache,那 么再从Cache角度考虑优化就是白费力气了,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 346,357
精华内容 138,542
关键字:

优化的思想方法有哪些