2017年11月8日星期三

又一员大将离开马斯克的OpenAI自立门户,称工业机器人市场大有可为

编译 | 陈韵竹

编辑 | 吴欣

来源 | 纽约时报


继生成对抗网络(GANs)发明人 Ian Goodfellow、机器学习专家 Andrej Karpathy 在今年陆续离开 OpenAI 之后,来自比利时的 Pieter Abbeel 也辞职创业了。他在强化学习领域颇有建树,去年 4 月加入 OpenAI 之前,他是加州伯克利大学教授,长期深入在人工智能领域的研究工作。


OpenAI ,是一个独立运营的人工智能非营利性组织,由于发起人包括特斯拉首席执行官 Elon Musk 和其他硅谷著名人士,而备受关注。与 Abbeel 一起创业的,还有 OpenAI 另外两位研究人员—— Peter Chen、Rocky Duan,以及前微软研究人员 Tianhao Zhang。



这家新公司正努力地教机器人自学,以摆脱计算机程序的控制。(由左至右依次是 Embodied Intelligence CEO Peter Chen、董事长兼首席科学家 Pieter Abbeel、CTO Rocky Duan、研究员 Tianhao Zhang)


他们创办的这家公司名为 Embodied Intelligence ,专注于研究让机器人能够自主学习完成任务的复杂算法,想要让机器人通过人工智能技术学习,把自动化技术应用到世界范围内的工厂、仓库、甚至是家庭中。


例如,它们可以学会安装那些它们不曾安装过的汽车零件,或是在仓库场景下给甚至不曾见过的节日礼物分类,或是执行传统机器所不能执行的任务。


目前,该公司已经获得来自硅谷风险投资公司 Amplify Partners 以及其他资方的共 700 万美元投资。「现在,工业机器人的每一个动作都被规定得精准到了毫米量级。但是,大多数的现实问题其实不能用这种方法解决。你不仅要告诉机器人该做什么,而且要告诉它怎么学习。」不难看出,Amplify Partners 创始人 Sunil Dhaliwal 认同并期待 Embodied Intelligence 带来新方法。


「这主要是一个计算机科学的问题——一个人工智能的问题,」Abbeel 说道,「我们已经有了可以完成工作的硬件。」值得一提的是, 在这个泛人工智能领域,谷歌公司、布朗大学、卡内基梅隆大学,以及 Micropsi、 Prowler.io 等新兴创业公司的研究者们也在做类似工作。


上述观点成为 Abbeel 在加州大学伯克利分校的演讲主题,他播放了一段机器人做家务的录像带。在这段录制于 2008 年的视频中,机器人已经能够完成诸如扫地、清理橱柜、安装洗碗机等任务。最后,它甚至打开了一罐啤酒,递给了坐在沙发上的小伙子。只不过在当时,这一切都要被一个工程师远程操控着,由人来决定机器人的每一个动作。


Abbeel 想用这个视频告诉人们,机器人的硬件系统已经足够灵活,能完成模仿人类的大部分复杂行为。而真正的挑战在于,它需要一种能够指导硬件行为的软件,而不是依赖于工程师的操控。




的确,大量机器人已经在承担工厂和仓库中的部分自动化工作。例如,机器人能在亚马逊公司庞大的配送中心里移动箱子。但目前完成这些工作的前提是,公司必须为这些机器的每一个具体工作进行编程。


毫无疑问,只有在这些机器人通过自学掌握更多任务处理方法时,才可能挖掘出其他可能的应用。而 Abbeel 的创始团队正在研究一种被称为强化学习的算法,这种算法让机器人通过反复不断的尝试和试错中学习如何执行任务。在《纽约时报》采访中,他说:「我们现在研发出了可教的机器人。」


谷歌旗下人工智能实验室 DeepMind 的做法也说明了其中道理,他们的研究员使用强化学习方法建立了 Alpha Go,打败了所有人类围棋玩家。从本质上说,这个机器就是通过一次又一次的自我博弈掌握了这个极其复杂的游戏。


工业界和学术界的其他研究人员表示,类似的算法同样可以让机器人学习处理与行动相关的任务。例如,通过反复尝试打开一扇门,一个机器人能够学到哪些特定的动作能够成功将门打开,而哪些动作不能。


