DataWhale集成学习笔记-task06

Bagging思想的实质是:通过Bootstrap 的方式对全样本数据集进行抽样得到抽样子集,对不同的子集使用同一种基本模型进行拟合,然后投票得出最终的预测。我们也从前面的探讨知道:Bagging主要通过降低方差的方式减少预测误差。那么,本章介绍的Boosting是与Bagging截然不同的思想,Boosting方法是使用同一组数据集进行反复学习,得到一系列简单模型,然后组合这些模型构成一个预测性能十分强大的机器学习模型。显然,Boosting思想提高最终的预测效果是通过不断减少偏差的形式,与Bagging有着本质的不同。
在Boosting这一大类方法中,笔者主要介绍两类常用的Boosting方式:Adaptive Boosting 和 Gradient Boosting 以及它们的变体Xgboost、LightGBM以及Catboost。

boosting

举例说明,对于一个复杂任务来说,将多个专家的判断进行适当的综合所作出的判断,要比其中任何一个专家单独判断要好。实际上这是一种“三个臭皮匠顶个诸葛亮的道理”。
弱学习:识别错误率小于1/2(即准确率仅比随机猜测略高的学习算法)
强学习:识别准确率很高并能在多项式时间内完成的学习算法

Adaboost算法

对于Adaboost来说,解决上述的两个问题的方式是:

  1. 提高那些被前一轮分类器错误分类的样本的权重,而降低那些被正确分类的样本的权重。这样一来,那些在上一轮分类器中没有得到正确分类的样本,由于其权重的增大而在后一轮的训练中“备受关注”。
  2. 各个弱分类器的组合是通过采取加权多数表决的方式,具体来说,加大分类错误率低的弱分类器的权重,因为这些分类器能更好地完成分类任务,而减小分类错误率较大的弱分类器的权重,使其在表决中起较小的作用。

Adaboost算法:(参考李航老师的《统计学习方法》)

假设给定一个二分类的训练数据集: T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\} T={(x1,y1),(x2,y2),,(xN,yN)},其中每个样本点由特征与类别组成。特征 x i ∈ X ⊆ R n x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n} xiXRn,类别 y i ∈ Y = { − 1 , + 1 } y_{i} \in \mathcal{Y}=\{-1,+1\} yiY={1,+1} X \mathcal{X} X是特征空间, Y \mathcal{Y} Y是类别集合,输出最终分类器 G ( x ) G(x) G(x)。Adaboost算法如下:
(1). 初始化训练数据的分布: D 1 = ( w 11 , ⋯   , w 1 i , ⋯   , w 1 N ) , w 1 i = 1 N , i = 1 , 2 , ⋯   , N D_{1}=\left(w_{11}, \cdots, w_{1 i}, \cdots, w_{1 N}\right), \quad w_{1 i}=\frac{1}{N}, \quad i=1,2, \cdots, N D1=(w11,,w1i,,w1N),w1i=N1,i=1,2,,N
(2) 对于m=1,2,…,M

  • 使用具有权值分布 D m D_m Dm的训练数据集进行学习,得到基本分类器: G m ( x ) : X → { − 1 , + 1 } G_{m}(x): \mathcal{X} \rightarrow\{-1,+1\} Gm(x):X{1,+1}
  • 计算 G m ( x ) G_m(x) Gm(x)在训练集上的分类误差率 e m = ∑ i = 1 N P ( G m ( x i ) ≠ y i ) = ∑ i = 1 N w m i I ( G m ( x i ) ≠ y i ) e_{m}=\sum_{i=1}^{N} P\left(G_{m}\left(x_{i}\right) \neq y_{i}\right)=\sum_{i=1}^{N} w_{m i} I\left(G_{m}\left(x_{i}\right) \neq y_{i}\right) em=i=1NP(Gm(xi)=yi)=i=1NwmiI(Gm(xi)=yi)
  • 计算 G m ( x ) G_m(x) Gm(x)的系数 α m = 1 2 log ⁡ 1 − e m e m \alpha_{m}=\frac{1}{2} \log \frac{1-e_{m}}{e_{m}} αm=21logem1em,这里的log是自然对数ln
  • 更新训练数据集的权重分布
    D m + 1 = ( w m + 1 , 1 , ⋯   , w m + 1 , i , ⋯   , w m + 1 , N ) w m + 1 , i = w m i Z m exp ⁡ ( − α m y i G m ( x i ) ) , i = 1 , 2 , ⋯   , N \begin{array}{c} D_{m+1}=\left(w_{m+1,1}, \cdots, w_{m+1, i}, \cdots, w_{m+1, N}\right) \\ w_{m+1, i}=\frac{w_{m i}}{Z_{m}} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right), \quad i=1,2, \cdots, N \end{array} Dm+1=(wm+1,1,,wm+1,i,,wm+1,N)wm+1,i=Zmwmiexp(αmyiGm(xi)),i=1,2,,N 这里的 Z m Z_m Zm是规范化因子,使得 D m + 1 D_{m+1} Dm+1称为概率分布, Z m = ∑ i = 1 N w m i exp ⁡ ( − α m y i G m ( x i ) ) Z_{m}=\sum_{i=1}^{N} w_{m i} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right) Zm=i=1Nwmiexp(αmyiGm(xi)) 也就是所有数的总和。

