2019-10-26 18:04:13 zhouaho2010 阅读数 2214
  • Kaggle 神器:XGBoost 从基础到实战

    主讲老师冒老师为计算机博士,现在中科院从事科研教学工作,十余年机器学习教学经验,主持国家级科研项目3项,研究方向为机器学习、计算机视觉及多媒体处理。 XGBoost是"极端梯度提升"(eXtreme Gradient Boosting)的简称。XGBoost源于梯度提升框架,但是能并行计算、近似建树、对稀疏数据的有效处理以及内存使用优化,这使得XGBoost至少比现有梯度提升实现有至少10倍的速度提升。XGBoost可以处理回归、分类和排序等多种任务。由于它在预测性能上的强大且训练速度快,XGBoost已屡屡斩获Kaggle各大竞赛的冠军宝座。

    39329 人正在学习 去看看 AI100讲师

首先简单自我介绍一下,本人现在是国内某211大学2019级博士研究生,计算机科学与技术专业,研究方向和兴趣包括深度学习(CV)、图像处理、菌群仿生优化算法、元胞自动机等,愿与大家分享自己的学习心得!目前主要研究图像去雾算法和深度学习理论。


如果要学习Machine Learning和Deep Learing,那么Gradient Descent Algorithm (梯度下降算法)是必须要掌握的!本篇博文是从零开始详细介绍了梯度下降算法的原理以及公式推导过程,并亲自录制了视频讲解(见文末),力求用最简单、最通俗的语言让小白能完完整整的听得懂。如果大家能看懂文字,就可以不用看视频,如果不想看文字或者文字看起来吃力,那我建议看文字的同时再看视频讲解。

1、从一个“房价预测”的案例开始讲解为什么要用梯度下降算法

     我有一个习惯,就是研究一个问题之前一定要问清楚为什么会引入这个概念,为什么要用这个东西?
下面先看这样一张图:
在这里插入图片描述      这是我从深度学习大牛吴恩达的课程里面截取的一张图,假设已经收集到波特兰的47个房子的面积以及对应房价,下面让你去预测(或者估计)某一个未知面积的房子房价是多少该怎么办呢?
     这显然就是一个机器学习里面的Supervised Learning(有监督学习)的问题,那我们建设建立了一个Linear Regression回归模型,即建立一个房价和房子面积的函数关系,如:
在这里插入图片描述
     这里面的hθh_{\theta }(x)称为假设函数,在机器学习力就是Target目标或者叫Label标签,在这个问题里就是房价,x就是房屋面积,那我们要做的就是通过已有的47个Examples(一般称为训练样本)数据去计算出(或者估计出)模型里面的参数,在这个问题里就是θ0\theta_{0}θ1\theta_{1},求出参数后,就可以计算未知的房屋面积对应的房价了,因为只要带入这个公式即可求出对应房价。如果用图来说明,就是用一条线去拟合已有的样本数据,然后就可以求出未知的房屋面积在这条拟合的曲线上对应的房价值就ok了:
在这里插入图片描述
     关键问题来了, 我们如何去求参数呢?使得我们建立的这个模型求出的hθh_{\theta }(x)与真正的对应房价是拟合的或者说很接近,那就要使得hθh_{\theta }(x)与真正的对应房价误差很小,那这个误差怎么表示呢?我们把这个误差称为Cost Function损失函数,这个时候就可以用梯度下降的算法来解决了!!!
     因此,使用梯度下降算法就是为了求解模型中的参数问题,优化模型,使得模型更准确!误差更小!


2、如何衡量误差?——Cost Function损失函数

     为了评估模型拟合的好坏,通常用损失函数(或者称为代价函数)来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。在线性回归中,损失函数通常为样本输出和假设函数的差取平方。
损失函数的写法有好几种:
在这里插入图片描述
以上三种都是可以的,没有什么本质上的区别,具体写哪种要看具体的问题如何方便。本博文就采用第一种形式了,用均方误差的形式。
详细说明一下这个公式:
     J(θ)就是损失函数,它代表假设函数hθh_{\theta }(x)与样本实际输出y的误差大小,i代表第i个样本(一共有N个样本),x代表feature特征,上面那个房价问题就是指的是房屋面积,这里只有一个特征,也就是一个维度,那如果换多个feature的问题:
在这里插入图片描述      上面这张表中,房价有四个特征,即四个维度,即x(1)x_{(1)}x(2)x_{(2)}x(3)x_{(3)}x(4)x_{(4)},如果再加上一个x(0)x_{(0)},而且x(0)x_{(0)}=1,那就是五个维度,那对应的参数θ就是5个,分别是θ(0)θ_{(0)}θ(1)θ_{(1)}θ(2)θ_{(2)}θ(3)θ_{(3)}θ(4)θ_{(4)},小写的n代表特征数,这里面n=4,实际维度就可以算为n+1=5个维度,那x(i)x^{(i)}就代表第i个样本的特征集合,一般用向量表示,比如x(2)x^{(2)}就是:
x(2)x^{(2)}=(14163240)\begin{pmatrix} 1416\\ 3\\ 2\\ 40\end{pmatrix}
xj(i){x_{j}}^{(i)}则表示i个样本的第j个维度的特征值,如x1(2){x_{1}}^{(2)}=1416,x4(4){x_{4}}^{(4)}=36,
     首先我们先任意给各θ赋初值,hθ(x(i))h_{\theta }(x^{(i)})代表用我们假设的函数求出来第i样本对应的值(在这个问题就是房价),y(i)y^{(i)}代表第i个样本对应的实际的值(在这个问题里就是房价),如果用线性回归模型,则有:
在这里插入图片描述
其中x(0)x^{(0)}=1,那θ(0)θ_{(0)}就代表一个常数项,所以也可以写成:
在这里插入图片描述
甚至我们写的更详细点,就是:
在这里插入图片描述如果用矩阵的表达形式就是:
在这里插入图片描述
其中:
θθ^{}=(θ(0)θ(1)θ(2)θ(3)θ(4))\begin{pmatrix} θ_{(0)}\\ θ_{(1)}\\ θ_{(2)}\\ θ_{(3)}\\ θ_{(4)}\end{pmatrix}XX^{}=(x(0)x(1)x(2)x(3)x(4))\begin{pmatrix} x_{(0)}\\ x_{(1)}\\ x_{(2)}\\ x_{(3)}\\x_{(4)}\end{pmatrix}
(注:我为什么要把各种表达都写出来,就是因为不同的书籍、论文中写法不一样,我刚开始学习的时候就有各种疑惑,现在我都写出来就是各位初学者能学会各种表达形式,以免心存疑惑)
     然后我们不断迭代更新θ,使得hθ(x(i))h_{\theta }(x^{(i)})y(i)y^{(i)}的误差越来越小直至达到最小了(可能是0),那最后的θ就是我们所要求解的值。
在这里插入图片描述

3、那如何求解参数θ使得损失函数J(θ)即误差最小呢?——梯度下降算法

3.1 什么是梯度

      在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。对于在点(x0y0)(x_{0},y_{0})的具体梯度向量就是(∂f/∂x0x_{0}, ∂f/∂y0y_{0})T^{T}.或者▽f((x0y0)(x_{0},y_{0})),如果是3个参数的向量梯度,就是(∂f/∂x, ∂f/∂y,∂f/∂z)T^{T},以此类推。

      那么这个梯度向量求出来有什么意义呢?他的意义从几何意义上讲,就是函数变化增加最快的地方。具体来说,对于函数f(x,y),在点(x0y0)(x_{0},y_{0}),沿着梯度向量的方向就是(∂f/∂x0x_{0}, ∂f/∂y0y_{0})T^{T}的方向是f(x,y)增加最快的地方。或者说,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是 -(∂f/∂x0x_{0}, ∂f/∂y0y_{0})T^{T}的方向,梯度减少最快,也就是更加容易找到函数的最小值。
  在这里插入图片描述      所以所谓的“梯度”就是求偏导,“梯度下降”就是沿着“导数值”减小的方向(负梯度方向),这样就可使得损失函数快速减小,误差就减小。在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。