类似于谷歌实验室和西北大学实验室,Embodied Intelligence 正在使用多种其他机器学习技术强化这些算法。最值得注意的是,这个创业公司正在探索一种称为模仿学习(Imitation Learning)的学习方式。相较于传统的强化学习任务,模仿学习在机器人、自然语言处理等多步决策问题中有更好的表现。




公司正在使用这种方法,训练一个两臂机器人从桌上拾起塑料管。Abbeel 和他的同事们戴着 VR 头显,拿着动作追踪器,不断地在数字世界中向机器人展示如何完成任务。然后,机器人可以从这些数据中学习。


「我们收集了人类工作时的数据,」Peter Chen 说,「然后,我们就可以训练机器模仿人类。」


尽管这些机器学习方法在过去几年刚刚取得一些成果,让很多人相信,它们将会彻底改变机器人领域。但也有不少研究者质疑,机器学习对机器人领域的改善作用到底有多大,他们认为,研究者和新闻媒体对此吹捧过度。


不过,作为该领域世界顶尖研究者之一,Abbeel 相信自己的创业公司能够迅速地将人工智能技术推广到像汽车工业这样的制造业中去。而那些机器人领域使用传统方法仍没能解决的问题,恰好是 Embodied Intelligence 想要攻克的方向。


毕竟机器学习先驱 Geoff Hinton 也曾说:「很明显,机器学习对于建立灵活、机敏的机器人至关重要。」


]]> 原文: http://ift.tt/2AwqfFQ
RSS Feed

机器知心

IFTTT

2017年11月7日星期二

如何使用TensorFlow和VAE模型生成手写数字

本文详细介绍了如何使用 TensorFlow 实现变分自编码器(VAE)模型,并通过简单的手写数字生成案例一步步引导读者实现这一强大的生成模型。


全部 VAE 代码:http://ift.tt/2j7mq5A


自编码器是一种能够用来学习对输入数据高效编码的神经网络。若给定一些输入,神经网络首先会使用一系列的变换来将数据映射到低维空间,这部分神经网络就被称为编码器。


然后,网络会使用被编码的低维数据去尝试重建输入,这部分网络称之为解码器。我们可以使用编码器将数据压缩为神经网络可以理解的类型。然而自编码器很少用做这个目的,因为通常存在比它更为有效的手工编写的算法(例如 jpg 压缩)。

此外,自编码器还被经常用来执行降噪任务,它能够学会如何重建原始图像。


什么是变分自编码器?


有很多与自编码器相关的有趣应用。其中之一被称为变分自编码器(variational autoencoder)。使用变分自编码器不仅可以压缩数据--还能生成自编码器曾经遇到过的新对象。


使用通用自编码器的时候,我们根本不知道网络所生成的编码具体是什么。虽然我们可以对比不同的编码对象,但是要理解它内部编码的方式几乎是不可能的。这也就意味着我们不能使用编码器来生成新的对象。我们甚至连输入应该是什么样子的都不知道。

而我们用相反的方法使用变分自编码器。我们不会尝试着去关注隐含向量所服从的分布,只需要告诉网络我们想让这个分布转换为什么样子就行了。


通常情况,我们会限制网络来生成具有单位正态分布性质的隐含向量。然后,在尝试生成数据的时候,我们只需要从这种分布中进行采样,然后把样本喂给解码器就行,解码器会返回新的对象,看上去就和我们用来训练网络的对象一样。

下面我们将介绍如何使用 Python 和 TensorFlow 实现这一过程,我们要教会我们的网络来画 MNIST 字符。


第一步加载训练数据


首先我们来执行一些基本的导入操作。TensorFlow 具有非常便利的函数来让我们能够很容易地访问 MNIST 数据集。


import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt %matplotlib inlinefrom tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST_data')

定义输入数据和输出数据


MNIST 图像的维度是 28*28 像素,只有单色通道。我们的输入数据 X_in 是一批一批的 MNIST 字符,网络会学习如何重建它们。然后在一个占位符 Y 中输出它们,输出和输入具有相同的维度。


Y_flat 将会在后面计算损失函数的时候用到,keep_prob 将会在应用 dropout 的时候用到(作为一种正则化的方法)。在训练的过程中,它的值会设为 0.8,当生成新数据的时候,我们不使用 dropout,所以它的值会变成 1。


lrelu 函数需要自及定义,因为 TensorFlow 中并没有预定义一个 Leaky ReLU 函数。