(3) 构建基本分类器的线性组合 f ( x ) = ∑ m = 1 M α m G m ( x ) f(x)=\sum_{m=1}^{M} \alpha_{m} G_{m}(x) f(x)=m=1MαmGm(x),得到最终的分类器
G ( x ) = sign ⁡ ( f ( x ) ) = sign ⁡ ( ∑ m = 1 M α m G m ( x ) ) \begin{aligned} G(x) &=\operatorname{sign}(f(x)) \\ &=\operatorname{sign}\left(\sum_{m=1}^{M} \alpha_{m} G_{m}(x)\right) \end{aligned} G(x)=sign(f(x))=sign(m=1MαmGm(x))
下面对Adaboost算法做如下说明:
对于步骤(1),假设训练数据的权值分布是均匀分布,是为了使得第一次没有先验信息的条件下每个样本在基本分类器的学习中作用一样。
对于步骤(2),每一次迭代产生的基本分类器 G m ( x ) G_m(x) Gm(x)在加权训练数据集上的分类错误率 e m = ∑ i = 1 N P ( G m ( x i ) ≠ y i ) = ∑ G m ( x i ) ≠ y i w m i \begin{aligned}e_{m} &=\sum_{i=1}^{N} P\left(G_{m}\left(x_{i}\right) \neq y_{i}\right) =\sum_{G_{m}\left(x_{i}\right) \neq y_{i}} w_{m i}\end{aligned} em=i=1NP(Gm(xi)=yi)=Gm(xi)=yiwmi代表了在 G m ( x ) G_m(x) Gm(x)中分类错误的样本权重和,这点直接说明了权重分布 D m D_m Dm G m ( x ) G_m(x) Gm(x)的分类错误率 e m e_m em有直接关系。同时,在步骤(2)中,计算基本分类器 G m ( x ) G_m(x) Gm(x)的系数 α m \alpha_m αm α m = 1 2 log ⁡ 1 − e m e m \alpha_{m}=\frac{1}{2} \log \frac{1-e_{m}}{e_{m}} αm=21logem1em,它表示了 G m ( x ) G_m(x) Gm(x)在最终分类器的重要性程度, α m \alpha_m αm的取值由基本分类器 G m ( x ) G_m(x) Gm(x)的分类错误率有直接关系,当 e m ⩽ 1 2 e_{m} \leqslant \frac{1}{2} em21时, α m ⩾ 0 \alpha_{m} \geqslant 0 αm0,并且 α m \alpha_m αm随着 e m e_m em的减少而增大,因此分类错误率越小的基本分类器在最终分类器的作用越大!
最重要的,对于步骤(2)中的样本权重的更新:
w m + 1 , i = { w m i Z m e − α m , G m ( x i ) = y i w m i Z m e α m , G m ( x i ) ≠ y i w_{m+1, i}=\left\{\begin{array}{ll} \frac{w_{m i}}{Z_{m}} \mathrm{e}^{-\alpha_{m}}, & G_{m}\left(x_{i}\right)=y_{i} \\ \frac{w_{m i}}{Z_{m}} \mathrm{e}^{\alpha_{m}}, & G_{m}\left(x_{i}\right) \neq y_{i} \end{array}\right. wm+1,i={Zmwmieαm,Zmwmieαm,Gm(xi)=yiGm(xi)=yi 因此,从上式可以看到:被基本分类器 G m ( x ) G_m(x) Gm(x)错误分类的样本的权重扩大,被正确分类的样本权重减少,二者相比相差 e 2 α m = 1 − e m e m \mathrm{e}^{2 \alpha_{m}}=\frac{1-e_{m}}{e_{m}} e2αm=em1em倍。
对于步骤(3),线性组合 f ( x ) f(x) f(x)实现了将M个基本分类器的加权表决,系数 α m \alpha_m αm标志了基本分类器 G m ( x ) G_m(x) Gm(x)的重要性,值得注意的是:所有的 α m \alpha_m αm之和不为1。 f ( x ) f(x) f(x)的符号决定了样本x属于哪一类。

例子

下面,我们使用一组简单的数据来手动计算Adaboost算法的过程:(例子来源:http://www.csie.edu.tw)

训练数据如下表,假设基本分类器的形式是一个分割 x < v x<v x<v x > v x>v x>v表示,阈值v由该基本分类器在训练数据集上分类错误率 e m e_m em最低确定。
 序号  1 2 3 4 5 6 7 8 9 10 x 0 1 2 3 4 5 6 7 8 9 y 1 1 1 − 1 − 1 − 1 1 1 1 − 1 \begin{array}{ccccccccccc} \hline \text { 序号 } & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\ \hline x & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\ y & 1 & 1 & 1 & -1 & -1 & -1 & 1 & 1 & 1 & -1 \\ \hline \end{array}  序号 xy1012113214315416517618719811091
解:
初始化样本权值分布
D 1 = ( w 11 , w 12 , ⋯   , w 110 ) w 1 i = 0.1 , i = 1 , 2 , ⋯   , 10 \begin{aligned} D_{1} &=\left(w_{11}, w_{12}, \cdots, w_{110}\right) \\ w_{1 i} &=0.1, \quad i=1,2, \cdots, 10 \end{aligned} D1w1i=(w11,w12,,w110)=0.1,i=1,2,,10
对m=1:

  • 在权值分布 D 1 D_1 D1的训练数据集上,遍历每个结点并计算分类误差率 e m e_m em,阈值取v=2.5时分类误差率最低,那么基本分类器为:
    G 1 ( x ) = { 1 , x < 2.5 − 1 , x > 2.5 G_{1}(x)=\left\{\begin{array}{ll} 1, & x<2.5 \\ -1, & x>2.5 \end{array}\right. G1(x)={1,1,x<2.5x>2.5
  • G 1 ( x ) G_1(x) G1(x)在训练数据集上的误差率为 e 1 = P ( G 1 ( x i ) ≠ y i ) = 0.3 e_{1}=P\left(G_{1}\left(x_{i}\right) \neq y_{i}\right)=0.3 e1=P(G1(xi)=yi)=0.3
  • 计算 G 1 ( x ) G_1(x) G1(x)的系数: α 1 = 1 2 log ⁡ 1 − e 1 e 1 = 0.4236 \alpha_{1}=\frac{1}{2} \log \frac{1-e_{1}}{e_{1}}=0.4236 α1=21loge11e1=0.4236
  • 更新训练数据的权值分布:
    D 2 = ( w 21 , ⋯   , w 2 i , ⋯   , w 210 ) w 2 i = w 1 i Z 1 exp ⁡ ( − α 1 y i G 1 ( x i ) ) , i = 1 , 2 , ⋯   , 10 D 2 = ( 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.07143 , 0.16667 , 0.16667 , 0.16667 , 0.07143 ) f 1 ( x ) = 0.4236 G 1 ( x ) \begin{aligned} D_{2}=&\left(w_{21}, \cdots, w_{2 i}, \cdots, w_{210}\right) \\ w_{2 i}=& \frac{w_{1 i}}{Z_{1}} \exp \left(-\alpha_{1} y_{i} G_{1}\left(x_{i}\right)\right), \quad i=1,2, \cdots, 10 \\ D_{2}=&(0.07143,0.07143,0.07143,0.07143,0.07143,0.07143,\\ &0.16667,0.16667,0.16667,0.07143) \\ f_{1}(x) &=0.4236 G_{1}(x) \end{aligned} D2=w2i=D2=f1(x)(w21,,w2i,,w210)Z1w1iexp(α1yiG1(xi)),i=1,2,,10(0.07143,0.07143,0.07143,0.07143,0.07143,0.07143,0.16667,0.16667,0.16667,0.07143)=0.4236G1(x)

对于m=2:

  • 在权值分布 D 2 D_2 D2的训练数据集上,遍历每个结点并计算分类误差率 e m e_m em,阈值取v=8.5时分类误差率最低,那么基本分类器为:
    G 2 ( x ) = { 1 , x < 8.5 − 1 , x > 8.5 G_{2}(x)=\left\{\begin{array}{ll} 1, & x<8.5 \\ -1, & x>8.5 \end{array}\right. G2(x)={1,1,x<8.5x>8.5
  • G 2 ( x ) G_2(x) G2(x)在训练数据集上的误差率为 e 2 = 0.2143 e_2 = 0.2143 e2=0.2143
  • 计算 G 2 ( x ) G_2(x) G2(x)的系数: α 2 = 0.6496 \alpha_2 = 0.6496 α2=0.6496
  • 更新训练数据的权值分布:
    D 3 = ( 0.0455 , 0.0455 , 0.0455 , 0.1667 , 0.1667 , 0.1667 0.1060 , 0.1060 , 0.1060 , 0.0455 ) f 2 ( x ) = 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) \begin{aligned} D_{3}=&(0.0455,0.0455,0.0455,0.1667,0.1667,0.1667\\ &0.1060,0.1060,0.1060,0.0455) \\ f_{2}(x) &=0.4236 G_{1}(x)+0.6496 G_{2}(x) \end{aligned} D3=f2(x)(0.0455,0.0455,0.0455,0.1667,0.1667,0.16670.1060,0.1060,0.1060,0.0455)=0.4236G1(x)+0.6496G2(x)

对m=3:

  • 在权值分布 D 3 D_3 D3的训练数据集上,遍历每个结点并计算分类误差率 e m e_m em,阈值取v=5.5时分类误差率最低,那么基本分类器为:
    G 3 ( x ) = { 1 , x > 5.5 − 1 , x < 5.5 G_{3}(x)=\left\{\begin{array}{ll} 1, & x>5.5 \\ -1, & x<5.5 \end{array}\right. G3(x)={1,1,x>5.5x<5.5
  • G 3 ( x ) G_3(x) G3(x)在训练数据集上的误差率为 e 3 = 0.1820 e_3 = 0.1820 e3=0.1820
  • 计算 G 3 ( x ) G_3(x) G3(x)的系数: α 3 = 0.7514 \alpha_3 = 0.7514 α3=0.7514
  • 更新训练数据的权值分布:
    D 4 = ( 0.125 , 0.125 , 0.125 , 0.102 , 0.102 , 0.102 , 0.065 , 0.065 , 0.065 , 0.125 ) D_{4}=(0.125,0.125,0.125,0.102,0.102,0.102,0.065,0.065,0.065,0.125) D4=(0.125,0.125,0.125,0.102,0.102,0.102,0.065,0.065,0.065,0.125)

于是得到: f 3 ( x ) = 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) + 0.7514 G 3 ( x ) f_{3}(x)=0.4236 G_{1}(x)+0.6496 G_{2}(x)+0.7514 G_{3}(x) f3(x)=0.4236G1(x)+0.6496G2(x)+0.7514G3(x),分类器 sign ⁡ [ f 3 ( x ) ] \operatorname{sign}\left[f_{3}(x)\right] sign[f3(x)]在训练数据集上的误分类点的个数为0。
于是得到最终分类器为: G ( x ) = sign ⁡ [ f 3 ( x ) ] = sign ⁡ [ 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) + 0.7514 G 3 ( x ) ] G(x)=\operatorname{sign}\left[f_{3}(x)\right]=\operatorname{sign}\left[0.4236 G_{1}(x)+0.6496 G_{2}(x)+0.7514 G_{3}(x)\right] G(x)=sign[f3(x)]=sign[0.4236G1(x)+0.6496G2(x)+0.7514G3(x)]

越复杂的模型偏差越小,方差越大。
----偏差方差理论
在这里插入图片描述
从上面的决策边界图可以看到:Adaboost模型的决策边界比单层决策树的决策边界要复杂的多。也就是说,Adaboost试图用增加模型复杂度而降低偏差的方式去减少总误差,但是过程中引入了方差,可能出现过拟合,因此在训练集和测试集之间的性能存在较大的差距,这就简单地回答的刚刚问题。值的注意的是:与单个分类器相比,Adaboost等Boosting模型增加了计算的复杂度,在实践中需要仔细思考是否愿意为预测性能的相对改善而增加计算成本,而且Boosting方式无法做到现在流行的并行计算的方式进行训练,因为每一步迭代都要基于上一部的基本分类器。

前向分步算法

回看Adaboost的算法内容,我们需要通过计算M个基本分类器,每个分类器的错误率、样本权重以及模型权重。我们可以认为:Adaboost每次学习单一分类器以及单一分类器的参数(权重)。接下来,我们抽象出Adaboost算法的整体框架逻辑,构建集成学习的一个非常重要的框架----前向分步算法,有了这个框架,我们不仅可以解决分类问题,也可以解决回归问题。
(1) 加法模型:
在Adaboost模型中,我们把每个基本分类器合成一个复杂分类器的方法是每个基本分类器的加权和,即: f ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right) f(x)=m=1Mβmb(x;γm),其中, b ( x ; γ m ) b\left(x ; \gamma_{m}\right) b(x;γm)为即基本分类器, γ m \gamma_{m} γm为基本分类器的参数, β m \beta_m βm为基本分类器的权重,显然这与第二章所学的加法模型。为什么这么说呢?大家把 b ( x ; γ m ) b(x ; \gamma_{m}) b(x;γm)看成是即函数即可。
在给定训练数据以及损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x))的条件下,学习加法模型 f ( x ) f(x) f(x)就是:
min ⁡ β m , γ m ∑ i = 1 N L ( y i , ∑ m = 1 M β m b ( x i ; γ m ) ) \min _{\beta_{m}, \gamma_{m}} \sum_{i=1}^{N} L\left(y_{i}, \sum_{m=1}^{M} \beta_{m} b\left(x_{i} ; \gamma_{m}\right)\right) βm,γmmini=1NL(yi,m=1Mβmb(xi;γm))
通常这是一个复杂的优化问题,很难通过简单的凸优化的相关知识进行解决。前向分步算法可以用来求解这种方式的问题,它的基本思路是:因为学习的是加法模型,如果从前向后,每一步只优化一个基函数及其系数,逐步逼近目标函数,那么就可以降低优化的复杂度。具体而言,每一步只需要优化:
min ⁡ β , γ ∑ i = 1 N L ( y i , β b ( x i ; γ ) ) \min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, \beta b\left(x_{i} ; \gamma\right)\right) β,γmini=1NL(yi,βb(xi;γ))
(2) 前向分步算法:
给定数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\} T={(x1,y1),(x2,y2),,(xN,yN)} x i ∈ X ⊆ R n x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n} xiXRn y i ∈ Y = { + 1 , − 1 } y_{i} \in \mathcal{Y}=\{+1,-1\} yiY={+1,1}。损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x)),基函数集合 { b ( x ; γ ) } \{b(x ; \gamma)\} {b(x;γ)},我们需要输出加法模型 f ( x ) f(x) f(x)

  • 初始化: f 0 ( x ) = 0 f_{0}(x)=0 f0(x)=0
  • 对m = 1,2,…,M:
    • (a) 极小化损失函数:
      ( β m , γ m ) = arg ⁡ min ⁡ β , γ ∑ i = 1 N L ( y i , f m − 1 ( x i ) + β b ( x i ; γ ) ) \left(\beta_{m}, \gamma_{m}\right)=\arg \min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, f_{m-1}\left(x_{i}\right)+\beta b\left(x_{i} ; \gamma\right)\right) (βm,γm)=argβ,γmini=1NL(yi,fm1(xi)+βb(xi;γ))
      得到参数 β m \beta_{m} βm γ m \gamma_{m} γm
    • (b) 更新:
      f m ( x ) = f m − 1 ( x ) + β m b ( x ; γ m ) f_{m}(x)=f_{m-1}(x)+\beta_{m} b\left(x ; \gamma_{m}\right) fm(x)=fm1(x)+βmb(x;γm)
  • 得到加法模型:
    f ( x ) = f M ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=f_{M}(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right) f(x)=fM(x)=m=1Mβmb(x;γm) 这样,前向分步算法将同时求解从m=1到M的所有参数 β m \beta_{m} βm γ m \gamma_{m} γm的优化问题简化为逐次求解各个 β m \beta_{m} βm γ m \gamma_{m} γm的问题。
    (3) 前向分步算法与Adaboost的关系:
    由于这里不是我们的重点,我们主要阐述这里的结论,不做相关证明,具体的证明见李航老师的《统计学习方法》第八章的3.2节。Adaboost算法是前向分步算法的特例,Adaboost算法是由基本分类器组成的加法模型,损失函数为指数损失函数。

梯度提升决策树 GCDT

(1) 基于残差学习的提升树算法:

在前面的学习过程中,我们一直讨论的都是分类树,比如Adaboost算法,并没有涉及回归的例子。在上一小节我们提到了一个加法模型+前向分步算法的框架,那能否使用这个框架解决回归的例子呢?答案是肯定的。接下来我们来探讨下如何使用加法模型+前向分步算法的框架实现回归问题。
在使用加法模型+前向分步算法的框架解决问题之前,我们需要首先确定框架内使用的基函数是什么,在这里我们使用决策树分类器。前面第二章我们已经学过了回归树的基本原理,树算法最重要是寻找最佳的划分点,分类树用纯度来判断最佳划分点使用信息增益(ID3算法),信息增益比(C4.5算法),基尼系数(CART分类树)。但是在回归树中的样本标签是连续数值,可划分点包含了所有特征的所有可取的值。所以再使用熵之类的指标不再合适,取而代之的是平方误差,它能很好的评判拟合程度。基函数确定了以后,我们需要确定每次提升的标准是什么。回想Adaboost算法,在Adaboost算法内使用了分类错误率修正样本权重以及计算每个基本分类器的权重,那回归问题没有分类错误率可言,也就没办法在这里的回归问题使用了,因此我们需要另辟蹊径。模仿分类错误率,我们用每个样本的残差表示每次使用基函数预测时没有解决的那部分问题。因此,我们可以得出如下算法:
输入数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } , x i ∈ X ⊆ R n , y i ∈ Y ⊆ R T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\}, x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n}, y_{i} \in \mathcal{Y} \subseteq \mathbf{R} T={(x1,y1),(x2,y2),,(xN,yN)},xiXRn,yiYR,输出最终的提升树 f M ( x ) f_{M}(x) fM(x)

  • 初始化 f 0 ( x ) = 0 f_0(x) = 0 f0(x)=0
  • 对m = 1,2,…,M:
    • 计算每个样本的残差: r m i = y i − f m − 1 ( x i ) , i = 1 , 2 , ⋯   , N r_{m i}=y_{i}-f_{m-1}\left(x_{i}\right), \quad i=1,2, \cdots, N rmi=yifm1(xi),i=1,2,,N
    • 拟合残差 r m i r_{mi} rmi学习一棵回归树,得到 T ( x ; Θ m ) T\left(x ; \Theta_{m}\right) T(x;Θm)
    • 更新 f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_{m}(x)=f_{m-1}(x)+T\left(x ; \Theta_{m}\right) fm(x)=fm1(x)+T(x;Θm)
  • 得到最终的回归问题的提升树: f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_{M}(x)=\sum_{m=1}^{M} T\left(x ; \Theta_{m}\right) fM(x)=m=1MT(x;Θm)