3.2 梯度下降的场景假设

     梯度下降法的基本思想可以类比为一个下山的过程。假设这样一个场景:一个人被困在山上,需要从山上下来( 找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法确定,他必须利用自己周围的信息去找到下山的路径。这个时候,他就可以利用梯度下降算法来帮助自己下山。具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走,同理,如果我们的目标是上山,也就是爬到山顶,那么此时应该是朝着最陡峭的方向往上走。然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。
在这里插入图片描述
     这里面的最低点也就是损失函数的最小值点,也就是误差最小值点,既然误差最小,那我们的模型就越拟合实际情况,那预测就越准确!
     梯度下降的基本过程就和下山的场景很类似。
     首先,我们有一个可微分的函数。这个函数就代表着一座山。我们的目标就是找到这个函数的最小值,也就是山底。根据之前的场景假设,最快的下山的方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度 ,然后朝着梯度相反的方向,就能让函数值下降的最快!因为梯度的方向就是函数之变化最快的方向。

3.3 微分

     看待微分的意义,可以有不同的角度,最常用的两种是:

1、函数图像中,某点的切线的斜率
2、函数的变化率
几个微分的例子:
在这里插入图片描述
     上面的例子都是单变量的微分,当一个函数有多个变量的时候,就有了多变量的微分,即分别对每个变量进行求微分:
在这里插入图片描述
     梯度实际上就是多变量微分的一般化:
在这里插入图片描述
     我们可以看到,梯度就是分别对每个变量进行微分,然后用逗号分割开,梯度是用<>包括起来,说明梯度其实一个向量。
     梯度是微积分中一个很重要的概念,之前提到过梯度的意义

1、在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
2、在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向

     这也就说明了为什么我们需要千方百计的求取梯度!我们需要到达山底,就需要在每一步观测到此时最陡峭的地方,梯度就恰巧告诉了我们这个方向。梯度的方向是函数在给定点上升最快的方向,那么梯度的反方向就是函数在给定点下降最快的方向,这正是我们所需要的。所以我们只要沿着梯度的方向一直走,就能走到局部的最低点!

3.4 梯度下降算法的核心思想与详细步骤:

在这里插入图片描述
     以二维为例,介绍如何求偏导!如图所示:
在这里插入图片描述     因为:
在这里插入图片描述
在这里插入图片描述
其中x0x_{0}=1,则有:
在这里插入图片描述
在这里插入图片描述
     则一般化这个求偏导的公式为:
在这里插入图片描述

因此:
在这里插入图片描述
     其中α为学习率,可以给定,然后修改,下面有详细的介绍。
注:如果看不懂这个公式请看我的视频讲解。
详细步骤:
 1. 先决条件: 确认优化模型的假设函数和损失函数。
 
 比如对于线性回归,假设函数表示为 :
在这里插入图片描述
其中θiθ_{i} (i = 0,1,2… n)为模型参数,xix_{i}(i = 0,1,2… n)为每个样本的n个特征值。为简化表示,我们增加一个特征x0x_{0}=1 ,这样hθh_{θ}(x0x_{0},x1x_{1},…xnx_{n})=i=0nθixi\displaystyle\sum_{i=0}^{n} θ_ix_i

同样是线性回归,对应于上面的假设函数,损失函数为:
    在这里插入图片描述
 2、算法相关参数初始化。 主要是初始化θ0,θ1…,θn,算法终止距离ε以及步长(即学习率)α。在没有任何先验知识的时候,可以任意初始化,如将所有的θ初始化为0, 将步长(即学习率α)初始化为0.1。在调优的时候再优化。
 关于学习率α,就是我2019年上半年参加一所高校博士招生考试的一道笔试题,我记得我答的比较准确,那么学习率该怎么取值呢?
 学习率α就是步长,如果下山过程中,把梯度看做下山的方向,那学习率α就是每次走的步数,一般有两点考虑: 在这里插入图片描述     为便于大家理解,再举一个形象点的例子,假设地面有个坑,如果是大象过来,可以直接迈过那个坑了触碰不到坑的底端(错过了最优点),那如果是蚂蚁呢,那就可能磨磨唧唧要爬很多很多次才能到达坑的底端(算法非常慢甚至不能结束)。 所以学习率α不能过大也不能过小。
     根据经验,可以从以下几个数值开始试验α的值,0.001 ,0.003, 0.01, 0.03, 0.1, 0.3, 1, …
     α初始值为0.001, 不符合预期乘以3倍用0.003代替,不符合预期再用0.01替代,如此循环直至找到最合适的α。然后对于这些不同的 α 值,绘制J(θ)随迭代步数变化的曲线,然后选择看上去使得 J(θ)快速下降的一个 α 值。所以,在为梯度下降算法选择合适的学习速率α时,可以大致按3的倍数再按10的倍数来选取一系列α值

3. 算法过程。 
 1)确定当前位置的损失函数的梯度,对于θi,其梯度表达式如下:
 在这里插入图片描述
 2)用步长乘以损失函数的梯度,得到当前位置下降的距离,即:
 在这里插入图片描述
 对应于前面下山例子中的某一步。
 3)确定是否所有的θi,梯度下降的距离都小于ε,如果小于ε则算法终止,当前所有的θi(i=0,1,…n)即为最终结果。否则进入步骤4.
 4)更新所有的θ,对于θi,其更新表达式如下。更新完毕后继续转入步骤1
 在这里插入图片描述
 下面用线性回归的例子来具体描述梯度下降。假设我们的样本是:
 在这里插入图片描述
 损失函数如前面所述:
 在这里插入图片描述
 则在算法过程步骤1中对于θi 的偏导数计算如下(前面已经解释过了):
 在这里插入图片描述
 由于样本中没有x0x_{0},上式中令所有的 x0jx_{0}^{j}=1.
 步骤4中θi的更新表达式如下(前面已经解释过了):
 在这里插入图片描述
 从这里可以看出当前点的梯度方向是由所有的样本决定的,加1m\frac{1}{m}是为了好理解。由于步长也为常数,他们的乘积也为常数,所以这里α1m\frac{1}{m}可以用一个常数表示。