tf.reset_default_graph()  batch_size = 64X_in = tf.placeholder(dtype=tf.float32, shape=[None, 28, 28], name='X') Y    = tf.placeholder(dtype=tf.float32, shape=[None, 28, 28], name='Y') Y_flat = tf.reshape(Y, shape=[-1, 28 * 28]) keep_prob = tf.placeholder(dtype=tf.float32, shape=(), name='keep_prob')  dec_in_channels = 1n_latent = 8reshaped_dim = [-1, 7, 7, dec_in_channels] inputs_decoder = 49 * dec_in_channels / 2def lrelu(x, alpha=0.3):    return tf.maximum(x, tf.multiply(x, alpha))


定义编码器


因为我们的输入是图像,所以使用一些卷积变换会更加合理。最值得注意的是我们在编码器中创建了两个向量,因为编码器应该创建服从高斯分布的对象。

  • 一个是均值向量
  • 一个是标准差向量

在后面你会看到,我们是如何「强制」编码器来保证它确实生成 了服从正态分布的数据点,我们可以把将会被输入到解码器中的编码值表示为 z。在计算损失函数的时候,我们会需要我们所选分布的均值和标准差。


def encoder(X_in, keep_prob):     activation = lrelu    with tf.variable_scope("encoder", reuse=None):         X = tf.reshape(X_in, shape=[-1, 28, 28, 1])         x = tf.layers.conv2d(X, filters=64, kernel_size=4, strides=2, padding='same', activation=activation)         x = tf.nn.dropout(x, keep_prob)         x = tf.layers.conv2d(x, filters=64, kernel_size=4, strides=2, padding='same', activation=activation)         x = tf.nn.dropout(x, keep_prob)         x = tf.layers.conv2d(x, filters=64, kernel_size=4, strides=1, padding='same', activation=activation)         x = tf.nn.dropout(x, keep_prob)         x = tf.contrib.layers.flatten(x)         mn = tf.layers.dense(x, units=n_latent)         sd       = 0.5 * tf.layers.dense(x, units=n_latent)                     epsilon = tf.random_normal(tf.stack([tf.shape(x)[0], n_latent]))          z  = mn + tf.multiply(epsilon, tf.exp(sd))                 return z, mn, sd


定义解码器


解码器不会关心输入值是不是从我们定义的某个特定分布中采样得到的。它仅仅会尝试重建输入图像。最后,我们使用了一系列的转置卷积(transpose convolution)。


def decoder(sampled_z, keep_prob):    with tf.variable_scope("decoder", reuse=None):         x = tf.layers.dense(sampled_z, units=inputs_decoder, activation=lrelu)         x = tf.layers.dense(x, units=inputs_decoder * 2 + 1, activation=lrelu)         x = tf.reshape(x, reshaped_dim)         x = tf.layers.conv2d_transpose(x, filters=64, kernel_size=4, strides=2, padding='same', activation=tf.nn.relu)         x = tf.nn.dropout(x, keep_prob)         x = tf.layers.conv2d_transpose(x, filters=64, kernel_size=4, strides=1, padding='same', activation=tf.nn.relu)         x = tf.nn.dropout(x, keep_prob)         x = tf.layers.conv2d_transpose(x, filters=64, kernel_size=4, strides=1, padding='same', activation=tf.nn.relu)                  x = tf.contrib.layers.flatten(x)         x = tf.layers.dense(x, units=28*28, activation=tf.nn.sigmoid)         img = tf.reshape(x, shape=[-1, 28, 28])        return img


现在,我们将两部分连在一起。


sampled, mn, sd = encoder(X_in, keep_prob) dec = decoder(sampled, keep_prob)


计算损失函数,并实施一个高斯隐藏分布