案例

下面我们用一个实际的案例来使用这个算法:(案例来源:李航老师《统计学习方法》)
训练数据如下表,学习这个回归问题的提升树模型,考虑只用树桩作为基函数。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

梯度提升决策树

Freidman提出了梯度提升算法(gradient boosting),这是利用最速下降法的近似方法,利用损失函数的负梯度在当前模型的值 − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) -\left[\frac{\partial L\left(y, f\left(x_{i}\right)\right)}{\partial f\left(x_{i}\right)}\right]_{f(x)=f_{m-1}(x)} [f(xi)L(y,f(xi))]f(x)=fm1(x)作为回归问题提升树算法中的残差的近似值,拟合回归树。与其说负梯度作为残差的近似值,不如说残差是负梯度的一种特例。
以下开始具体介绍梯度提升算法:
输入训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } , x i ∈ X ⊆ R n , y i ∈ Y ⊆ R T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\}, x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n}, y_{i} \in \mathcal{Y} \subseteq \mathbf{R} T={(x1,y1),(x2,y2),,(xN,yN)},xiXRn,yiYR和损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x)),输出回归树 f ^ ( x ) \hat{f}(x) f^(x)

  • 初始化 f 0 ( x ) = arg ⁡ min ⁡ c ∑ i = 1 N L ( y i , c ) f_{0}(x)=\arg \min _{c} \sum_{i=1}^{N} L\left(y_{i}, c\right) f0(x)=argminci=1NL(yi,c)
  • 对于m=1,2,…,M:
    • 对i = 1,2,…,N计算: r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{m i}=-\left[\frac{\partial L\left(y_{i}, f\left(x_{i}\right)\right)}{\partial f\left(x_{i}\right)}\right]_{f(x)=f_{m-1}(x)} rmi=[f(xi)L(yi,f(xi))]f(x)=fm1(x)
    • r m i r_{mi} rmi拟合一个回归树,得到第m棵树的叶结点区域 R m j , j = 1 , 2 , ⋯   , J R_{m j}, j=1,2, \cdots, J Rmj,j=1,2,,J
    • 对j=1,2,…J,计算: c m j = arg ⁡ min ⁡ c ∑ x i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{m j}=\arg \min _{c} \sum_{x_{i} \in R_{m j}} L\left(y_{i}, f_{m-1}\left(x_{i}\right)+c\right) cmj=argmincxiRmjL(yi,fm1(xi)+c)
    • 更新 f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_{m}(x)=f_{m-1}(x)+\sum_{j=1}^{J} c_{m j} I\left(x \in R_{m j}\right) fm(x)=fm1(x)+j=1JcmjI(xRmj)
  • 得到回归树: f ^ ( x ) = f M ( x ) = ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) \hat{f}(x)=f_{M}(x)=\sum_{m=1}^{M} \sum_{j=1}^{J} c_{m j} I\left(x \in R_{m j}\right) f^(x)=fM(x)=m=1Mj=1JcmjI(xRmj)
    但是其实没有定义L的函数,也就是损失函数,根据不同的损失函数是不同的方法
    损失函数可以有很多种,比如:
     Setting   Loss Function  − ∂ L ( y i , f ( x i ) ) / ∂ f ( x i )  Regression  1 2 [ y i − f ( x i ) ] 2 y i − f ( x i )  Regression  ∣ y i − f ( x i ) ∣ sign ⁡ [ y i − f ( x i ) ]  Regression   Huber  y i − f ( x i )  for  ∣ y i − f ( x i ) ∣ ≤ δ m δ m sign ⁡ [ y i − f ( x i ) ]  for  ∣ y i − f ( x i ) ∣ > δ m  where  δ m = α  th-quantile  { ∣ y i − f ( x i ) ∣ }  Classification   Deviance  k  th component:  I ( y i = G k ) − p k ( x i ) \begin{array}{l|l|l} \hline \text { Setting } & \text { Loss Function } & -\partial L\left(y_{i}, f\left(x_{i}\right)\right) / \partial f\left(x_{i}\right) \\ \hline \text { Regression } & \frac{1}{2}\left[y_{i}-f\left(x_{i}\right)\right]^{2} & y_{i}-f\left(x_{i}\right) \\ \hline \text { Regression } & \left|y_{i}-f\left(x_{i}\right)\right| & \operatorname{sign}\left[y_{i}-f\left(x_{i}\right)\right] \\ \hline \text { Regression } & \text { Huber } & y_{i}-f\left(x_{i}\right) \text { for }\left|y_{i}-f\left(x_{i}\right)\right| \leq \delta_{m} \\ & & \delta_{m} \operatorname{sign}\left[y_{i}-f\left(x_{i}\right)\right] \text { for }\left|y_{i}-f\left(x_{i}\right)\right|>\delta_{m} \\ & & \text { where } \delta_{m}=\alpha \text { th-quantile }\left\{\left|y_{i}-f\left(x_{i}\right)\right|\right\} \\ \hline \text { Classification } & \text { Deviance } & k \text { th component: } I\left(y_{i}=\mathcal{G}_{k}\right)-p_{k}\left(x_{i}\right) \\ \hline \end{array}  Setting  Regression  Regression  Regression  Classification  Loss Function 21[yif(xi)]2yif(xi) Huber  Deviance L(yi,f(xi))/f(xi)yif(xi)sign[yif(xi)]yif(xi) for yif(xi)δmδmsign[yif(xi)] for yif(xi)>δm where δm=α th-quantile {yif(xi)}k th component: I(yi=Gk)pk(xi)
    观察Huber损失函数:
    L δ ( y , f ( x ) ) = { 1 2 ( y − f ( x ) ) 2  for  ∣ y − f ( x ) ∣ ≤ δ δ ∣ y − f ( x ) ∣ − 1 2 δ 2  otherwise  L_{\delta}(y, f(x))=\left\{\begin{array}{ll} \frac{1}{2}(y-f(x))^{2} & \text { for }|y-f(x)| \leq \delta \\ \delta|y-f(x)|-\frac{1}{2} \delta^{2} & \text { otherwise } \end{array}\right. Lδ(y,f(x))={21(yf(x))2δyf(x)21δ2 for yf(x)δ otherwise 
案例

可见博客中比较详细
如果增加学习率0.1,则可以如下
预测结果为:
f ( x ) = 7.306 + 0.1 ∗ ( − 1.006 + − 0.52 + 0.15 + − 0.16 + 0.07 ) x ≤ 3.5 f(x)=7.306+0.1 *(-1.006+−0.52+0.15+−0.16+0.07) \qquad x\leq 3.5 f(x)=7.306+0.1(1.006+0.52+0.15+0.16+0.07)x3.5
为什么要用学习率呢?这是Shrinkage的思想,如果每次都全部加上(学习率为1)很容易一步学到位导致过拟合。
sklearn

XGBoost算法

XGBoost本质上还是一个GBDT,但是力争把速度和效率发挥到极致,所以叫X (Extreme) GBoosted,包括前面说过,两者都是boosting方法。XGBoost是一个优化的分布式梯度增强库,旨在实现高效,灵活和便携。 它在Gradient Boosting框架下实现机器学习算法。 XGBoost提供了并行树提升(也称为GBDT,GBM), 相同的代码在主要的分布式环境(Hadoop,SGE,MPI)上运行,并且可以解决超过数十亿个样例的问题。XGBoost利用了核外计算并且能够使数据科学家在一个主机上处理数亿的样本数据。最终,将这些技术进行结合来做一个端到端的系统以最少的集群系统来扩展到更大的数据集上。Xgboost以CART决策树为子模型,通过Gradient Tree Boosting实现多棵CART树的集成学习,得到最终模型。下面我们来看看XGBoost的最终模型构建
原理推导具体可见 知乎1
实现可见知乎2
网格搜索实例可见博客

参数解释

XGBoost的参数分为三种:

  • 通用参数:(两种类型的booster,因为tree的性能比线性回归好得多,因此我们很少用线性回归。)
    • booster:使用哪个弱学习器训练,默认gbtree,可选gbtree,gblinear 或dart
    • nthread:用于运行XGBoost的并行线程数,默认为最大可用线程数
    • verbosity:打印消息的详细程度。有效值为0(静默),1(警告),2(信息),3(调试)。
    • Tree Booster的参数:
      • eta(learning_rate):learning_rate,在更新中使用步长收缩以防止过度拟合,默认= 0.3,范围:[0,1];典型值一般设置为:0.01-0.2
      • gamma(min_split_loss):默认= 0,分裂节点时,损失函数减小值只有大于等于gamma节点才分裂,gamma值越大,算法越保守,越不容易过拟合,但性能就不一定能保证,需要平衡。范围:[0,∞]
      • max_depth:默认= 6,一棵树的最大深度。增加此值将使模型更复杂,并且更可能过度拟合。范围:[0,∞]
      • min_child_weight:默认值= 1,如果新分裂的节点的样本权重和小于min_child_weight则停止分裂 。这个可以用来减少过拟合,但是也不能太高,会导致欠拟合。范围:[0,∞]
      • max_delta_step:默认= 0,允许每个叶子输出的最大增量步长。如果将该值设置为0,则表示没有约束。如果将其设置为正值,则可以帮助使更新步骤更加保守。通常不需要此参数,但是当类极度不平衡时,它可能有助于逻辑回归。将其设置为1-10的值可能有助于控制更新。范围:[0,∞]
      • subsample:默认值= 1,构建每棵树对样本的采样率,如果设置成0.5,XGBoost会随机选择一半的样本作为训练集。范围:(0,1]
      • sampling_method:默认= uniform,用于对训练实例进行采样的方法。
        • uniform:每个训练实例的选择概率均等。通常将subsample> = 0.5 设置 为良好的效果。
        • gradient_based:每个训练实例的选择概率与规则化的梯度绝对值成正比,具体来说就是 g 2 + λ h 2 \sqrt{g^2+\lambda h^2} g2+λh2 ,subsample可以设置为低至0.1,而不会损失模型精度。
      • colsample_bytree:默认= 1,列采样率,也就是特征采样率。范围为(0,1]
      • lambda(reg_lambda):默认=1,L2正则化权重项。增加此值将使模型更加保守。
      • alpha(reg_alpha):默认= 0,权重的L1正则化项。增加此值将使模型更加保守。
      • tree_method:默认=auto,XGBoost中使用的树构建算法。
        • auto:使用启发式选择最快的方法。
          • 对于小型数据集,exact将使用精确贪婪()。
          • 对于较大的数据集,approx将选择近似算法()。它建议尝试hist,gpu_hist,用大量的数据可能更高的性能。(gpu_hist)支持。external memory外部存储器。
        • exact:精确的贪婪算法。枚举所有拆分的候选点。
        • approx:使用分位数和梯度直方图的近似贪婪算法。
        • hist:更快的直方图优化的近似贪婪算法。(LightGBM也是使用直方图算法)
        • gpu_hist:GPU hist算法的实现。
      • scale_pos_weight:控制正负权重的平衡,这对于不平衡的类别很有用。Kaggle竞赛一般设置sum(negative instances) / sum(positive instances),在类别高度不平衡的情况下,将参数设置大于0,可以加快收敛。
      • num_parallel_tree:默认=1,每次迭代期间构造的并行树的数量。此选项用于支持增强型随机森林。
      • monotone_constraints:可变单调性的约束,在某些情况下,如果有非常强烈的先验信念认为真实的关系具有一定的质量,则可以使用约束条件来提高模型的预测性能。(例如params_constrained[‘monotone_constraints’] = “(1,-1)”,(1,-1)我们告诉XGBoost对第一个预测变量施加增加的约束,对第二个预测变量施加减小的约束。)
    • Linear Booster的参数:
      • lambda(reg_lambda):默认= 0,L2正则化权重项。增加此值将使模型更加保守。归一化为训练示例数。
      • alpha(reg_alpha):默认= 0,权重的L1正则化项。增加此值将使模型更加保守。归一化为训练示例数。
      • updater:默认= shotgun。
        • shotgun:基于shotgun算法的平行坐标下降算法。使用“ hogwild”并行性,因此每次运行都产生不确定的解决方案。
        • coord_descent:普通坐标下降算法。同样是多线程的,但仍会产生确定性的解决方案。
      • feature_selector:默认= cyclic。特征选择和排序方法
        • cyclic:通过每次循环一个特征来实现的。
        • shuffle:类似于cyclic,但是在每次更新之前都有随机的特征变换。
        • random:一个随机(有放回)特征选择器。
        • greedy:选择梯度最大的特征。(贪婪选择)
        • thrifty:近似贪婪特征选择(近似于greedy)
      • top_k:要选择的最重要特征数(在greedy和thrifty内)
  • 任务参数(这个参数用来控制理想的优化目标和每一步结果的度量方法。)
    • objective:默认=reg:squarederror,表示最小平方误差。
      • reg:squarederror,最小平方误差。
      • reg:squaredlogerror,对数平方损失。 1 2 [ l o g ( p r e d + 1 ) − l o g ( l a b e l + 1 ) ] 2 \frac{1}{2}[log(pred+1)-log(label+1)]^2 21[log(pred+1)log(label+1)]2
      • reg:logistic,逻辑回归
      • reg:pseudohubererror,使用伪Huber损失进行回归,这是绝对损失的两倍可微选择。
      • binary:logistic,二元分类的逻辑回归,输出概率。
      • binary:logitraw:用于二进制分类的逻辑回归,逻辑转换之前的输出得分。
      • binary:hinge:二进制分类的铰链损失。这使预测为0或1,而不是产生概率。(SVM就是铰链损失函数)
      • count:poisson –计数数据的泊松回归,泊松分布的输出平均值。
      • survival:cox:针对正确的生存时间数据进行Cox回归(负值被视为正确的生存时间)。
      • survival:aft:用于检查生存时间数据的加速故障时间模型。
      • aft_loss_distribution:survival:aft和aft-nloglik度量标准使用的概率密度函数。
      • multi:softmax:设置XGBoost以使用softmax目标进行多类分类,还需要设置num_class(类数)
      • multi:softprob:与softmax相同,但输出向量,可以进一步重整为矩阵。结果包含属于每个类别的每个数据点的预测概率。
      • rank:pairwise:使用LambdaMART进行成对排名,从而使成对损失最小化。
      • rank:ndcg:使用LambdaMART进行列表式排名,使标准化折让累积收益(NDCG)最大化。
      • rank:map:使用LambdaMART进行列表平均排名,使平均平均精度(MAP)最大化。
      • reg:gamma:使用对数链接进行伽马回归。输出是伽马分布的平均值。
      • reg:tweedie:使用对数链接进行Tweedie回归。
      • 自定义损失函数和评价指标:https://xgboost.readthedocs.io/en/latest/tutorials/custom_metric_obj.html
    • eval_metric:验证数据的评估指标,将根据目标分配默认指标(回归均方根,分类误差,排名的平均平均精度),用户可以添加多个评估指标
      • rmse,均方根误差; rmsle:均方根对数误差; mae:平均绝对误差;mphe:平均伪Huber错误;logloss:负对数似然; error:二进制分类错误率;
      • merror:多类分类错误率; mlogloss:多类logloss; auc:曲线下面积; aucpr:PR曲线下的面积;ndcg:归一化累计折扣;map:平均精度;
    • seed :随机数种子,[默认= 0]。
调参说明

参数调优的一般步骤

    1. 确定学习速率和提升参数调优的初始值
    1. max_depth 和 min_child_weight 参数调优
    1. gamma参数调优
    1. subsample 和 colsample_bytree 参数优
    1. 正则化参数alpha调优
    1. 降低学习速率和使用更多的决策树

LightGBM

LightGBM也是像XGBoost一样,是一类集成算法,他跟XGBoost总体来说是一样的,算法本质上与Xgboost没有出入,只是在XGBoost的基础上进行了优化,因此就不对原理进行重复介绍,在这里我们来看看几种算法的差别:

  • 优化速度和内存使用
    • 降低了计算每个分割增益的成本。
    • 使用直方图减法进一步提高速度。
    • 减少内存使用。
    • 减少并行学习的计算成本。
  • 稀疏优化
    • 用离散的bin替换连续的值。如果#bins较小,则可以使用较小的数据类型(例如uint8_t)来存储训练数据 。
    • 无需存储其他信息即可对特征数值进行预排序 。
  • 精度优化
    • 使用叶子数为导向的决策树建立算法而不是树的深度导向。
    • 分类特征的编码方式的优化
    • 通信网络的优化
    • 并行学习的优化
    • GPU支持

LightGBM的优点:

1)更快的训练效率

2)低内存使用

3)更高的准确率