4、梯度下降的算法调优

在使用梯度下降时,需要进行调优。哪些地方需要调优呢?

  1. 算法的步长选择。在前面的算法描述中,我提到取步长为1,但是实际上取值取决于数据样本,可以多取一些值,从小到大,分别运行算法,看看迭代效果,如果损失函数在变小,说明取值有效,否则要增大步长。前面说了。步长太大,会导致迭代过快,甚至有可能错过最优解。步长太小,迭代速度太慢,很长时间算法都不能结束。所以算法的步长需要多次运行后才能得到一个较为优的值。

  2. 算法参数的初始值选择。 初始值不同,获得的最小值也有可能不同,因此梯度下降求得的只是局部最小值;当然如果损失函数是凸函数则一定是最优解。由于有局部最优解的风险,需要多次用不同初始值运行算法,关键损失函数的最小值,选择损失函数最小化的初值。

  3.归一化。由于样本不同特征的取值范围不一样,可能导致迭代很慢,为了减少特征取值的影响,可以对特征数据归一化,也就是对于每个特征x,求出它的期望x¯和标准差std(x),然后转化为:

x−x¯¯¯std(x)
    这样特征的新期望为0,新方差为1,迭代速度可以大大加快。

5、改进的梯度下降的算法(大家族)

  • 批量梯度下降法BGD(Batch Gradient Descent)
        批量梯度下降法,是梯度下降法最常用的形式,具体做法也就是在更新参数时使用所有的样本来进行更新,这个方法就是前面讲的线性回归的梯度下降算法。
        在这里插入图片描述
  • 随机梯度下降法SGD(Stochastic Gradient Descent)
        随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有的N个样本的数据,而是仅仅选取一个样本j来求梯度。对应的更新公式是:
        在这里插入图片描述
        随机梯度下降法,和批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用一个样本来梯度下降。自然各自的优缺点都非常突出。对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。
       那么,有没有一个中庸的办法能够结合两种方法的优点呢?有!这小批量梯度下降法MBGD。
  • 小批量梯度下降法MBGD(Mini-batch Gradient Descent)
      小批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,也就是对于N个样本,我们采用x个样本来迭代,1<x<N。一般可以取x=10,当然根据样本的数据,可以调整这个x的值。对应的更新公式是:
    在这里插入图片描述
         到此,梯度下降算法就全部讲完了,有些表达也参考了一些博文,在此表示感谢,大家看看如果有问题就留言。 熬夜写博客不容易啊,尤其是敲公式,这篇博文花了我好几天的时间不断修整,如果大家觉得有帮助,请点个赞、评论一下,非常感谢啊!你们的支持是我输出文章的极大鼓励!!!后面准备写代码实战!

         视频讲解地址(直接点击即可)
    如果有想要更快更容易了解梯度下降算法的童鞋请看我的视频讲解!制作视频花了很大心血,录错了又得重新来,反反复复花了很多时间,所以收取一点点费用,也是想赚点博士生活费,谢谢大家支持!
    技术交流扣扣群:533209464(备注“学习”)
    在这里插入图片描述
