AI 之旅:启程

“All models are wrong, but some are useful.”程序员

— George Box算法

机器学习(Machine Learning)最大的魅力在于改变了开发者的思考方式,开发者不须要再费力地给程序编写固定的逻辑指令,而是让程序对大量的未知数据进行分析思考,而后学会如何去处理未知的输入,如何对结果进行预测,如何采起动做服务器

基本术语

  • 监督式机器学习(Supervised machine learning): 机器学习系统学习如何组合输入以对 前所未见的数据 产生 有用的预测
  • 标签(Label): 指咱们正在预测的东西或者说试图预测的目标,如小麦未来的价格、照片中的动物种类、邮件是否是垃圾邮件等,是简单线性回归的 y
  • 特征(Feature): 指从输入数据中提取的供机器学习系统使用的信息,是咱们表示数据的方式,如邮件的发件人地址、邮件内容,是线性回归的 x 值,一个复杂的机器学习系统可能须要成千上万个特征
  • 样本(Example): 指一份数据,样本分为有标签样本和无标签样本。有标签样本包含特征和标签 labeled examples: {features, label}: (x, y),如这封被用户主动标记为垃圾邮件的邮件。无标签样本只有特征没有标签 unlabeled examples: {features, ?}: (x, ?)。咱们的目的就是经过大量的有标签样本去训练模型,让它可以对任何无标签的样本进行标签的预测
  • 模型(Model): 是执行预测的工具,定义了特征和标签之间的关系,如垃圾邮件监测模型会将某些特征和垃圾邮件标签紧密联系起来,模型有两个阶段: 训练和推理
  • 训练(Training): 建立模型或者让模型学习,也就是说向模型提供有标签样本,从而让模型逐渐学习到特征和标签之间的关系
  • 推理(Inference): 将训练后的模型应用于无标签样本,也就是说用这个训练后的模型去作有用的预测的过程
  • 回归模型(Regression model): 预测的是连续的值,如用户点击这条广告的几率、小麦的价格
  • 分类模型(Classification mode): 预测的是离散的值,如这封邮件是否是垃圾邮件、这张图片中的动物是什么动物

线性回归

在统计学中,线性回归(Linear Regression)是对 标量响应(因变量) 和 一到多个解释变量(自变量) 之间的关系进行建模的一种线性方法,只有一个解释变量时被称为简单线性回归,有多个解释变量时被称为 multiple 线性回归,预测多个相关因变量时被称为 multivariate 线性回归
网络

linear regression
能够看出每分钟蟋蟀的叫声和温度的关系是线性的关系,咱们就能够随便画一条直线去拟合:

y = mx + b
  • y 指温度(试图预测的值)
  • m 指直线的斜率
  • x 指每分钟虫鸣数(输入的特征值)
  • b 指 y 轴截距

在统计学中,肯定函数中的参数时一般采用 “最小二乘法”,这是最多见最简单的尽量减少偏差的拟合方法。在机器学习中,这个关系模型的表示也差很少:app

y' = b + w_1x_1
  • y' 指预测的标签(理想输出)
  • b 指误差(y 轴截距),有时被称为 w_0
  • w_1 指特征 1 的权重,和传统直线方程中的斜率 m 是一个概念
  • x_1 指特征(一个已知输入)

要想推理(预测)一个新的每分钟虫鸣数 x_1 对应的温度 y',只须要把 x_1 带入这个模型便可
这个预测模型只有每分钟虫鸣数一个特征,而一个复杂的模型每每有多个特征和对应的权重,如: y' = b + w_1x_1 + w_2x_2 + w_3x_3
建立或训练模型的过程就是寻找最好的权重和误差值的过程(肯定最好的 bw_1 的过程),而在监督式学习中,机器学习算法经过“考察大量样本以便尝试寻找一个最小化损失的模型”来构建模型,这个过程也被称为经验式风险最小化(empirical risk minimization)
损失就是指对糟糕预测的惩罚,是表示模型在一个样本上预测的糟糕程度,是个数值,若是模型的预测是完美的,那么损失就是零,不然损失就很大,咱们能够建立一个数学函数(损失函数)去有意义地汇总各个损失
机器学习