4)支持并行化学习

5)可以处理大规模数据

LightGBM参数说明

具体可见中文文档
1.核心参数:(括号内名称是别名)

  • objective(objective,app ,application):默认regression,用于设置损失函数
    • 回归问题:
      • L2损失:regression(regression_l2,l2,mean_squared_error,mse,l2_root,root_mean_squared_error,rmse)
      • L1损失:regression_l1(l1, mean_absolute_error, mae)
      • 其他损失:huber,fair,poisson,quantile,mape,gamma,tweedie
    • 二分类问题:二进制对数损失分类(或逻辑回归):binary
    • 多类别分类:
      • softmax目标函数: multiclass(softmax)
      • One-vs-All 目标函数:multiclassova(multiclass_ova,ova,ovr)
    • 交叉熵:
      • 用于交叉熵的目标函数(具有可选的线性权重):cross_entropy(xentropy)
      • 交叉熵的替代参数化:cross_entropy_lambda(xentlambda)
  • boosting :默认gbdt,设置提升类型,选项有gbdt,rf,dart,goss,别名:boosting_type,boost
    • gbdt(gbrt):传统的梯度提升决策树
    • rf(random_forest):随机森林
    • dart:多个加性回归树的DROPOUT方法 Dropouts meet Multiple Additive Regression Trees,参见:https://arxiv.org/abs/1505.01866
    • goss:基于梯度的单边采样 Gradient-based One-Side Sampling
  • data(train,train_data,train_data_file,data_filename):用于训练的数据或数据file
  • valid (test,valid_data,valid_data_file,test_data,test_data_file,valid_filenames):验证/测试数据的路径,LightGBM将输出这些数据的指标
  • num_iterations:默认=100,类型= INT
  • n_estimators:提升迭代次数,LightGBM构造用于多类分类问题的树num_class * num_iterations
  • learning_rate(shrinkage_rate,eta) :收缩率,默认=0.1
  • num_leaves(num_leaf,max_leaves,max_leaf) :默认=31,一棵树上的最大叶子数
  • tree_learner (tree,tree_type,tree_learner_type):默认=serial,可选:serial,feature,data,voting
    • serial:单台机器的 tree learner
    • feature:特征并行的 tree learner
    • data:数据并行的 tree learner
    • voting:投票并行的 tree learner
  • num_threads(num_thread, nthread):LightGBM 的线程数,为了更快的速度, 将此设置为真正的 CPU 内核数, 而不是线程的数量 (大多数 CPU 使用超线程来使每个 CPU 内核生成 2 个线程),当你的数据集小的时候不要将它设置的过大 (比如, 当数据集有 10,000 行时不要使用 64 线程),对于并行学习, 不应该使用全部的 CPU 内核, 因为这会导致网络性能不佳。
  • device(device_type):默认cpu,为树学习选择设备, 你可以使用 GPU 来获得更快的学习速度,可选cpu, gpu。
  • seed (random_seed,random_state):与其他种子相比,该种子具有较低的优先级,这意味着如果您明确设置其他种子,它将被覆盖。