为了计算图像重构的损失函数,我们简单地使用了平方差(这有时候会使图像变得有些模糊)。这个损失函数还结合了 KL 散度,这确保了我们的隐藏值将会从一个标准分布中采样。关于这个主题,如果想要了解更多,可以看一下这篇文章(http://ift.tt/2AsndlK


unreshaped = tf.reshape(dec, [-1, 28*28]) img_loss = tf.reduce_sum(tf.squared_difference(unreshaped, Y_flat), 1) latent_loss = -0.5 * tf.reduce_sum(1.0 + 2.0 * sd - tf.square(mn) - tf.exp(2.0 * sd), 1) loss = tf.reduce_mean(img_loss + latent_loss) optimizer = tf.train.AdamOptimizer(0.0005).minimize(loss) sess = tf.Session() sess.run(tf.global_variables_initializer())

训练网络


现在我们终于可以训练我们的 VAE 了!


每隔 200 步,我们会看一下当前的重建是什么样子的。大约在处理了 2000 次迭代后,大多数重建看上去是挺合理的。


for i in range(30000):     batch = [np.reshape(b, [28, 28]) for b in mnist.train.next_batch(batch_size=batch_size)[0]]     sess.run(optimizer, feed_dict = {X_in: batch, Y: batch, keep_prob: 0.8})             if not i % 200:         ls, d, i_ls, d_ls, mu, sigm = sess.run([loss, dec, img_loss, dst_loss, mn, sd], feed_dict = {X_in: batch, Y: batch, keep_prob: 1.0})         plt.imshow(np.reshape(batch[0], [28, 28]), cmap='gray')         plt.show()         plt.imshow(d[0], cmap='gray')         plt.show()         print(i, ls, np.mean(i_ls), np.mean(d_ls))


生成新数据


最惊人的是我们现在可以生成新的字符了。最后,我们仅仅是从一个单位正态分布里面采集了一个值,输入到解码器。生成的大多数字符都和人类手写的是一样的。


randoms = [np.random.normal(0, 1, n_latent) for _ in range(10)] imgs = sess.run(dec, feed_dict = {sampled: randoms, keep_prob: 1.0}) imgs = [np.reshape(imgs[i], [28, 28]) for i in range(len(imgs))]for img in imgs:     plt.figure(figsize=(1,1))     plt.axis('off')     plt.imshow(img, cmap='gray')


一些自动生成的字符。


总结


这是关于 VAE 应用一个相当简单的例子。但是可以想象一下更多的可能性!神经网络可以学习谱写音乐,它们可以自动地创建对书籍、游戏的描述。借用创新思维,VAE 可以为一些新颖的项目开创空间。


原文链接:http://ift.tt/2z1XoeO



]]> 原文: http://ift.tt/2jbjvcl
RSS Feed

机器知心

IFTTT

为什么XGBoost在机器学习竞赛中表现如此卓越?

挪威科技大学 Didrik Nielsen 的硕士论文《使用 XGBoost 的树提升:为什么 XGBoost 能赢得「每一场」机器学习竞赛?(Tree Boosting With XGBoost - Why Does XGBoost Win "Every" Machine Learning Competition?)》研究分析了 XGBoost 与传统 MART 的不同之处以及在机器学习竞赛上的优势。机器之心技术分析师对这篇长达 110 页的论文进行了解读,提炼出了其中的要点和核心思想,汇成此篇。本文原文发表在机器之心英文官网上。

引言


tree boosting(树提升)已经在实践中证明可以有效地用于分类和回归任务的预测挖掘。


之前很多年来,人们所选择的树提升算法一直都是 MART(multiple additive regression tree/多重累加回归树)。但从 2015 年开始,一种新的且总是获胜的算法浮出了水面:XGBoost。这种算法重新实现了树提升,并在 Kaggle 和其它数据科学竞赛中屡获佳绩,因此受到了人们的欢迎。

在《Tree Boosting With XGBoost - Why Does XGBoost Win "Every" Machine Learning Competition?》这篇论文中,来自挪威科技大学的 Didrik Nielsen 研究调查了:

  1. XGBoost 与传统 MART 的不同之处
  2. XGBoost 能赢得「每一场」机器学习竞赛的原因

这篇论文分成三大部分:

  1. 回顾统计学习的一些核心概念
  2. 介绍 boosting 并以函数空间中数值优化的方式对其进行解释;进一步讨论更多树方法以及树提升方法的核心元素
  3. 比较 MART 和 XGBoost 所实现的树提升算法的性质;解释 XGBoost 受欢迎的原因

统计学习的基本概念


这篇论文首先介绍了监督学习任务并讨论了模型选择技术。


机器学习算法的目标是减少预期的泛化误差,这也被称为风险(risk)。如果我们知道真实的分布 P(x,y),那么风险的最小化就是一个可以通过优化算法解决的最优化任务。但是,我们并不知道真实分布,只是有一个用于训练的样本集而已。我们需要将其转换成一个优化问题,即最小化在训练集上的预期误差。因此,由训练集所定义的经验分布会替代真实分布。上述观点可以表示成下面的统计学公式:

其中  是模型的真实风险 R(f) 的经验估计。L(.) 是一个损失函数,比如平方误差损失函数(这是回归任务常用的损失函数),其它损失函数可以在这里找到:http://ift.tt/2zmFCmm 是样本的数量。