2015-06-10 15:32:40 majinlei121 阅读数 2607
  • Kaggle 神器:XGBoost 从基础到实战

    主讲老师冒老师为计算机博士,现在中科院从事科研教学工作,十余年机器学习教学经验,主持国家级科研项目3项,研究方向为机器学习、计算机视觉及多媒体处理。 XGBoost是"极端梯度提升"(eXtreme Gradient Boosting)的简称。XGBoost源于梯度提升框架,但是能并行计算、近似建树、对稀疏数据的有效处理以及内存使用优化,这使得XGBoost至少比现有梯度提升实现有至少10倍的速度提升。XGBoost可以处理回归、分类和排序等多种任务。由于它在预测性能上的强大且训练速度快,XGBoost已屡屡斩获Kaggle各大竞赛的冠军宝座。

    39329 人正在学习 去看看 AI100讲师

转自:http://blog.csdn.net/gggg_ggg/article/details/44831895

在数字图像处理过程中,经常会遇到求梯度后,重新构建图像的问题。一般情况下,都是通过解泊松方程(还有其他方式重构图像,具体算法如下图所示,),利用拉普拉斯算子求解;但有一点请注意泊松方程求出的只是近似值,无法求出精确的原始值。


2018-07-27 14:34:54 lxdssg 阅读数 7025
  • Kaggle 神器:XGBoost 从基础到实战

    主讲老师冒老师为计算机博士,现在中科院从事科研教学工作,十余年机器学习教学经验,主持国家级科研项目3项,研究方向为机器学习、计算机视觉及多媒体处理。 XGBoost是"极端梯度提升"(eXtreme Gradient Boosting)的简称。XGBoost源于梯度提升框架,但是能并行计算、近似建树、对稀疏数据的有效处理以及内存使用优化,这使得XGBoost至少比现有梯度提升实现有至少10倍的速度提升。XGBoost可以处理回归、分类和排序等多种任务。由于它在预测性能上的强大且训练速度快,XGBoost已屡屡斩获Kaggle各大竞赛的冠军宝座。

    39329 人正在学习 去看看 AI100讲师

本算法是基于tensorflow,使用python语言进行的一种图像分类算法,参考于谷歌的mnist手写识别,包括以下几个模块:图像读取,图像处理,图像增强。卷积神经网络部分包括:卷积层1,汇合层1(部分文献也有叫池化层的),卷积层2,汇合层2,全连接层1,全连接层2,共6层神经网络。损失函数采用交叉熵,优化则采用adam优化法,由于数据集大小较小,只有200张图片,故没有采用MBGD梯度下降算法,直接采用BGD梯度下降算法。

首先是图像读取模块,由于本方案是应用于识别渣土车顶棚是否遮盖好的算法,所以没有网上现成的数据库,目前只有从网上收集图片,并转换成数据。