2.用于控制模型学习过程的参数:

  • max_depth:限制树模型的最大深度. 这可以在 #data 小的情况下防止过拟合. 树仍然可以通过 leaf-wise 生长。
  • min_data_in_leaf: 默认=20,一个叶子上数据的最小数量. 可以用来处理过拟合。
  • min_sum_hessian_in_leaf(min_sum_hessian_per_leaf, min_sum_hessian, min_hessian):默认=1e-3,一个叶子上的最小 hessian 和. 类似于 min_data_in_leaf, 可以用来处理过拟合.
  • feature_fraction:default=1.0,如果 feature_fraction 小于 1.0, LightGBM 将会在每次迭代中随机选择部分特征. 例如, 如果设置为 0.8, 将会在每棵树训练之前选择 80% 的特征,可以用来加速训练,可以用来处理过拟合。
  • feature_fraction_seed:默认=2,feature_fraction 的随机数种子。
  • bagging_fraction(sub_row, subsample):默认=1,不进行重采样的情况下随机选择部分数据
  • bagging_freq(subsample_freq):bagging 的频率, 0 意味着禁用 bagging. k 意味着每 k 次迭代执行bagging
  • bagging_seed(bagging_fraction_seed) :默认=3,bagging 随机数种子。
  • early_stopping_round(early_stopping_rounds, early_stopping):默认=0,如果一个验证集的度量在 early_stopping_round 循环中没有提升, 将停止训练
  • lambda_l1(reg_alpha):L1正则化系数
  • lambda_l2(reg_lambda):L2正则化系数
  • min_split_gain(min_gain_to_split):执行切分的最小增益,默认=0.
  • cat_smooth:默认=10,用于分类特征,可以降低噪声在分类特征中的影响, 尤其是对数据很少的类别