当 n 足够大时,我们有:

ERM(经验风险最小化)是一种依赖于经验风险的最小化的归纳原理(Vapnik, 1999)。经验风险最小化运算 f hat 是目标函数的经验近似,定义为:

其中 F 属于某个函数类,并被称为某个模型类(model class),比如常数、线性方法、局部回归方法(k-最近邻、核回归)、样条函数等。ERM 是从函数集 F 中选择最优函数 f hat 的标准。


这个模型类和 ERM 原理可以将学习问题转变成优化问题。模型类可以被看作是候选的解决方案函数,而 ERM 则为我们提供了选择最小化函数的标准。


针对优化问题的方法有很多,其中两种主要方法是梯度下降法和牛顿法;MART 和 XGBoost 分别使用了这两种方法。


这篇论文也总结了常见的学习方法:


1. 常数

2. 线性方法

3. 局部最优方法

4. 基函数扩展:显式非线性项、样条、核方法等

5. 自适应基函数模型:GAM(广义相加模型)、神经网络、树模型、boosting


另一个机器学习概念是模型选择(model selection),这要考虑不同的学习方法和它们的超参数。首要的问题一直都是:增加模型的复杂度是否更好?而答案也总是与模型自身的泛化性能有关。如下图 1 所示,我们也许可以在模型更加复杂的同时得到更好的表现(避免欠拟合),但我们也会失去泛化性能(过拟合):


图 1:泛化性能 vs 训练误差


为平方损失使用预期条件风险的经典的偏置-方差分解(bias-variance decomposition),我们可以观察风险相对于复杂度的变化:


图 2:预期风险 vs 方差 vs 偏置


为此通常使用的一种技术是正则化(regularization)。通过隐式和显式地考虑数据的拟合性和不完善性,正则化这种技术可以控制拟合的方差。它也有助于模型具备更好的泛化性能。


不同的模型类测量复杂度的方法也不一样。LASSO 和 Ridge(Tikhonov regularization)是两种常用于线性回归的测量方法。我们可以将约束(子集化、步进)或惩罚(LASSO、Ridge)直接应用于复杂度测量。


理解 Boosting、树方法和树提升


Boosting


boosting 是一种使用多个更简单的模型来拟合数据的学习算法,它所用的这些更简单的模型也被称为基本学习器(base learner)或弱学习器(weak learner)。其学习的方法是使用参数设置一样或稍有不同的基本学习器来自适应地拟合数据。


Freund 和 Schapire (1996) 带来了第一个发展:AdaBoost。实际上 AdaBoost 是最小化指数损失函数,并迭代式地在加权的数据上训练弱学习器。研究者也提出过最小化对数损失的二阶近似的新型 boosting 算法:LogitBoost。


Breiman (1997a,b 1998) 最早提出可以将 boosting 算法用作函数空间中的数值优化技术。这个想法使得 boosting 技术也可被用于回归问题。这篇论文讨论了两种主要的数值优化方法:梯度提升和牛顿提升(也被称为二阶梯度提升或 Hessian boosting,因为其中应用了 Hessian 矩阵)。下面,让我们一步一步了解 boosting 算法。


boosting 拟合同一类的集成模型(ensemble model):

其可以被写成自适应基函数模型:

其中 f_0(x)=θ_0 且 f_m(x)=θ_m*Φ_m(x),m=1,…,M,Φm 是按顺序累加的基本函数,可用于提升当前模型的拟合度。

因此,大多数 boosting 算法都可以看作是在每次迭代时或准确或近似地求解

所以,AdaBoost 就是为指数损失函数求解上述等式,其约束条件为:Φm 是 A={-1,1} 的分类器。而梯度提升或牛顿提升则是为任意合适的损失函数近似求解上述等式。

梯度提升和牛顿提升的算法如下:


  • 是梯度
  • 是使用数据学习到的弱学习器
  • 是经验 Hessian

  • 梯度提升:是由线搜索(line search)确定的步长
  • 牛顿提升: h_m(x) 是经验 Hessian


最常用的基本学习器是回归树(比如 CART),以及分量形式的线性模型(component-wise linear model)或分量形式的平滑样条(component-wise smoothing spline)。基本学习器的原则是要简单,即有很高的偏置,但方差很低。