"""
定义一个遍历文件夹下所有图片,并转化为矩阵,压缩为特定大小,并传入一个总
的矩阵中去的函数
"""      
def creat_x_database(rootdir,resize_row,resize_col):
    #列出文件夹下所有的,目录和文件
    list = os.listdir(rootdir)
    #创建一个随机矩阵,作为多个图片转换为矩阵后传入其中
    database=np.arange(len(list)*resize_row*resize_col*3).reshape(len(list)
    ,resize_row,resize_col,3)
    for i in range(0,len(list)):
        path = os.path.join(rootdir,list[i])    #把目录和文件名合成一个路径
        if os.path.isfile(path):                ##判断路径是否为文件
            image_raw_data = tf.gfile.FastGFile(path,'rb').read()#读取图片
            with tf.Session() as sess:
                img_data = tf.image.decode_jpeg(image_raw_data)#图片解码
                #压缩图片矩阵为指定大小
                resized=tf.image.resize_images(img_data,[resize_row,resize_col],method=0)
                database[i]=resized.eval()
    return database                          
  

以上是创建数据集,还有标签集,网上部分创建标签集的方法是直接读取已经设定好标签的图片名字创建,比较适合分类数目较多的且在一个文件夹下的图片,这里笔者因为图片数量不多加之图片全是网上搜索,故采用以下方法

def creat_y_database(length,classfication_value,one_hot_value):
    #创建一个适当大小的矩阵来接收
    array=np.arange(length*classfication_value).reshape(length,classfication_value)
    for i in range(0,length):
        array[i]=one_hot_value #这里采用one hot值来区别合格与不合格
    return array

下面是卷积神经网络的搭建,这里参考的mnist手写输入识别的分类的神经网络

'''
初步打造一个卷积神经网,使其能够对输入图片进行二分类
'''
#计算准确率

def compute_accuracy(v_xs, v_ys):
    global prediction
    y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
    return result          
#定义各参数变量并初始化            
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

def conv2d(x, W):
    # stride [1, x_movement, y_movement, 1]
    # Must have strides[0] = strides[3] = 1
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    # stride [1, x_movement, y_movement, 1]
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')



#创建训练集
fail_x_data=creat_x_database('E:/data/muck truck pic/failed',128,128)
true_x_data=creat_x_database('E:/data/muck truck pic/qualified',128,128) 
x_data=np.vstack((fail_x_data,true_x_data))  #两个矩阵在列上进行合并
#创建标签集    
fail_y_data=creat_y_database(fail_x_data.shape[0],2,[0,1])
true_y_data=creat_y_database(true_x_data.shape[0],2,[1,0])
y_data=np.vstack((fail_y_data,true_y_data))
#划分训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(x_data,y_data,test_size=0.1,random_state=0)
#train_test_split函数用于将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签。
    
    
xs = tf.placeholder(tf.float32, [None, 128,128,3])/255 #归一化
ys = tf.placeholder(tf.float32, [None, 2])
keep_prob = tf.placeholder(tf.float32)
#x_image = tf.reshape(xs, [-1, 50, 50, 3])

W_conv1 = weight_variable([5,5, 3,32]) # patch 5x5, in size 3, out size 32
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(xs, W_conv1) + b_conv1) # output size 128x128x32
h_pool1 = max_pool_2x2(h_conv1)                          # output size 64x64x32

W_conv2 = weight_variable([5,5, 32, 64]) # patch 5x5, in size 32, out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 64x64x64
h_pool2 = max_pool_2x2(h_conv2) #32x32x64

W_fc1 = weight_variable([32*32*64, 1024])
b_fc1 = bias_variable([1024])
   
h_pool2_flat = tf.reshape(h_pool2, [-1, 32*32*64])
h_fc1 = tf.nn.sigmoid(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

W_fc2 = weight_variable([1024, 2])
b_fc2 = bias_variable([2])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction+ 1e-10), reduction_indices=[1]))
#由于 prediction 可能为 0, 导致 log 出错,最后结果会出现 NA      
#train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)    
sess=tf.Session()
init=tf.global_variables_initializer()
sess.run(init)