3.度量参数:

  • metric:default={l2 for regression}, {binary_logloss for binary classification}, {ndcg for lambdarank}, type=multi-enum, options=l1, l2, ndcg, auc, binary_logloss, binary_error …
    • l1, absolute loss, alias=mean_absolute_error, mae
    • l2, square loss, alias=mean_squared_error, mse
    • l2_root, root square loss, alias=root_mean_squared_error, rmse
    • quantile, Quantile regression
    • huber, Huber loss
    • fair, Fair loss
    • poisson, Poisson regression
    • ndcg, NDCG
    • map, MAP
    • auc, AUC
    • binary_logloss, log loss
    • binary_error, 样本: 0 的正确分类, 1 错误分类
    • multi_logloss, mulit-class 损失日志分类
    • multi_error, error rate for mulit-class 出错率分类
    • xentropy, cross-entropy (与可选的线性权重), alias=cross_entropy
    • xentlambda, “intensity-weighted” 交叉熵, alias=cross_entropy_lambda
    • kldiv, Kullback-Leibler divergence, alias=kullback_leibler
    • 支持多指标, 使用 , 分隔
  • train_metric(training_metric, is_training_metric):默认=False,如果你需要输出训练的度量结果则设置 true

4.GPU 参数:

  • gpu_device_id:default为-1, 这个default意味着选定平台上的设备。
实例

博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值