boosting 方法中的超参数有:


  1. 迭代次数 M:M 越大,过拟合的可能性就越大,因此需要验证集或交叉验证集。
  2. 学习率 η :降低学习率往往会改善泛化性能,但同时也会让 M 增大,如下图所示。


在 Boston Housing 数据集上的不同学习率的样本外(out-of-sample)RMSE


树方法


树模型是简单和可解释的模型。它们的预测能力确实有限,但将多个树模型组合到一起(比如 bagged trees、随机森林或在 boosting 中),它们就可以变成一种强大的预测模型。

我们可以将树模型看作是将特征空间分割成几个不同的矩形和非重叠区域集合,然后它可以拟合一些简单的模型。下图给出了使用 Boston Housing 数据得到的可视化结果:



终端节点的数量和树的深度可以看作是树模型的复杂度度量。为了泛化这种模型,我们可以在复杂度度量上轻松地应用一个复杂度限制,或在终端节点的数量或叶权重的惩罚项上应用一个惩罚(XGBoost 使用的这种方法)。


因为学习这种树的结构是 NP 不完全的,所以学习算法往往会计算出一个近似的解。这方面有很多不同的学习算法,比如 CART(分类和回归树)、C4.5 和 CHAID。这篇论文描述了 CART,因为 MART 使用的 CART,XGBoost 也实现了一种与 CART 相关的树模型。

CART 以一种自上而下的方式生长树。通过考虑平行于坐标轴的每次分割,CART 可以选择最小化目标的分割。在第二步中,CART 会考虑每个区域内每次平行的分割。在这次迭代结束时,最好的分割会选出。CART 会重复所有这些步骤,直到达到停止标准。

给定一个区域 Rj,学习其权重 wj 通常很简单。令 Ij 表示属于区域 Rj 的索引的集合,即 xi∈Rj,其中 i∈Ij。


其权重是这样估计的:

对于一个树模型 f_hat,经验风险为:

其中我们令 L_j hat 表示节点 j 处的累积损失。在学习过程中,当前树模型用 f_before hat 和 f_after hat 表示。


我们可以计算所考虑的分割所带来的增益:

对于每一次分割,每个可能节点的每个可能分割都会计算这种增益,再取其中最大的增益。


现在让我们看看缺失值。CART 会使用替代变量(surrogate variable)来处理缺失值,即对于每个预测器,我们仅使用非缺失数据来寻找分割,然后再基于主分割寻找替代预测因子,从而模拟该分割。比如,假设在给定的模型中,CART 根据家庭收入分割数据。如果一个收入值不可用,那么 CART 可能会选择教育水平作为很好的替代。


但 XGBoost 是通过学习默认方向来处理缺失值。XGBoost 会在内部自动学习当某个值缺失时,最好的方向是什么。这可以被等价地看作是根据训练损失的减少量而自动「学习」缺失值的最佳插补值。


根据类别预测器,我们可以以两种方式处理它们:分组类别或独立类别。CART 处理的是分组类别,而 XGBoost 需要独立类别(one-hot 编码)。


这篇论文以列表的形式总结了树模型的优缺点。优点(Hastie et al., 2009; Murphy, 2012):


  • •容易解释
  • •可以相对快地构建
  • •可以自然地处理连续和分类数据
  • •可以自然地处理缺失数据
  • •对输入中的异常值是稳健的
  • •在输入单调变换时是不变的
  • •会执行隐式的变量选择
  • •可以得到数据中的非线性关系
  • •可以得到输入之间的高阶交互
  • •能很好地扩展到大型数据集


缺点(Hastie et al., 2009; Kuhn and Johnson, 2013; Wei-Yin Loh, 1997; Strobl et al., 2006):


  • •往往会选择具有更高数量的不同值的预测器
  • •当预测器具有很多类别时,可能会过拟合
  • •不稳定,有很好的方差
  • •缺乏平滑
  • •难以获取叠加结构
  • •预测性能往往有限


树提升


在上述发展的基础上,现在我们将 boosting 算法与基本学习器树方法结合起来。提升后的树模型可以看作是自适应基函数模型,其中的基函数是回归树:

提升树模型(boosting tree model)是多个树 fm 的和,所以也被称为树集成(tree ensemble)或叠加树模型(additive tree model)。因此它比单个树模型更加平滑,如下图所示:

拟合 Boston Housing 数据的叠加树模型的可视化


在提升树模型上实现正则化的方法有很多:


1. 在基函数扩展上进行正则化