for i in range(1000):
#    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: x_train, ys: y_train, keep_prob: 0.5})
    if i % 50 == 0:
        print(compute_accuracy(x_test,y_test))
        print(sess.run(cross_entropy, feed_dict={xs: x_train, ys: y_train, keep_prob: 1}))

这里有一个坑点要说明一下,在修改神经网络的过程中,发现精确度一直不变,这说明模型不收敛,一层一层的查找问题才发现是prediction的值可能为0,导致交叉熵出现-Naf这种情况。解决办法如上所示,在prediction的后面加一个极小数,防止log出现负无穷的情况。同时参考其他文章,在倒数第二层的激活函数上由ReLU改为sigmoid,原因是ReLU输出可能相差很大(比如0和几十),这时再经过softmax就会出现一个节点为1其它全0的情况。softmax的cost function里包含一项log(y),如果y正好是0就没法算了。

最终训练结果如图所示:

训练结果并不好,最高有75%,可能原因有超参数的调整没到位,图像样本太少,训练层数太少,训练次数太少等。后期需要改进这个模型。

 

 

参考文献:【1】https://blog.csdn.net/huangbo10/article/details/24941079

                  【2】https://github.com/MorvanZhou/tutorials/blob/master/tensorflowTUT/tf18_CNN3/full_code.py

                  【3】http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.html

2018-03-14 09:00:11 qq_36330643 阅读数 1035
  • Kaggle 神器:XGBoost 从基础到实战

    主讲老师冒老师为计算机博士,现在中科院从事科研教学工作,十余年机器学习教学经验,主持国家级科研项目3项,研究方向为机器学习、计算机视觉及多媒体处理。 XGBoost是"极端梯度提升"(eXtreme Gradient Boosting)的简称。XGBoost源于梯度提升框架,但是能并行计算、近似建树、对稀疏数据的有效处理以及内存使用优化,这使得XGBoost至少比现有梯度提升实现有至少10倍的速度提升。XGBoost可以处理回归、分类和排序等多种任务。由于它在预测性能上的强大且训练速度快,XGBoost已屡屡斩获Kaggle各大竞赛的冠军宝座。

    39329 人正在学习 去看看 AI100讲师

在机器学习领域中,梯度下降的方式有三种,分别是:批量梯度下降法BGD、随机梯度下降法SGD、小批量梯度下降法MBGD,并且都有不同的优缺点。

下面我们以线性回归算法(也可以是别的算法,只是损失函数(目标函数)不同而已,它们的导数的不同,做法是一模一样的)为例子来对三种梯度下降法进行比较。

1. 线性回归

假设 特征 和 结果 都满足线性。即不大于一次方。这个是针对 收集的数据而言。
收集的数据中,每一个分量,就可以看做一个特征数据。每个特征至少对应一个未知的参数。这样就形成了一个线性模型函数,向量表示形式:

clip_image005

这个就是一个组合问题,已知一些数据,如何求里面的未知参数,给出一个最优解。 一个线性矩阵方程,直接求解,很可能无法直接求解。有唯一解的数据集,微乎其微。

基本上都是解不存在的超定方程组。因此,需要退一步,将参数求解问题,转化为求最小误差问题,求出一个最接近的解,这就是一个松弛求解。

求一个最接近解,直观上,就能想到,误差最小的表达形式。仍然是一个含未知参数的线性模型,一堆观测数据,其模型与数据的误差最小的形式,模型与数据差的平方和最小:

clip_image006

2. 参数更新

对目标函数进行求导,导数如下:



利用梯度下降跟新参数,参数更新方式如下:

                                                                                                                                                                           (1)

3. 批量梯度下降法(Batch Gradient Descent,简称BGD)是梯度下降法最原始的形式,它的具体思路是在更新每一参数时都使用所有的样本来进行更新,也就是方程(1)中的m表示样本的所有个数。

优点:全局最优解;易于并行实现;

缺点:当样本数目很多时,训练过程会很慢。