loss
蓝色线表示预测,红色箭头表示各个损失,很显然右侧的要比左侧的平均损失更小。一个最多见的损失函数是平方损失函数(squared loss / L_2 loss),一个样本的平方损失就是标签和预测值差的平方,即 (y - y')^2。整个数据集每一个样本的平均平方损失被称为 均方偏差 MSE(mean squared error),就是把每一个样本的平方损失加起来除以样本数:

MSE = \frac{1}{N} \sum_{(x,y)\in D} (y - prediction(x))^2

下降损失

如何快速高效地肯定最好(如使 MSE 最小)的 bw_1 的值呢?最简单的办法就是先胡乱猜一个 bw_1 的值,计算一下损失,而后调整一下 bw_1 的值,计算损失,比较一下这两次损失再决定如何调整 bw_1 的值(若是损失变小了说明调整的方向对了,继续按照当前方向调整就好了,若是损失变大了就要考虑改变调整的方向了),理论上不断地迭代试错下去就能找到最好的 bw_1 的值
函数

iterative approach
使用迭代法(iterative approach)不单是由于它简单直接,更是由于它在面对大型数据集时仍然表现良好
对于线性回归来讲,选择哪一个点做为起始点并非很重要,好比咱们彻底能够选择 b = 0, w_1 = 0 做为迭代的起始点。图中绿色的框是最关键的部分,正是它决定了迭代的方向,即新的 bw_1 的值,迭代到整体损失再也不变化或者变化极其缓慢为止,这时表示模型已收敛(converged)
假设咱们有充足的时间和计算资源去计算全部 w_1 的可能值和对应的损失,对于咱们一直研究的回归问题,损失 和 w_1 的关系图形始终是凸形(convex)的,或者说关系图形是个碗形:
convex
咱们的目标就是不断改变 w_1 的值直到找到惟一的损失最小的那个最低点(斜率为 0),即损失函数收敛的位置,迭代的策略有不少种,最多见的就是梯度降低法(gradient descent)
gradient descent
先随便选一个点做为起始点,如图中的一个比 0 大一点的点,而后梯度降低算法会计算起始点处损失曲线的梯度,而损失的梯度在这里等于曲线在该点的导数(斜率)。若是有多个权重,那么梯度就是对应权重的偏导数,更准确点说梯度是全部自变量对应偏导数的矢量,梯度降低算法会沿着负梯度的方向一直走以便尽快下降损失,下一步的步长不能过小否则计算量会很大很慢,不能太大否则可能会致使模型偏离,因此这就涉及到学习速率(Learning Rate)的问题了
阶梯降低算法把梯度乘以学习速率做为下一步的变化量,而如何肯定学习速率每每依赖于经验技巧,因此说学习速率是一个超参数(Hyperparameters): 在机器学习算法中程序员要扭动的旋钮。每一个回归问题都存在一个 Goldilocks 学习速率,一维空间的理想学习速率是 \frac{ 1 }{ f(x)'' }(f(x) 对 x 的二阶导数的倒数),二位或多维空间的理想学习速率是海森矩阵的倒数
除了学习速率还有一个问题须要考虑,那就是样本的个数,若是样本个数特别大,大到几十亿甚至几千亿的数量级,那么每次迭代计算梯度时都须要输入所有的样本吗(须要的样本数量称为 batch)?因此为了减小计算量能够从数据集中随机的选择一些样本,这样通过不多的计算就能够很快地收敛。而随机梯度降低 SGD(Stochastic gradient descent)更是极端地每次迭代只使用一个样本,通过足够的迭代 SGD 能够发挥做用可是噪音更多。Mini-batch SGD 是介于 full-batch 迭代和 SGD 迭代之间的折衷方案,Mini-batch SGD 一般会随机选 10 到 1000 个样本,它比 SGD 噪音更少,比 full-batch 更有效率
已经大概知道了如何有效地下降损失,那损失能下降到 0 么?能根据已知的样本训练一个完美的模型么?事实上并不能,也没有必要,就算费尽心机地把模型训练地对已知样本的预测准确率是完美的 100%,可是面对新的样本时仍是没法达到 100%,由于“凡事皆有例外”,并且这样看似完美的模型在面对新的样本时预测的准确率甚至还不如其余简单的模型:
generalization
能够看到,蓝色点表明生病的树,黄色点表明健康的树,背景色表明模型的预测,左边的图表明训练好的特别复杂可是损失很低的模型,可是在新的样本上测试时(右图)能够发现模型表现特别糟糕,对大部分新数据的分类都不许确,这就涉及到泛化的问题了

泛化

泛化(Generalization)指对新的前所未见的数据进行正确预测的能力。上面的模型过拟合(overfit)了训练数据的特性,一个过拟合的模型虽然在训练过程当中损失很低可是在预测新数据时却表现糟糕,那怎么判断一个模型对新的数据能不能作出很好地预测呢?这就涉及到正则化的问题了。过拟合之因此会出现问题是由于它为了追求训练时的完美让模型变得异常复杂,而机器学习应该在拟合数据的同时尽量地保证简单,应该符合奥卡姆剃刀定律,为了方便验证模型的泛化能力,能够将数据集分红专门用来训练的训练集和专门用来测试的测试集,在测试集上表现良好每每能代表在新的数据集也能表现良好,前提是测试集足够大且不会反复用相同测试集做假
泛化过程通常须要知足三项基本假设:工具

  • 咱们从分布中随机抽取独立同分布(i.i.d)的样本,样本以前不会互相影响
  • 分布是固定的(stationary),分布在数据集内不会变化
  • 咱们从同一分布(same distribution)的数据划分中抽取样本

实际上,有些状况下可能会违反其中一些假设,如广告推荐模型可能依赖于用户以前看过的广告,这违反了第一条假设,而一旦违反任意一项假设,就表示咱们已经失去了重要的理论支持,就必须得时刻注意各项指标了
既然测试集应该足够大,那多大好呢?怎么合理地把数据集分红训练集和测试集呢?训练集和测试集应该相互独立,但 训练集的规模越大模型的学习效果就越好,测试集规模越大咱们咱们对评估指标的信心就越足,若是数据集的规模自己就很大就简单多了,但若是数据集规模很是小,就要先进行像交叉验证(cross-validation)之类的复杂操做了
测试集应该知足两个条件:学习

  • 规模足够大以产生具备统计意义的结果
  • 可以表明整个数据集,不要选择与训练集不一样特征的测试集

永远不要对测试集进行训练,若是你发现模型在测试集上预测的准确度特别高,甚至比在训练集上的还高,先不要兴奋,你极可能把一些测试数据用于训练了,得从新检查一下训练集是否是包含了一些训练集的数据
在训练集上训练模型,在测试集上评估模型,再根据评估的结果调整模型,如此循环下去直到能选择一个在测试集上表现最好的模型。这样的流程有点问题,咱们可能无形中对测试数据的特性进行了过拟合,因此为了不出现这种状况,咱们从数据集中再单独划分出一些数据做为验证集,这样迭代评估的时候只在验证集上评估便可,测试集只用来确认结果,要确保在测试集上得出的结果基本符合在验证集上得出的结果,若是不符合就说明对验证集进行了过拟合
测试

validation set

特征工程

咱们彷佛忘了一个最基本的问题,那就是如何从原始数据中抽象出供模型使用的特征值,而从各类各样的数据源中提取数据,而后再根据这些数据建立特征向量的过程被称为特征工程(feature engineering)。像房屋的卧室数量这样的简单数值信息直接复制到特征向量就能够了,可是像房屋的所属街道这样的字符串信息怎么映射到特征向量呢?最简单的方式就是采用 one-hot 独热编码,如一共有 N 个街道,那就建立一个 N 位的编码,而后按照字典的方式将全部街道映射到这个这个编码上(第 i 个街道那一位置 1,其它位置 0),若是 N 特别大,能够采用稀疏表示法(sparse representation)压缩。那究竟什么样的特征才算好的特征呢?首先,它应该具备非零值且至少出现不少次,若是一个特征出现次数极少或只出现一次,就能够考虑在预处理时就把它过滤掉了。其次,它应该具备清晰明确的意义,以便咱们在检查和调试时特征被正确的处理。第三,特征值不该随时间而发生变化。最后,特征值不该采用不理性的离群值。要作这么多工做的缘由是为了把噪音降到最低,机器学习就像一个黑盒子,把数据都丢进去,却不检查数据,就盼着能得到好的结果,这从目前来看很不合适也不现实,因此在把数据交给机器学习模型以前,咱们只能凭借本身的经验对特征进行抽象和过滤等处理,甚至还要监控特征随着时间变化的状况。
不少时候浮点特征值的范围会很大(如 100 到 900),为了让梯度降低法更快地收敛,同时为了不数据溢出致使的 NaN 问题,能够把它缩放到标准范围(如 0 到 1 或 -1 到 +1),最简单的缩放策略就是线性的缩放,不过还有一种缩放策略是先计算每一个值的 Z score,缩放后的值为 (原始值 - 平均值) / 标准差,这样的话大多数缩放后的值都会介于 -3 和 +3 之间了。
有时咱们须要处理一下极端离群值(extreme outlier):

extreme outliers

有时咱们须要对浮点数进行分箱(Binning):
bin
纬度原本是连续的浮点类型的,可是小纬度内房价的差异并非连续的,差异通常也不大,因此能够把纬度分箱,纬度 37.4 能够表示为 [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
到如今为止,咱们能够假设用于训练和测试的数据是可靠的了,咱们像挑出坏苹果同样把很差的样本挑出去了:

  • 遗漏值,如某个房屋的年龄忘写了
  • 重复样本,如服务器错误地把相同的日志上传了两次
  • 不良标签,如一我的错误地把一个橡树图片标记为枫树
  • 不良特征值,如一我的把编号多输了几位

良好的机器学习依赖于良好的数据

特征组合

到目前为止,咱们研究的都是线性问题,线性学习器不但简单并且能够很容易扩展到大型数据集,可是若是要建模的问题很复杂怎么办?

linear problem
这时候就不能用 y = SIGN(b + w_1x_1 + w_2x_2) 去线性拟合了,可能你已经想到了,一种机智的作法是额外定义一种特征 x_3 = x_1x_2,这样咱们就能够在线性模型中使用它了 y = SIGN(b + w_1x_1 + w_2x_2 + w_3x_3),若是 x_1x_2 的乘积为正,那么就是一三象限的蓝色点,不然就是二四象限的橙色点,这样咱们就能够在线性模型中学习非线性的规律了,而像 x_3 这种把几个特征乘起来的合成特征(synthetic feature)被称为特征交叉(feature cross),一些有趣的研究代表将特征交叉乘积得到的线性学习效果和深度网络结合起来能够实现极其强大的建模能力
特征交叉也会带来一些问题,好比几个特别大特别稀疏的特征交叉后将是一个更大的特征表示,这会致使模型大小膨胀,占据大量 RAM 内存,减缓运行时间,获得的噪声系数可能会致使过拟合,这就须要更复杂的如 L_0L_1 正则化去解决这个问题了

正则化

在研究泛化问题时咱们重点关注了过拟合的问题,若是咱们过于追求在训练集上的损失极低,就可能会出现过拟合训练集而带来的问题:

regularization

能够发现,在训练损失愈来愈低时,验证损失可能会愈来愈高,就像咱们只跟一我的练习外语交流同样,刚开始进步很是快,可是随着时间的发展你会慢慢习惯他的表达方式和发音习惯(就像过拟合了训练数据同样),致使再跟其余人交流外语时变得很困难。那怎样处理过拟合呢?最简单的就是正则化(Regularization),正则化有不少策略,最简单的就是尽早中止(Early stopping 早停法),也就是在收敛前(红线上升以前)中止训练,可是实际上很难实现,还有一种策略就是经过惩罚模型复杂度来尽量地下降模型的复杂度,有时也称为结构式风险最小化(structural risk minimization)

\text{minimize: } Loss(Data\;|\;Model) + complexity(Model)

咱们要平衡这两个因素,让损失和复杂度都尽量地低,也就是说,要确保正确的训练数据,又不过分信赖训练数据。那如何定义模型复杂度呢?最简单的就是选择较小的权重,也就是说即便参数小到能够忽略咱们依然能够获取正确的训练样本,从数学上来讲通常使用 L_2 正则化,也称为岭正则化,在这种正则化策略中,咱们对权重的平方和进行惩罚,若是熟悉贝叶斯先验几率就知道这是一种先验几率,在咱们知道训练样本以前就猜到权重应该是以 0 为中心呈正态分布的,并且数值不会太大。以数学的方式表示上面的公式为

Loss(Data|Model) + \lambda \left(w_1^2 + \ldots + w_n^2 \right)

能够看到第一项下降损失的过程取决于训练数据,而第二项简化模型则与数据无关,这两项经过 \lambda 实现了平衡,\lambda 的选取取决于你和实际状况,若是有大量训练数据且训练数据与测试数据看起来一致,知足独立同分布,你可能不须要多少正则化,不然可能须要大量正则化和交叉验证,\lambda(lambda)也被称为正则化率(regularization rate),若是 lambda 值太高,模型会很是简单,但会面临数据欠拟合的风险,模型将没法充分了解训练数据以进行有用的预测,若是 lambda 值太低,模型会比较复杂,会面临数据过拟合的风险,模型会过多解读训练数据的特殊性从而很难泛化到新的数据。将 lambda 值设为 0 可完全取消正则化,此时训练的惟一目的就是最小化损失,可是会使过拟合的风险达到最高。
L_2 正则化鼓励 non-informative 特征的权重趋向于 0,可是当这类特征刚好与标签相关时,会致使模型学到一个中等的权重,此时,模型错误地给了 non-informative 特征一些本应该给 informative 特征的信任。L_2 正则化对大权重的惩罚比小权重更严厉,所以,即便一个权重降低得比另外一个快,L_2 正则化也会强制使较大权重的那个降低得比较小的更快。L_2 正则化与学习速率息息相关,很容易让人困惑
L_2 正则化虽然可使权重变小,但不能使他们正好为 0,L_0 正则化虽然可使权重为 0,这样能够直接忽略某些特征进而减小内存消耗,可是它会将咱们的凸优化问题变成非非凸优化问题(NP 困难),因此 L_0 正则化并不实用。而 L_1 正则化具备凸优化的优点,能够进行有效计算。L_2 会下降权重的平方,L_1 会下降权重的绝对值,L_2 的导数是 2 乘以权重,L_1 的导数是与权重无关的常量 k,也就是说 L_2 每次移除权重的 x%,一般不会减到 0,L_1 每次从权重中减去固定的常数,若是减法使权重从 +0.1 变成 -0.2,因为惩罚的是绝对值,因此权重会变成 0

逻辑回归

不少问题都须要把 几率估计 做为输出,好比图片中的动物是猫的几率是多少、狗晚上吵醒人的几率是多少,既然是几率,那么几率值确定是 0 到 1 之间,那咱们以前学到的线性模型的输出能强制限制到 0 到 1 之间么?很显然不太现实,那咱们就要想出一种不一样的损失函数和预测方法使几率值很天然的处于 0 到 1 之间,咱们将这种想法称为逻辑回归(Logistic Regression)。逻辑回归的几率就很是有用了,甚至能够被看作实际几率去作有用的预测,用这个几率乘以想要预测的项就能够获得预期值。它在二元分类(binary classification)中也很是有用,如一封邮件是垃圾邮件的几率是多少,一枚硬币朝上的几率是多少。那逻辑回归模型是怎样保证输出老是介于 0 到 1 之间呢?咱们来看一下 S 型函数(sigmoid function):

y = \frac{1}{1 + e^{-z}}

sigmoid function
逻辑回归模型也相似:

y' = \frac{1}{1 + e^{-(z)}}

l
y' 表示逻辑回归模型的输出, z 表示线性模型的 b + w_1x_1 + w_2x_2 +  ... w_Nx_Nz 也称为对数概率(log-odds),由于 z = log(\frac{y}{1-y}),若是是二元分类问题,那么 y1 - y 就是相对的两个几率
咱们最开始讨论的线性回归用的损失函数是平方损失(Squared Loss),而逻辑回归用的是对数损失(Log Loss):

\text{Log Loss} = \sum_{(x,y)\in D} -y\log(y') - (1 - y)\log(1 - y')

其中 (x,y)\in D 表示包含不少有标签样本的数据集,y 表示有标签样本中的标签,y' 表示预测的值
在逻辑回归模型中正则化变得更加剧要,若是没有正则化,那么逻辑回归的渐进性将在高维上让损失趋向于 0 ,若是未指定正则化函数,模型将变得彻底过拟合,所以逻辑回归模型一般使用 L_2 正则化或早停法下降模型的复杂度

分类

机器学习模型解决的最多见的问题就是分类问题,如邮件是正常邮件仍是垃圾邮件,图片中的物体是什么,咱们可使用逻辑回归做为分类的基础,给 几率输出 应用 固定的阈值(threshold)就好了,如一封邮件为垃圾邮件的几率超过了 0.8,咱们就认为它是垃圾邮件,0.8 就是分类的阈值(分类阈值 classification threshold 也被称为断定阈值 decision threshold),一旦选定了分类阈值,那咱们怎么评估这个阈值下模型的质量呢?最传统的方式就是用准确率(accuracy)这个指标,也就是预测正确数除以总数。可是准确率有时会成为不好或者误导性的指标,好比当不一样错误的类型代价不同时,当分类不平衡(正例或负例极少)时(一个广告的点击率是千分之一万分之一甚至更低,那么一个模型预测一个广告不被点击的的准确率是 99.999% 没有任何意义),此时区分不一样错误的类型可能会有所帮助:

  • 真正例(True Positives):狼真的来了,正确喊出狼来了
  • 假正例(False Positives):狼没有来,却喊狼来了,全部人都很生气
  • 假负例(False Negatives):狼真的来了,却没发现,后果更严重
  • 真负例(True Negatives):狼没有来,也没喊狼来了,一切安好

也就是说,TP 和 TN 都是正确的预测,而 FP 是指模型错误地将负类别预测成正类别,FN 更是严重错误地将正类别预测成负类别
如今假如出现了 100 次狼来了事件,有 1 次狼真的来了小男孩喊狼来了,有 1 次狼没来却喊狼来了,有 8 次狼来了却没喊,有 90 次 狼没来也没喊,那么小男孩的准确率高达 \frac{TP+TN}{TP+TN+FP+FN} = \frac{1+90}{1+90+1+8} = 0.91,从 91% 的准确率来看这个小男孩还挺好,可是事实是这样的吗?在 91 次狼没来中小男孩有 90 次没喊狼来了,可是,在 9 次狼真的来了的时候小男孩却只有 1 次喊狼来了,这是多么可怕啊!若是是肿瘤诊断模型,9 个恶性肿瘤中只有 1 个被发现是恶性肿瘤,那后果将更加的可怕
所以咱们须要一些新的指标来评估,如精确率(precision),也就是小男孩喊狼来了的状况中有多少次是对的,\frac{TP}{TP+FP} = \frac{1}{1+1} = 0.5。另外一方面,召回率(recall)是指在全部尝试进入村子的狼中咱们发现了多少头,即正确被识别为正例的比例,\frac{TP}{TP+FN} = \frac{1}{1+8} = 0.11。有趣的是这些指标每每是此消彼长的,如为了把召回率作得好只要有风吹草动就喊狼来了,这会下降分类阈值,为了精确率高只有在确认狼真的来了才喊狼来了,这会提升分类阈值,所以只有这两方面都作得好才能评价模型的优劣。通常来讲,提升分类阈值会减小假正例,从而提升精确率
你可能会说,那我把全部可能的分类阈值都试一下看那个阈值下模型的表现更好不就好了么?事实上确实有这样的,叫 ROC 曲线
真正例率 TPR(True Positive Rate)为 TPR = \frac{TP} {TP + FN},和召回率同样
假正例率 FPR(False Positive Rate)为 FPR = \frac{FP} {FP + TN}
将不一样阈值下的 TPR 和 FPR 值的点连成一条曲线就是 ROC 曲线:

roc
观察这个 ROC 曲线,咱们惊讶地发现曲线下的面积就能够很好地表示分类模型的好坏,面积越大,那么随机选择一个正样本和一个负样本时正样本排在前面的几率就越大。而这个曲线下面积简称为 AUC(Area under the ROC Curve)
还有一个指标,那就是误差,回归模型应该是无误差的,也就是说,预测的平均值和观察到的平均值差很少是同样的,预测误差(Prediction bias)等于预测的平均值减去数据集中标签的平均值,若是预测误差不为 0 那么说明模型可能有问题,须要找一下是什么缘由致使的非零误差,固然,即便是预测误差为零也不能说明模型是完美的,还要看其余指标。形成预测误差的缘由可能有特征集不完整,数据集中的噪音,有误差的训练样本,太强的正则化等等,能够经过添加校准层(calibration layer)来调整模型的输出,从而减小误差,可是这只是下策,由于这个治标不治本,并且你还得维护这个脆弱的系统

神经网络

当问题复杂到没法用线性回归解决怎么办?即便是利用特征交叉也没法解决非线性的问题呢?这个时候咱们但愿经过某种方式,让模型本身学习非线性的规律,而不用咱们手动为它设置参数。这一愿景能够经过深度神经网络(Deep Neural Networks)实现,它在复杂数据问题上作得特别好,例如图片数据,视频数据,音频数据等。先来看一下线性模型的表示,如 y = b + w_1x_1 + w_2x_2 + w_3x_3:

linear
每一个特征输入都有一个权重,这些权重以线性方式结合到一块儿产生惟一的输出,也就是各个输入特征的加权和,那咱们怎么把它扩展到非线性模型呢?
咱们发现,无论咱们以线性的方式往中间加多少层,线性函数的组合依然是线性函数,模型依然是线性的。所以咱们想办法加一些非线性函数进去,这些非线性函数可能位于任何小的隐藏式节点的输出中:
这种非线性函数也被称为激活函数(Activation Function),常见的激活函数有 S 型激活函数和 ReLU 激活函数,S 型函数以前提到过,能够把加权和平滑地限制到 0 到 1 之间,而 ReLU(rectified linear unit) 激活函数更加的简单,它接受线性函数,并在零值处截断,即 F(x)=max(0,x)
事实上,任何数学函数均可以做为激活函数,假设用 \sigma 表示激活函数,那么网络中节点的值就是 \sigma(\boldsymbol w \cdot \boldsymbol x+b)
如今,咱们有了人们常说的神经网络的全部标准组件:

  • 一组节点,相似于神经元,位于层中
  • 一组权重,表示每一个神经网络层与其下层的关系,下面的层能够是另外一个神经网络层也能够是其它类型的层
  • 一组误差,每一个节点一个误差
  • 激活函数,用来转换层中每一个节点的输出,不一样层可能有不一样的激活函数

训练神经网络最经常使用的训练算法就是反向传播算法(Backpropagation),它使梯度降低用于多层神经网络成为可能,反向传播依赖梯度这个概念,事物必须是可微的,这样咱们才能进行学习
须要注意的是,可能会出现梯度消失(Vanishing Gradients)的状况,若是网络太过深刻,信噪比随着模型的深刻变差,学习可能变得特别慢,这个时候 ReLU 或其余策略可能比较有用。若是网络中的权重太大,那么较低层的梯度会涉及许多大项的乘积,可能就会出现梯度爆炸(Exploding Gradients)的状况,此时梯度太大根本没法收敛,Batch 标准化或者下降学习速率会比较有用。若是加权和都低于 0,那么 ReLU 单元会卡住,对网络输出没有任何贡献,梯度就没法反向传播,永远没法返回存在 ReLU 层的位置,就会出现死亡 ReLU 单元(Dead ReLU Units)的状况,此时使用不一样的初始化或下降学习速率会有所帮助
训练神经网络时还有一个颇有用的技巧,正则化的另外一种形式,叫作丢弃(Dropout),就是针对几率 P 取一个节点,而后从网络的一个梯度步长中把它移除。在其余梯度步长中重复此过程,并随机取不一样的节点进行丢弃,丢弃的越多,正则化的效果就越强
到目前为止,咱们讨论的分类问题都是二元分类问题,如邮件是否是垃圾邮件,肿瘤是恶性的仍是良性的,咱们也知道了,利用逻辑回归和能够很好地解决二元分类问题,可是生活中不少分类问题是多类别(multi-class)的,如图片中的东西是苹果仍是梨仍是小狗仍是其余的东西,这朵花是什么花。那咱们怎么把二元分类拓展到多类别分类呢?one-vs.-all 提供了利用二元分类的方式,若是有 N 个可能解,one-vs.-all 就包含 N 个单独的二元分类器,也就是说每一个可能的结果都对应一个二元分类器,在训练的时候,模型会运行一系列二元分类器,对每一个分类器进行训练以回答单独的分类问题,如给定一张狗狗的图片,可能会训练五种不一样的识别器:

  • 这是一张苹果的图片吗?不是
  • 这是一张小熊的图片吗?不是
  • 这是一张糖果的图片吗?不是
  • 这是一张狗狗的图片吗?是
  • 这是一张鸡蛋的图片吗?不是

当类别不多时还能够接受,但类别不少时,效率就会变得异常低下,所以咱们可使用深度神经网络建立一个明显更高效的 one-vs.-all 模型,其中每一个输出节点表明不一样的类型:

on-vs.-all
咱们已经知道,逻辑回归在处理二元分类问题时颇有用,它能够把输出(几率)限制在 0 到 1 以内, 若是一封邮件是垃圾邮件的几率是 80%,那么是正常邮件的几率就是 20%,加起来确定等于 1,那怎么把这个扩展到多类别问题中呢?答案是 Softmax,它为每一个类别分配一个几率,这些几率加起来必须等于 1,这会帮助训练比其余方式更快地收敛:
softmax
Softmax 层是输出层以前的神经网络层,必须和输出层有同样的节点数,它的公式本质上也是逻辑回归公式的延伸:

p(y = j|\textbf{x})  = \frac{e^{(\textbf{w}_j^{T}\textbf{x} + b_j)}}{\sum_{k\in K} {e^{(\textbf{w}_k^{T}\textbf{x} + b_k)}} }

当类别不少时,Softmax 的代价会变得很大,因此除了 Full Softmax 还有一种策略叫 Candidate sampling,对全部正例标签计算几率,但只对负例标签的随机样本计算几率,如咱们想肯定图片是小猎犬仍是寻血猎犬,咱们就没必要为每一个非狗样本提供几率了
Softmax 假设每一个样本只能有一个类别,若是一个样本同时属于多个类别,那么你就不能用 Softmax,你只能依赖多个逻辑回归

思考

如今咱们思考一个问题,咱们在读一本书的时候,或者在思考的时候,脑海里总有一个声音跟你说话,这个声音很像你本身的声音,但又不是你的声音,若是你看过西部世界,或者对心理学有过了解,你可能知道有一种理论叫作二分心智。二分心智通常被看作是人类意识的起源,而人们对于意识这种东西并非真正的了解,可是人类却总想扮演上帝的角色,想要赋予一我的造的机器意识。上个世纪人们开动本身的想象力,想象着赋予机器意识的那一天,各类科幻电影更是把这种想象表达的淋漓尽致,然而到如今人们才冷静下来,发现人工智能还有很长很长一段路要走,与其建立人工智能不如利用已有的知识水平为人工智能铺路,不如将已有的人工智能成果(机器学习)应用于现实生活中,Google 的 AI 向善就是很好地方式,利用 AI 技术能够预测洪水,能够用于医疗,能够预测疾病,能够帮助聋哑人跟正常人沟通等等等等
机器学习做为实现 AI 的主要手段,涉及到的知识和领域很是多,而 Google 提供的 TensorFlow 平台让普通人建立或训练机器学习模型成为可能,做为普通人,你没法提出革命性的人工智能理论,甚至没法理解不少数学知识,可是有了 TensorFlow 平台,有了一些训练好的模型,你就能够建立本身想要的,能帮助你本身或者帮助他人解决问题的模型

参考

附录

TensorFlow

  • “Goldilocks and the Three Bears” 的故事讲述了 Goldilocks 小女孩闯入了已经外出的三只小熊的家,她以为三把椅子中不硬不软的椅子坐起来最舒服,三碗粥中不热不冷的粥最好吃,三张床中不硬不软的床睡着最舒服。因此 Goldilocks 一般用来形容刚恰好的东西
  • 奥卡姆剃刀是指简约法则,简单的解决方案相对于复杂的解决方案更多是正确的,也就是说,大道至简
  • one-hot encoding 一般被翻译为独热编码,全部编码位中只有一个是热的,也就是 1,多个 1 的编码被叫作 multi-hot encoding
  • feature cross 中的 cross 源自 cross product,即叉积/向量积
  • 能够下载 Jupyter Notebook 在本地作练习题:download.mlcc.google.cn/mledu-exerc…
  • steps 表示训练迭代的总次数
  • batch size 表示每次迭代须要的样本数
  • 训练模型须要的总样本数等于 batch\,size * steps
  • periods 表示报告的粒度,每一个 periods 内须要的训练样本数等于 \frac{batch\,size * steps} {periods}
相关文章
相关标签/搜索