2. 在各个树模型上进行正则化

3. 随机化


一般来说,提升树往往使用很浅的回归树,即仅有少数终端节点的回归树。相对于更深度的树,这样的方差较低,但偏置更高。这可以通过应用复杂度约束来完成。


XGBoost 相对于 MART 的优势之一是复杂度的惩罚,这对叠加树模型而言并不常见。目标函数的惩罚项可以写成:

其中第一项是每个单个树的终端节点的数量,第二项是在该项权重上的 L2 正则化,最后一项是在该项权重上的 L1 正则化。


Friedman(2002) 最早引入了随机化,这是通过随机梯度下降实现的,其中包括在每次迭代时进行行子采样(row subsampling)。随机化有助于提升泛化性能。子采样的方法有两种:行子采样与列子采样(column subsampling)。MART 仅包含行子采样(没有替代),而 XGBoost 包含了行子采样和列子采样两种。


正如前面讨论的那样,MART 和 XGBoost 使用了两种不同的 boosting 算法来拟合叠加树模型,分别被称为 GTB(梯度树提升)和 NTB(牛顿树提升)。这两种算法都是要在每一次迭代 m 最小化:

其基函数是树:

其一般步骤包含 3 个阶段:


1. 确定一个固定的候选树结构的叶权重 ;

2. 使用前一阶段确定的权重,提出不同的树结构,由此确定树结构和区域;

3. 一旦树结构确定,每个终端节点中的最终叶权重(其中 j=1,..,T)也就确定了。


算法 3 和 4 使用树作为基函数,对算法 1 和 2 进行了扩展:


XGBoost 和 MART 的差异


最后,论文对两种树提升算法的细节进行了比较,并试图给出 XGBoost 更好的原因。


算法层面的比较


正如之前的章节所讨论的那样,XGBoost 和 MART 都是要通过简化的 FSAM(Forward Stage Additive Modelling/前向阶段叠加建模)求解同样的经验风险最小化问题:

即不使用贪婪搜索,而是每次添加一个树。在第 m 次迭代时,使用下式学习新的树:

XGBoost 使用了上面的算法 3,即用牛顿树提升来近似这个优化问题。而 MART 使用了上面的算法 4,即用梯度树提升来做这件事。这两种方法的不同之处首先在于它们学习树结构的方式,然后还有它们学习分配给所学习的树结构的终端节点的叶权重的方式。

再看看这些算法,我们可以发现牛顿树提升有 Hessian 矩阵,其在确定树结构方面发挥了关键性的作用,XGBoost:

而使用了梯度树提升的 MART 则是:

然后,XGBoost 可以直接这样定义牛顿树提升的叶权重:

使用梯度树提升的 MART 则这样定义:


总结一下,XGBoost 使用的 Hessian 是一种更高阶的近似,可以学习到更好的树结构。但是,MART 在确定叶权重上表现更好,但却是对准确度更低的树结构而言。


在损失函数的应用性方面,牛顿树提升因为要使用 Hessian 矩阵,所以要求损失函数是二次可微的。所以它在选择损失函数上要求更加严格,必须要是凸的。


当 Hessian 每一处都等于 1 时,这两种方法就是等价的,这就是平方误差损失函数的情况。因此,如果我们使用平方误差损失函数之外的任何损失函数,在牛顿树提升的帮助下,XGBoost 应该能更好地学习树结构。只是梯度树提升在后续的叶权重上更加准确。因此无法在数学上对它们进行比较。


尽管如此,该论文的作者在两个标准数据集上对它们进行了测试:Sonar 和 Ionosphere(Lichman, 2013)。这个实证比较使用了带有 2 个终端节点的树,没有使用其它正则化,而且这些数据也没有分类特征和缺失值。梯度树提升还加入了一个线搜索(line search),如图中红色线所示。


这个比较图说明这两种方法都能无缝地执行。而且线搜索确实能提升梯度提升树的收敛速度。


正则化比较


正则化参数实际上有 3 类:


1.boosting 参数:树的数量 M 和学习率η

2. 树参数:在单个树的复杂度上的约束和惩罚

3. 随机化参数:行子采样和列子采样


两种 boosting 方法的主要差别集中在树参数以及随机化参数上。


对于树参数,MART 中的每个树都有同样数量的终端节点,但 XGBoost 可能还会包含终端节点惩罚 γ,因此其终端节点的数量可能会不一样并且在最大终端节点数量的范围内。XGBoost 也在叶权重上实现了 L2 正则化,并且还将在叶权重上实现 L1 正则化。