4. 随机梯度下降法:它的具体思路是在更新每一参数时都使用一个样本来进行更新,也就是方程(1)中的m等于1。每一次跟新参数都用一个样本,更新很多次。如果样本量很大的情况(例如几十万),那么可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次,这种跟新方式计算复杂度太高。

但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。

优点:训练速度快;

缺点:准确度下降,并不是全局最优;不易于并行实现。

从迭代的次数上来看,SGD迭代的次数较多,在解空间的搜索过程看起来很盲目。

5.小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD):它的具体思路是在更新每一参数时都使用一部分样本来进行更新,也就是方程(1)中的m的值大于1小于所有样本的数量。为了克服上面两种方法的缺点,又同时兼顾两种方法的有点。

6.三种方法使用的情况:

如果样本量比较小,采用批量梯度下降算法。如果样本太大,或者在线算法,使用随机梯度下降算法。在实际的一般情况下,采用小批量梯度下降算法。


参考:

http://blog.csdn.net/viewcode/article/details/8794401

http://mp.weixin.qq.com/s/fXlbB7KmiX0iIv6xwSxNIA
2018-07-09 09:08:02 qq_15262755 阅读数 1605
  • Kaggle 神器:XGBoost 从基础到实战

    主讲老师冒老师为计算机博士,现在中科院从事科研教学工作,十余年机器学习教学经验,主持国家级科研项目3项,研究方向为机器学习、计算机视觉及多媒体处理。 XGBoost是"极端梯度提升"(eXtreme Gradient Boosting)的简称。XGBoost源于梯度提升框架,但是能并行计算、近似建树、对稀疏数据的有效处理以及内存使用优化,这使得XGBoost至少比现有梯度提升实现有至少10倍的速度提升。XGBoost可以处理回归、分类和排序等多种任务。由于它在预测性能上的强大且训练速度快,XGBoost已屡屡斩获Kaggle各大竞赛的冠军宝座。

    39329 人正在学习 去看看 AI100讲师

主要参考 电子工业出版社的《数字图像处理 原理与实践matlab版》

step01 用二维高斯模板进行卷积以消除杂点

step02 用已结偏导数的有限差分来计算梯度的幅值和方向

step03 对帝都肤质进行非极大值抑制

step04 双阈值算法监测和连接边缘 

step05 利用多尺度综合技术对结果进行优化。(优化的方法并不唯一,可以根据具体应用或针对具体图像特征再做考虑)

代码;

 I=imread('D:\Desktop\TEST.jpg');
 [R,C,D]=size(I);
Im=rgb2gray(I);


img=edge(Im,'canny',[0.032,0.08],3);//阈值矩阵的上界和下界可以调整
figure(1);
imshow(Im);
figure(2);
imshow(I);
figure(3);

imshow(img);

结果:


可以发现分割后的效果并不理想

在对植物部分进行分割后再次用canny进行边缘检测后的结果如下所示


植物界外的分割部分有所提高,但是植物的叶脉部分也被当做边缘提出了

接下来主要是通过调整阈值的取值范围以期获得较好的边缘检测结果
高阈值比较严格,求的边缘很少,认为高阈值的边缘都是有效。低阈值宽松,求的边缘很多(一般包括了高阈值求到的边缘),其中不少是无效的边缘(反正不想要的)。
先用高阈值求边缘。canny求得的边缘希望是连在一起的(通常是封闭的),但高阈值求的边缘一般断断续续。断开的地方如果低阈值求的边缘存在,就用低阈值的边缘接上去,目的让边缘尽量都连在一起。其它情况下低阈值的边缘是不用的。

两个阈值是有区别的,高的那个阈值是将要提取轮廓的物体与背景区分开来,就像阈值分割的那个参数一样,是决定目标与背景对比度的,低的那个阈值是用来平滑边缘的轮廓,有时高的阈值设置太大了,可能边缘轮廓不连续或者不够平滑,通过低阈值来平滑轮廓线,或者使不连续的部分连接起来。

最后调整结果任然不满意


考虑对图像进行一定的预处理后再进行边缘检测

图像面试小结

阅读数 85

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