在随机化参数方面,XGBoost 提供了列子采样和行子采样;而 MART 只提供了行子采样。


为什么 XGBoost 能赢得「每一场」竞赛?


通过使用模拟数据,论文作者首次表明树提升可以被看作是自适应地确定局部邻域。


使用

生成

然后使用局部线性回归(使用了两种不同灵活度的拟合)来拟合它:

然后使用平滑样条函数(使用了两种不同灵活度的拟合)来拟合它:

现在我们尝试提升的树桩(boosted tree stump)(两个终端节点)拟合:

本论文详细说明了权重函数影响拟合的确定的方式,并且表明树提升可以被看作是直接在拟合阶段考虑偏置-方差权衡。这有助于邻域保持尽可能大,以避免方差不必要地增大,而且只有在复杂结构很显然的时候才会变小。

尽管当涉及到高维问题时,树提升「打败了」维度的诅咒(curse of dimensionality),而没有依赖任何距离指标。另外,数据点之间的相似性也可以通过邻域的自适应调整而从数据中学习到。这能使模型免疫维度的诅咒。

另外更深度的树也有助于获取特征的交互。因此无需搜索合适的变换。


因此,是提升树模型(即自适应的确定邻域)的帮助下,MART 和 XGBoost 一般可以比其它方法实现更好的拟合。它们可以执行自动特征选择并且获取高阶交互,而不会出现崩溃。

通过比较 MART 和 XGBoost,尽管 MART 确实为所有树都设置了相同数量的终端节点,但 XGBoost 设置了 Tmax 和一个正则化参数使树更深了,同时仍然让方差保持很低。相比于 MART 的梯度提升,XGBoost 所使用的牛顿提升很有可能能够学习到更好的结构。XGBoost 还包含一个额外的随机化参数,即列子采样,这有助于进一步降低每个树的相关性。


机器之心分析师的看法


这篇论文从基础开始,后面又进行了详细的解读,可以帮助读者理解提升树方法背后的算法。通过实证和模拟的比较,我们可以更好地理解提升树相比于其它模型的关键优势以及 XGBoost 优于一般 MART 的原因。因此,我们可以说 XGBoost 带来了改善提升树的新方法。

本分析师已经参与过几次 Kaggle 竞赛了,深知大家对 XGBoost 的兴趣以及对于如何调整 XGBoost 的超参数的广泛深度的讨论。相信这篇文章能够启迪和帮助初学者以及中等水平的参赛者更好地详细理解 XGBoost。


参考文献

  • Chen, T. and Guestrin, C. (2016). Xgboost: A scalable tree boosting system. In Proceedings of the 22Nd ACM SIGKDD International Conference on Knowl- edge Discovery and Data Mining, KDD 』16, pages 785–794, New York, NY, USA. ACM.
  • Freund, Y. and Schapire, R. E. (1996). Experiments with a new boosting algorithm. In Saitta, L., editor, Proceedings of the Thirteenth International Conference on Machine Learning (ICML 1996), pages 148–156. Morgan Kaufmann.
  • Friedman, J. H. (2002). Stochastic gradient boosting. Comput. Stat. Data Anal., 38(4):367–378.
  • Hastie, T., Tibshirani, R., and Friedman, J. (2009). The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition. Springer Series in Statistics. Springer.
  • Kuhn, M. and Johnson, K. (2013). Applied Predictive Modeling. SpringerLink : Bu ̈cher. Springer New York.
  • Lichman, M. (2013). UCI machine learning repository.
  • Murphy, K. P. (2012). Machine Learning: A Probabilistic Perspective. The MIT Press.
  • Strobl, C., laure Boulesteix, A., and Augustin, T. (2006). Unbiased split selection for classification trees based on the gini index. Technical report.
  • Vapnik, V. N. (1999). An overview of statistical learning theory. Trans. Neur. Netw., 10(5):988–999.
  • Wei-Yin Loh, Y.-S. S. (1997). Split selection methods for classification trees. Statistica Sinica, 7(4):815–840.
  • Wikipedia::Lasso. http://ift.tt/1RPIrQe
  • Wikipedia::Tikhonov regularization. http://ift.tt/1jaI5PF


]]> 原文: http://ift.tt/2znY1PE
RSS Feed

机器知心

IFTTT