diff --git a/html/week3.html b/html/week3.html index 7e4b41ce..b5097b04 100644 --- a/html/week3.html +++ b/html/week3.html @@ -2,15 +2,16 @@
-第3周六、逻辑回归(Logistic Regression)6.1 分类问题6.2 假说表示6.3 判定边界6.4 代价函数6.5 简化的成本函数和梯度下降6.6 高级优化6.7 多类别分类:一对多七、正则化(Regularization)7.1 过拟合的问题7.2 代价函数7.3 正则化线性回归7.4 正则化的逻辑回归模型
参考文档: 6 - 1 - Classification (8 min).mkv
在这个以及接下来的几个视频中,开始介绍分类问题。
在分类问题中,你要预测的变量 是离散的值,我们将学习一种叫做逻辑回归 (Logistic Regression) 的算法,这是目前最流行使用最广泛的一种学习算法。
在分类问题中,我们尝试预测的是结果是否属于某一个类(例如正确或错误)。分类问题的例子有:判断一封电子邮件是否是垃圾邮件;判断一次金融交易是否是欺诈;之前我们也谈到了肿瘤分类问题的例子,区别一个肿瘤是恶性的还是良性的。
我们从二元的分类问题开始讨论。
我们将因变量(dependent variable)可能属于的两个类分别称为负向类(negative class)和正向类(positive class),则因变量 ,其中 0 表示负向类,1 表示正向类。
如果我们要用线性回归算法来解决一个分类问题,对于分类, 取值为 0 或者1,但如果你使用的是线性回归,那么假设函数的输出值可能远大于 1,或者远小于0,即使所有训练样本的标签 都等于 0 或 1。尽管我们知道标签应该取值0 或者1,但是如果算法得到的值远大于1或者远小于0的话,就会感觉很奇怪。所以我们在接下来的要研究的算法就叫做逻辑回归算法,这个算法的性质是:它的输出值永远在0到 1 之间。
顺便说一下,逻辑回归算法是分类算法,我们将它作为分类算法使用。有时候可能因为这个算法的名字中出现了“回归”使你感到困惑,但逻辑回归算法实际上是一种分类算法,它适用于标签 取值离散的情况,如:1 0 0 1。
在接下来的视频中,我们将开始学习逻辑回归算法的细节。
参考视频: 6 - 2 - Hypothesis Representation (7 min).mkv
在这段视频中,我要给你展示假设函数的表达式,也就是说,在分类问题中,要用什么样的函数来表示我们的假设。此前我们说过,希望我们的分类器的输出值在0和1之间,因此,我们希望想出一个满足某个性质的假设函数,这个性质是它的预测值要在0和1之间。
回顾在一开始提到的乳腺癌分类问题,我们可以用线性回归的方法求出适合数据的一条直线:
根据线性回归模型我们只能预测连续的值,然而对于分类问题,我们需要输出0或1,我们可以预测:
当时,预测 。
当时,预测 。
对于上图所示的数据,这样的一个线性模型似乎能很好地完成分类任务。假使我们又观测到一个非常大尺寸的恶性肿瘤,将其作为实例加入到我们的训练集中来,这将使得我们获得一条新的直线。
这时,再使用0.5作为阀值来预测肿瘤是良性还是恶性便不合适了。可以看出,线性回归模型,因为其预测的值可以超越[0,1]的范围,并不适合解决这样的问题。
我们引入一个新的模型,逻辑回归,该模型的输出变量范围始终在0和1之间。 -逻辑回归模型的假设是: +
第3周六、逻辑回归(Logistic Regression)6.1 分类问题6.2 假说表示6.3 判定边界6.4 代价函数6.5 简化的成本函数和梯度下降6.6 高级优化6.7 多类别分类:一对多七、正则化(Regularization)7.1 过拟合的问题7.2 代价函数7.3 正则化线性回归7.4 正则化的逻辑回归模型
参考文档: 6 - 1 - Classification (8 min).mkv
在这个以及接下来的几个视频中,开始介绍分类问题。
在分类问题中,你要预测的变量 是离散的值,我们将学习一种叫做逻辑回归 (Logistic Regression) 的算法,这是目前最流行使用最广泛的一种学习算法。
在分类问题中,我们尝试预测的是结果是否属于某一个类(例如正确或错误)。分类问题的例子有:判断一封电子邮件是否是垃圾邮件;判断一次金融交易是否是欺诈;之前我们也谈到了肿瘤分类问题的例子,区别一个肿瘤是恶性的还是良性的。
我们从二元的分类问题开始讨论。
我们将因变量(dependent variable)可能属于的两个类分别称为负向类(negative class)和正向类(positive class),则因变量 ,其中 0 表示负向类,1 表示正向类。
如果我们要用线性回归算法来解决一个分类问题,对于分类, 取值为 0 或者1,但如果你使用的是线性回归,那么假设函数的输出值可能远大于 1,或者远小于0,即使所有训练样本的标签 都等于 0 或 1。尽管我们知道标签应该取值0 或者1,但是如果算法得到的值远大于1或者远小于0的话,就会感觉很奇怪。所以我们在接下来的要研究的算法就叫做逻辑回归算法,这个算法的性质是:它的输出值永远在0到 1 之间。
顺便说一下,逻辑回归算法是分类算法,我们将它作为分类算法使用。有时候可能因为这个算法的名字中出现了“回归”使你感到困惑,但逻辑回归算法实际上是一种分类算法,它适用于标签 取值离散的情况,如:1 0 0 1。
在接下来的视频中,我们将开始学习逻辑回归算法的细节。
参考视频: 6 - 2 - Hypothesis Representation (7 min).mkv
在这段视频中,我要给你展示假设函数的表达式,也就是说,在分类问题中,要用什么样的函数来表示我们的假设。此前我们说过,希望我们的分类器的输出值在0和1之间,因此,我们希望想出一个满足某个性质的假设函数,这个性质是它的预测值要在0和1之间。
回顾在一开始提到的乳腺癌分类问题,我们可以用线性回归的方法求出适合数据的一条直线:
根据线性回归模型我们只能预测连续的值,然而对于分类问题,我们需要输出0或1,我们可以预测:
当时,预测 。
当时,预测 。
对于上图所示的数据,这样的一个线性模型似乎能很好地完成分类任务。假使我们又观测到一个非常大尺寸的恶性肿瘤,将其作为实例加入到我们的训练集中来,这将使得我们获得一条新的直线。
这时,再使用0.5作为阀值来预测肿瘤是良性还是恶性便不合适了。可以看出,线性回归模型,因为其预测的值可以超越[0,1]的范围,并不适合解决这样的问题。
我们引入一个新的模型,逻辑回归,该模型的输出变量范围始终在0和1之间。 +逻辑回归模型的假设是: 其中: - 代表特征向量 - 代表逻辑函数(logistic function)是一个常用的逻辑函数为S形函数(Sigmoid function),公式为: 。
python代码实现:
xxxxxxxxxx
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
该函数的图像为:
合起来,我们得到逻辑回归模型的假设:
对模型的理解: 。
的作用是,对于给定的输入变量,根据选择的参数计算输出变量=1的可能性(estimated probablity)即 -例如,如果对于给定的,通过已经确定的参数计算得出,则表示有70%的几率为正向类,相应地为负向类的几率为1-0.7=0.3。
参考视频: 6 - 3 - Decision Boundary (15 min).mkv
现在讲下决策边界(decision boundary)的概念。这个概念能更好地帮助我们理解逻辑回归的假设函数在计算什么。
在逻辑回归中,我们预测:
当时,预测 。
当时,预测 。
根据上面绘制出的 S 形函数图像,我们知道当
时
时
时
又 ,即: - 时,预测 - 时,预测
现在假设我们有一个模型:
并且参数 是向量[-3 1 1]。 则当,即时,模型将预测 。 -我们可以绘制直线,这条线便是我们模型的分界线,将预测为1的区域和预测为 0的区域分隔开。
假使我们的数据呈现这样的分布情况,怎样的模型才能适合呢?
因为需要用曲线才能分隔 的区域和 的区域,我们需要二次方特征:是[-1 0 0 1 1],则我们得到的判定边界恰好是圆点在原点且半径为1的圆形。
我们可以用非常复杂的模型来适应非常复杂形状的判定边界。
参考视频: 6 - 4 - Cost Function (11 min).mkv
在这段视频中,我们要介绍如何拟合逻辑回归模型的参数。具体来说,我要定义用来拟合参数的优化目标或者叫代价函数,这便是监督学习问题中的逻辑回归模型的拟合问题。
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将带入到这样定义了的代价函数中时,我们得到的代价函数将是一个非凸函数(non-convexfunction)。
这意味着我们的代价函数有许多局部最小值,这将影响梯度下降算法寻找全局最小值。
线性回归的代价函数为: 。 -我们重新定义逻辑回归的代价函数为:,其中
与 之间的关系如下图所示:
这样构建的函数的特点是:当实际的 且也为 1 时误差为 0,当 但不为1时误差随着变小而变大;当实际的 且也为 0 时代价为 0,当 但不为 0时误差随着 的变大而变大。 -将构建的 简化如下: - + 代表特征向量 + 代表逻辑函数(logistic function)是一个常用的逻辑函数为S形函数(Sigmoid function),公式为: 。
python代码实现:
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
该函数的图像为:
合起来,我们得到逻辑回归模型的假设:
对模型的理解: 。
的作用是,对于给定的输入变量,根据选择的参数计算输出变量=1的可能性(estimated probablity)即 +例如,如果对于给定的,通过已经确定的参数计算得出,则表示有70%的几率为正向类,相应地为负向类的几率为1-0.7=0.3。
参考视频: 6 - 3 - Decision Boundary (15 min).mkv
现在讲下决策边界(decision boundary)的概念。这个概念能更好地帮助我们理解逻辑回归的假设函数在计算什么。
在逻辑回归中,我们预测:
当时,预测 。
当时,预测 。
根据上面绘制出的 S 形函数图像,我们知道当
时
时
时
又 ,即: + 时,预测 + 时,预测
现在假设我们有一个模型:
并且参数 是向量[-3 1 1]。 则当,即时,模型将预测 。 +我们可以绘制直线,这条线便是我们模型的分界线,将预测为1的区域和预测为 0的区域分隔开。
假使我们的数据呈现这样的分布情况,怎样的模型才能适合呢?
因为需要用曲线才能分隔 的区域和 的区域,我们需要二次方特征:是[-1 0 0 1 1],则我们得到的判定边界恰好是圆点在原点且半径为1的圆形。
我们可以用非常复杂的模型来适应非常复杂形状的判定边界。
参考视频: 6 - 4 - Cost Function (11 min).mkv
在这段视频中,我们要介绍如何拟合逻辑回归模型的参数。具体来说,我要定义用来拟合参数的优化目标或者叫代价函数,这便是监督学习问题中的逻辑回归模型的拟合问题。
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将带入到这样定义了的代价函数中时,我们得到的代价函数将是一个非凸函数(non-convexfunction)。
这意味着我们的代价函数有许多局部最小值,这将影响梯度下降算法寻找全局最小值。
线性回归的代价函数为: 。 +我们重新定义逻辑回归的代价函数为:,其中
与 之间的关系如下图所示:
这样构建的函数的特点是:当实际的 且也为 1 时误差为 0,当 但不为1时误差随着变小而变大;当实际的 且也为 0 时代价为 0,当 但不为 0时误差随着 的变大而变大。 +将构建的 简化如下: + 带入代价函数得到: - -即:
Python代码实现:
xxxxxxxxxx
import numpy as np
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X* theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X* theta.T)))
return np.sum(first - second) / (len(X))
在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:
Repeat { - + +即:
Python代码实现:
xxxxxxxxxx
import numpy as np
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X* theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X* theta.T)))
return np.sum(first - second) / (len(X))
在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:
Repeat { + (simultaneously update all ) }
求导后得到:
Repeat { - + (simultaneously update all ) -}
在这个视频中,我们定义了单训练样本的代价函数,凸性分析的内容是超出这门课的范围的,但是可以证明我们所选的代价值函数会给我们一个凸优化问题。代价函数会是一个凸函数,并且没有局部最优值。
推导过程:
+}
在这个视频中,我们定义了单训练样本的代价函数,凸性分析的内容是超出这门课的范围的,但是可以证明我们所选的代价值函数会给我们一个凸优化问题。代价函数会是一个凸函数,并且没有局部最优值。
推导过程:
考虑: - + 则: - - -
所以: - - - - - - - - -
注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的与线性回归中不同,所以实际上是不一样的。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。
一些梯度下降算法之外的选择: -除了梯度下降算法以外,还有一些常被用来令代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常比梯度下降算法要更加快速。这些算法有:共轭梯度(Conjugate Gradient),局部优化法(Broyden fletcher goldfarb shann,BFGS)和有限内存局部优化法(LBFGS) ,fminunc是 matlab和octave 中都带的一个最小值优化函数,使用时我们需要提供代价函数和每个参数的求导,下面是 octave 中使用 fminunc 函数的代码示例:
xxxxxxxxxx
function [jVal, gradient] = costFunction(theta)
jVal = [...code to compute J(theta)...];
gradient = [...code to compute derivative of J(theta)...];
end
options = optimset('GradObj', 'on', 'MaxIter', '100');
initialTheta = zeros(2,1);
[optTheta, functionVal, exitFlag] = fminunc(@costFunction, initialTheta, options);
在下一个视频中,我们会把单训练样本的代价函数的这些理念进一步发展,然后给出整个训练集的代价函数的定义,我们还会找到一种比我们目前用的更简单的写法,基于这些推导出的结果,我们将应用梯度下降法得到我们的逻辑回归算法。
参考视频: 6 - 5 - Simplified Cost Function and Gradient Descent (10 min).mkv
在这段视频中,我们将会找出一种稍微简单一点的方法来写代价函数,来替换我们现在用的方法。同时我们还要弄清楚如何运用梯度下降法,来拟合出逻辑回归的参数。因此,听了这节课,你就应该知道如何实现一个完整的逻辑回归算法。
这就是逻辑回归的代价函数:
这个式子可以合并成:
+ + +
所以: + + + + + + + + +
注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的与线性回归中不同,所以实际上是不一样的。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。
一些梯度下降算法之外的选择: +除了梯度下降算法以外,还有一些常被用来令代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常比梯度下降算法要更加快速。这些算法有:共轭梯度(Conjugate Gradient),局部优化法(Broyden fletcher goldfarb shann,BFGS)和有限内存局部优化法(LBFGS) ,fminunc是 matlab和octave 中都带的一个最小值优化函数,使用时我们需要提供代价函数和每个参数的求导,下面是 octave 中使用 fminunc 函数的代码示例:
xfunction [jVal, gradient] = costFunction(theta)
jVal = [...code to compute J(theta)...];
gradient = [...code to compute derivative of J(theta)...];
end
options = optimset('GradObj', 'on', 'MaxIter', '100');
initialTheta = zeros(2,1);
[optTheta, functionVal, exitFlag] = fminunc(@costFunction, initialTheta, options);
在下一个视频中,我们会把单训练样本的代价函数的这些理念进一步发展,然后给出整个训练集的代价函数的定义,我们还会找到一种比我们目前用的更简单的写法,基于这些推导出的结果,我们将应用梯度下降法得到我们的逻辑回归算法。
参考视频: 6 - 5 - Simplified Cost Function and Gradient Descent (10 min).mkv
在这段视频中,我们将会找出一种稍微简单一点的方法来写代价函数,来替换我们现在用的方法。同时我们还要弄清楚如何运用梯度下降法,来拟合出逻辑回归的参数。因此,听了这节课,你就应该知道如何实现一个完整的逻辑回归算法。
这就是逻辑回归的代价函数:
这个式子可以合并成:
即,逻辑回归的代价函数: - - -根据这个代价函数,为了拟合出参数,该怎么做呢?我们要试图找尽量让 取得最小值的参数。 - -所以我们想要尽量减小这一项,这将我们将得到某个参数。 -如果我们给出一个新的样本,假如某个特征 ,我们可以用拟合训练样本的参数,来输出对假设的预测。 -另外,我们假设的输出,实际上就是这个概率值:,就是关于 以为参数, 的概率,你可以认为我们的假设就是估计 的概率,所以,接下来就是弄清楚如何最大限度地最小化代价函数,作为一个关于的函数,这样我们才能为训练集拟合出参数。
最小化代价函数的方法,是使用梯度下降法(gradient descent)。这是我们的代价函数: -
如果我们要最小化这个关于的函数值,这就是我们通常用的梯度下降法的模板。
我们要反复更新每个参数,用这个式子来更新,就是用它自己减去学习率 + + +根据这个代价函数,为了拟合出参数,该怎么做呢?我们要试图找尽量让 取得最小值的参数。 + +所以我们想要尽量减小这一项,这将我们将得到某个参数。 +如果我们给出一个新的样本,假如某个特征 ,我们可以用拟合训练样本的参数,来输出对假设的预测。 +另外,我们假设的输出,实际上就是这个概率值:,就是关于 以为参数, 的概率,你可以认为我们的假设就是估计 的概率,所以,接下来就是弄清楚如何最大限度地最小化代价函数,作为一个关于的函数,这样我们才能为训练集拟合出参数。
最小化代价函数的方法,是使用梯度下降法(gradient descent)。这是我们的代价函数: +
如果我们要最小化这个关于的函数值,这就是我们通常用的梯度下降法的模板。
我们要反复更新每个参数,用这个式子来更新,就是用它自己减去学习率 乘以后面的微分项。求导后得到:
如果你计算一下的话,你会得到这个等式: - -我把它写在这里,将后面这个式子,在 到 上求和,其实就是预测误差乘以 ,所以你把这个偏导数项放回到原来式子这里,我们就可以将梯度下降算法写作如下形式: -
所以,如果你有 个特征,也就是说:,参数向量包括 一直到,那么你就需要用这个式子:
来同时更新所有的值。
现在,如果你把这个更新规则和我们之前用在线性回归上的进行比较的话,你会惊讶地发现,这个式子正是我们用来做线性回归梯度下降的。
那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看看发生了哪些变化。实际上,假设的定义发生了变化。
对于线性回归假设函数:
而现在逻辑函数假设函数:
因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。
在先前的视频中,当我们在谈论线性回归的梯度下降法时,我们谈到了如何监控梯度下降法以确保其收敛,我通常也把同样的方法用在逻辑回归中,来监测梯度下降,以确保它正常收敛。
当使用梯度下降法来实现逻辑回归时,我们有这些不同的参数,就是 一直到,我们需要用这个表达式来更新这些参数。我们还可以使用 for循环来更新这些参数值,用 for i=1 to n
,或者 for i=1 to n+1
。当然,不用 for循环也是可以的,理想情况下,我们更提倡使用向量化的实现,可以把所有这些 n个参数同时更新。
最后还有一点,我们之前在谈线性回归时讲到的特征缩放,我们看到了特征缩放是如何提高梯度下降的收敛速度的,这个特征缩放的方法,也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。
就是这样,现在你知道如何实现逻辑回归,这是一种非常强大,甚至可能世界上使用最广泛的一种分类算法。
参考视频: 6 - 6 - Advanced Optimization (14 min).mkv
在上一个视频中,我们讨论了用梯度下降的方法最小化逻辑回归中代价函数。在本次视频中,我会教你们一些高级优化算法和一些高级的优化概念,利用这些方法,我们就能够使通过梯度下降,进行逻辑回归的速度大大提高,而这也将使算法更加适合解决大型的机器学习问题,比如,我们有数目庞大的特征量。 -现在我们换个角度来看什么是梯度下降,我们有个代价函数,而我们想要使其最小化,那么我们需要做的是编写代码,当输入参数 时,它们会计算出两样东西: 以及 等于 0、1直到 时的偏导数项。
假设我们已经完成了可以实现这两件事的代码,那么梯度下降所做的就是反复执行这些更新。 -另一种考虑梯度下降的思路是:我们需要写出代码来计算 和这些偏导数,然后把这些插入到梯度下降中,然后它就可以为我们最小化这个函数。 -对于梯度下降来说,我认为从技术上讲,你实际并不需要编写代码来计算代价函数。你只需要编写代码来计算导数项,但是,如果你希望代码还要能够监控这些 的收敛性,那么我们就需要自己编写代码来计算代价函数和偏导数项。所以,在写完能够计算这两者的代码之后,我们就可以使用梯度下降。 -然而梯度下降并不是我们可以使用的唯一算法,还有其他一些算法,更高级、更复杂。如果我们能用这些方法来计算代价函数和偏导数项两个项的话,那么这些算法就是为我们优化代价函数的不同方法,共轭梯度法 BFGS (变尺度法) 和L-BFGS (限制变尺度法) 就是其中一些更高级的优化算法,它们需要有一种方法来计算 ,以及需要一种方法计算导数项,然后使用比梯度下降更复杂的算法来最小化代价函数。这三种算法的具体细节超出了本门课程的范畴。实际上你最后通常会花费很多天,或几周时间研究这些算法,你可以专门学一门课来提高数值计算能力,不过让我来告诉你他们的一些特性:
这三种算法有许多优点:
一个是使用这其中任何一个算法,你通常不需要手动选择学习率 ,所以对于这些算法的一种思路是,给出计算导数项和代价函数的方法,你可以认为算法有一个智能的内部循环,而且,事实上,他们确实有一个智能的内部循环,称为线性搜索(line search)算法,它可以自动尝试不同的学习速率 ,并自动选择一个好的学习速率 ,因此它甚至可以为每次迭代选择不同的学习速率,那么你就不需要自己选择。这些算法实际上在做更复杂的事情,不仅仅是选择一个好的学习速率,所以它们往往最终比梯度下降收敛得快多了,不过关于它们到底做什么的详细讨论,已经超过了本门课程的范围。
实际上,我过去使用这些算法已经很长一段时间了,也许超过十年了,使用得相当频繁,而直到几年前我才真正搞清楚共轭梯度法 BFGS 和 L-BFGS的细节。
我们实际上完全有可能成功使用这些算法,并应用于许多不同的学习问题,而不需要真正理解这些算法的内环间在做什么,如果说这些算法有缺点的话,那么我想说主要缺点是它们比梯度下降法复杂多了,特别是你最好不要使用 L-BGFS、BFGS这些算法,除非你是数值计算方面的专家。实际上,我不会建议你们编写自己的代码来计算数据的平方根,或者计算逆矩阵,因为对于这些算法,我还是会建议你直接使用一个软件库,比如说,要求一个平方根,我们所能做的就是调用一些别人已经写好用来计算数字平方根的函数。幸运的是现在我们有Octave 和与它密切相关的 MATLAB 语言可以使用。
Octave 有一个非常理想的库用于实现这些先进的优化算法,所以,如果你直接调用它自带的库,你就能得到不错的结果。我必须指出这些算法实现得好或不好是有区别的,因此,如果你正在你的机器学习程序中使用一种不同的语言,比如如果你正在使用C、C++、Java等等,你可能会想尝试一些不同的库,以确保你找到一个能很好实现这些算法的库。因为在L-BFGS或者等高线梯度的实现上,表现得好与不太好是有差别的,因此现在让我们来说明:如何使用这些算法:
比方说,你有一个含两个参数的问题,这两个参数是和,因此,通过这个代价函数,你可以得到和 的值,如果你将 最小化的话,那么它的最小值将是 ,。代价函数的导数推出来就是这两个表达式:
如果我们不知道最小值,但你想要代价函数找到这个最小值,是用比如梯度下降这些算法,但最好是用比它更高级的算法,你要做的就是运行一个像这样的Octave 函数:
xxxxxxxxxx
function [jVal, gradient]=costFunction(theta)
jVal=(theta(1)-5)^2+(theta(2)-5)^2;
gradient=zeros(2,1);
gradient(1)=2*(theta(1)-5);
gradient(2)=2*(theta(2)-5);
end
这样就计算出这个代价函数,函数返回的第二个值是梯度值,梯度值应该是一个2×1的向量,梯度向量的两个元素对应这里的两个偏导数项,运行这个costFunction 函数后,你就可以调用高级的优化函数,这个函数叫 -fminunc,它表示Octave 里无约束最小化函数。调用它的方式如下:
xxxxxxxxxx
options=optimset('GradObj','on','MaxIter',100);
initialTheta=zeros(2,1);
[optTheta, functionVal, exitFlag]=fminunc(@costFunction, initialTheta, options);
你要设置几个options,这个 options 变量作为一个数据结构可以存储你想要的options,所以 GradObj 和On,这里设置梯度目标参数为打开(on),这意味着你现在确实要给这个算法提供一个梯度,然后设置最大迭代次数,比方说100,我们给出一个 的猜测初始值,它是一个2×1的向量,那么这个命令就调用fminunc,这个@符号表示指向我们刚刚定义的costFunction 函数的指针。如果你调用它,它就会使用众多高级优化算法中的一个,当然你也可以把它当成梯度下降,只不过它能自动选择学习速率,你不需要自己来做。然后它会尝试使用这些高级的优化算法,就像加强版的梯度下降法,为你找到最佳的值。
让我告诉你它在 Octave 里什么样:
所以我写了这个关于theta的 costFunction 函数,它计算出代价函数 jval以及梯度gradient,gradient 有两个元素,是代价函数对于theta(1) 和 theta(2)这两个参数的偏导数。
我希望你们从这个幻灯片中学到的主要内容是:写一个函数,它能返回代价函数值、梯度值,因此要把这个应用到逻辑回归,或者甚至线性回归中,你也可以把这些优化算法用于线性回归,你需要做的就是输入合适的代码来计算这里的这些东西。
现在你已经知道如何使用这些高级的优化算法,有了这些算法,你就可以使用一个复杂的优化库,它让算法使用起来更模糊一点。因此也许稍微有点难调试,不过由于这些算法的运行速度通常远远超过梯度下降。
所以当我有一个很大的机器学习问题时,我会选择这些高级算法,而不是梯度下降。有了这些概念,你就应该能将逻辑回归和线性回归应用于更大的问题中,这就是高级优化的概念。
在下一个视频,我想要告诉你如何修改你已经知道的逻辑回归算法,然后使它在多类别分类问题中也能正常运行。
参考视频: 6 - 7 - Multiclass Classification_ One-vs-all (6 min).mkv
在本节视频中,我们将谈到如何使用逻辑回归 (logistic regression)来解决多类别分类问题,具体来说,我想通过一个叫做"一对多" (one-vs-all) 的分类算法。
先看这样一些例子。
第一个例子:假如说你现在需要一个学习算法能自动地将邮件归类到不同的文件夹里,或者说可以自动地加上标签,那么,你也许需要一些不同的文件夹,或者不同的标签来完成这件事,来区分开来自工作的邮件、来自朋友的邮件、来自家人的邮件或者是有关兴趣爱好的邮件,那么,我们就有了这样一个分类问题:其类别有四个,分别用、、、 来代表。
第二个例子是有关药物诊断的,如果一个病人因为鼻塞来到你的诊所,他可能并没有生病,用 这个类别来代表;或者患了感冒,用 来代表;或者得了流感用来代表。
第三个例子:如果你正在做有关天气的机器学习分类问题,那么你可能想要区分哪些天是晴天、多云、雨天、或者下雪天,对上述所有的例子, 可以取一个很小的数值,一个相对"谨慎"的数值,比如1 到3、1到4或者其它数值,以上说的都是多类分类问题,顺便一提的是,对于下标是0 1 2 3,还是 1 2 3 4 都不重要,我更喜欢将分类从 1 开始标而不是0,其实怎样标注都不会影响最后的结果。
然而对于之前的一个,二元分类问题,我们的数据看起来可能是像这样:
对于一个多类分类问题,我们的数据集或许看起来像这样:
我用3种不同的符号来代表3个类别,问题就是给出3个类型的数据集,我们如何得到一个学习算法来进行分类呢?
我们现在已经知道如何进行二元分类,可以使用逻辑回归,对于直线或许你也知道,可以将数据集一分为二为正类和负类。用一对多的分类思想,我们可以将其用在多类分类问题上。
下面将介绍如何进行一对多的分类工作,有时这个方法也被称为"一对余"方法。
现在我们有一个训练集,好比上图表示的有3个类别,我们用三角形表示 ,方框表示,叉叉表示 。我们下面要做的就是使用一个训练集,将其分成3个二元分类问题。
我们先从用三角形代表的类别1开始,实际上我们可以创建一个,新的"伪"训练集,类型2和类型3定为负类,类型1设定为正类,我们创建一个新的训练集,如下图所示的那样,我们要拟合出一个合适的分类器。
这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为1,圆形的值为0,下面我们来训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。
为了能实现这样的转变,我们将多个类中的一个类标记为正向类(),然后将其他所有类都标记为负向类,这个模型记作。接着,类似地第我们选择另一个类标记为正向类(),再将其它类都标记为负向类,将这个模型记作 ,依此类推。 -最后我们得到一系列的模型简记为: 其中:
最后,在我们需要做预测时,我们将所有的分类机都运行一遍,然后对每一个输入变量,都选择最高可能性的输出变量。
总之,我们已经把要做的做完了,现在要做的就是训练这个逻辑回归分类器:, 其中 对应每一个可能的 ,最后,为了做出预测,我们给出输入一个新的 值,用这个做预测。我们要做的就是在我们三个分类器里面输入 ,然后我们选择一个让 最大的,即。
你现在知道了基本的挑选分类器的方法,选择出哪一个分类器是可信度最高效果最好的,那么就可认为得到一个正确的分类,无论值是多少,我们都有最高的概率值,我们预测就是那个值。这就是多类别分类问题,以及一对多的方法,通过这个小方法,你现在也可以将逻辑回归分类器用在多类分类的问题上。
参考视频: 7 - 1 - The Problem of Overfitting (10 min).mkv
到现在为止,我们已经学习了几种不同的学习算法,包括线性回归和逻辑回归,它们能够有效地解决许多问题,但是当将它们应用到某些特定的机器学习应用时,会遇到过拟合(over-fitting)的问题,可能会导致它们效果很差。
在这段视频中,我将为你解释什么是过度拟合问题,并且在此之后接下来的几个视频中,我们将谈论一种称为正则化(regularization)的技术,它可以改善或者减少过度拟合问题。
如果我们有非常多的特征,我们通过学习得到的假设可能能够非常好地适应训练集(代价函数可能几乎为0),但是可能会不能推广到新的数据。
下图是一个回归问题的例子:
第一个模型是一个线性模型,欠拟合,不能很好地适应我们的训练集;第三个模型是一个四次方的模型,过于强调拟合原始数据,而丢失了算法的本质:预测新数据。我们可以看出,若给出一个新的值使之预测,它将表现的很差,是过拟合,虽然能非常好地适应我们的训练集但在新输入变量进行预测时可能会效果不好;而中间的模型似乎最合适。
分类问题中也存在这样的问题:
就以多项式理解, 的次数越高,拟合的越好,但相应的预测的能力就可能变差。
问题是,如果我们发现了过拟合问题,应该如何处理?
参考视频: 7 - 2 - Cost Function (10 min).mkv
上面的回归问题中如果我们的模型是: - + +我把它写在这里,将后面这个式子,在 到 上求和,其实就是预测误差乘以 ,所以你把这个偏导数项放回到原来式子这里,我们就可以将梯度下降算法写作如下形式: +
所以,如果你有 个特征,也就是说:,参数向量包括 一直到,那么你就需要用这个式子:
来同时更新所有的值。
现在,如果你把这个更新规则和我们之前用在线性回归上的进行比较的话,你会惊讶地发现,这个式子正是我们用来做线性回归梯度下降的。
那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看看发生了哪些变化。实际上,假设的定义发生了变化。
对于线性回归假设函数:
而现在逻辑函数假设函数:
因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。
在先前的视频中,当我们在谈论线性回归的梯度下降法时,我们谈到了如何监控梯度下降法以确保其收敛,我通常也把同样的方法用在逻辑回归中,来监测梯度下降,以确保它正常收敛。
当使用梯度下降法来实现逻辑回归时,我们有这些不同的参数,就是 一直到,我们需要用这个表达式来更新这些参数。我们还可以使用 for循环来更新这些参数值,用 for i=1 to n
,或者 for i=1 to n+1
。当然,不用 for循环也是可以的,理想情况下,我们更提倡使用向量化的实现,可以把所有这些 个参数同时更新。
最后还有一点,我们之前在谈线性回归时讲到的特征缩放,我们看到了特征缩放是如何提高梯度下降的收敛速度的,这个特征缩放的方法,也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。
就是这样,现在你知道如何实现逻辑回归,这是一种非常强大,甚至可能世界上使用最广泛的一种分类算法。
参考视频: 6 - 6 - Advanced Optimization (14 min).mkv
在上一个视频中,我们讨论了用梯度下降的方法最小化逻辑回归中代价函数。在本次视频中,我会教你们一些高级优化算法和一些高级的优化概念,利用这些方法,我们就能够使通过梯度下降,进行逻辑回归的速度大大提高,而这也将使算法更加适合解决大型的机器学习问题,比如,我们有数目庞大的特征量。 +现在我们换个角度来看什么是梯度下降,我们有个代价函数,而我们想要使其最小化,那么我们需要做的是编写代码,当输入参数 时,它们会计算出两样东西: 以及 等于 0、1直到 时的偏导数项。
假设我们已经完成了可以实现这两件事的代码,那么梯度下降所做的就是反复执行这些更新。 +另一种考虑梯度下降的思路是:我们需要写出代码来计算 和这些偏导数,然后把这些插入到梯度下降中,然后它就可以为我们最小化这个函数。 +对于梯度下降来说,我认为从技术上讲,你实际并不需要编写代码来计算代价函数。你只需要编写代码来计算导数项,但是,如果你希望代码还要能够监控这些 的收敛性,那么我们就需要自己编写代码来计算代价函数和偏导数项。所以,在写完能够计算这两者的代码之后,我们就可以使用梯度下降。 +然而梯度下降并不是我们可以使用的唯一算法,还有其他一些算法,更高级、更复杂。如果我们能用这些方法来计算代价函数和偏导数项两个项的话,那么这些算法就是为我们优化代价函数的不同方法,共轭梯度法 BFGS (变尺度法) 和L-BFGS (限制变尺度法) 就是其中一些更高级的优化算法,它们需要有一种方法来计算 ,以及需要一种方法计算导数项,然后使用比梯度下降更复杂的算法来最小化代价函数。这三种算法的具体细节超出了本门课程的范畴。实际上你最后通常会花费很多天,或几周时间研究这些算法,你可以专门学一门课来提高数值计算能力,不过让我来告诉你他们的一些特性:
这三种算法有许多优点:
一个是使用这其中任何一个算法,你通常不需要手动选择学习率 ,所以对于这些算法的一种思路是,给出计算导数项和代价函数的方法,你可以认为算法有一个智能的内部循环,而且,事实上,他们确实有一个智能的内部循环,称为线性搜索(line search)算法,它可以自动尝试不同的学习速率 ,并自动选择一个好的学习速率 ,因此它甚至可以为每次迭代选择不同的学习速率,那么你就不需要自己选择。这些算法实际上在做更复杂的事情,不仅仅是选择一个好的学习速率,所以它们往往最终比梯度下降收敛得快多了,不过关于它们到底做什么的详细讨论,已经超过了本门课程的范围。
实际上,我过去使用这些算法已经很长一段时间了,也许超过十年了,使用得相当频繁,而直到几年前我才真正搞清楚共轭梯度法 BFGS 和 L-BFGS的细节。
我们实际上完全有可能成功使用这些算法,并应用于许多不同的学习问题,而不需要真正理解这些算法的内环间在做什么,如果说这些算法有缺点的话,那么我想说主要缺点是它们比梯度下降法复杂多了,特别是你最好不要使用 L-BGFS、BFGS这些算法,除非你是数值计算方面的专家。实际上,我不会建议你们编写自己的代码来计算数据的平方根,或者计算逆矩阵,因为对于这些算法,我还是会建议你直接使用一个软件库,比如说,要求一个平方根,我们所能做的就是调用一些别人已经写好用来计算数字平方根的函数。幸运的是现在我们有Octave 和与它密切相关的 MATLAB 语言可以使用。
Octave 有一个非常理想的库用于实现这些先进的优化算法,所以,如果你直接调用它自带的库,你就能得到不错的结果。我必须指出这些算法实现得好或不好是有区别的,因此,如果你正在你的机器学习程序中使用一种不同的语言,比如如果你正在使用C、C++、Java等等,你可能会想尝试一些不同的库,以确保你找到一个能很好实现这些算法的库。因为在L-BFGS或者等高线梯度的实现上,表现得好与不太好是有差别的,因此现在让我们来说明:如何使用这些算法:
比方说,你有一个含两个参数的问题,这两个参数是和,因此,通过这个代价函数,你可以得到和 的值,如果你将 最小化的话,那么它的最小值将是 ,。代价函数的导数推出来就是这两个表达式:
如果我们不知道最小值,但你想要代价函数找到这个最小值,是用比如梯度下降这些算法,但最好是用比它更高级的算法,你要做的就是运行一个像这样的Octave 函数:
xxxxxxxxxx
function [jVal, gradient]=costFunction(theta)
jVal=(theta(1)-5)^2+(theta(2)-5)^2;
gradient=zeros(2,1);
gradient(1)=2*(theta(1)-5);
gradient(2)=2*(theta(2)-5);
end
这样就计算出这个代价函数,函数返回的第二个值是梯度值,梯度值应该是一个2×1的向量,梯度向量的两个元素对应这里的两个偏导数项,运行这个costFunction 函数后,你就可以调用高级的优化函数,这个函数叫 +fminunc,它表示Octave 里无约束最小化函数。调用它的方式如下:
xxxxxxxxxx
options=optimset('GradObj','on','MaxIter',100);
initialTheta=zeros(2,1);
[optTheta, functionVal, exitFlag]=fminunc(@costFunction, initialTheta, options);
你要设置几个options,这个 options 变量作为一个数据结构可以存储你想要的options,所以 GradObj 和On,这里设置梯度目标参数为打开(on),这意味着你现在确实要给这个算法提供一个梯度,然后设置最大迭代次数,比方说100,我们给出一个 的猜测初始值,它是一个2×1的向量,那么这个命令就调用fminunc,这个@符号表示指向我们刚刚定义的costFunction 函数的指针。如果你调用它,它就会使用众多高级优化算法中的一个,当然你也可以把它当成梯度下降,只不过它能自动选择学习速率,你不需要自己来做。然后它会尝试使用这些高级的优化算法,就像加强版的梯度下降法,为你找到最佳的值。
让我告诉你它在 Octave 里什么样:
所以我写了这个关于theta的 costFunction 函数,它计算出代价函数 jval以及梯度gradient,gradient 有两个元素,是代价函数对于theta(1) 和 theta(2)这两个参数的偏导数。
我希望你们从这个幻灯片中学到的主要内容是:写一个函数,它能返回代价函数值、梯度值,因此要把这个应用到逻辑回归,或者甚至线性回归中,你也可以把这些优化算法用于线性回归,你需要做的就是输入合适的代码来计算这里的这些东西。
现在你已经知道如何使用这些高级的优化算法,有了这些算法,你就可以使用一个复杂的优化库,它让算法使用起来更模糊一点。因此也许稍微有点难调试,不过由于这些算法的运行速度通常远远超过梯度下降。
所以当我有一个很大的机器学习问题时,我会选择这些高级算法,而不是梯度下降。有了这些概念,你就应该能将逻辑回归和线性回归应用于更大的问题中,这就是高级优化的概念。
在下一个视频,我想要告诉你如何修改你已经知道的逻辑回归算法,然后使它在多类别分类问题中也能正常运行。
参考视频: 6 - 7 - Multiclass Classification_ One-vs-all (6 min).mkv
在本节视频中,我们将谈到如何使用逻辑回归 (logistic regression)来解决多类别分类问题,具体来说,我想通过一个叫做"一对多" (one-vs-all) 的分类算法。
先看这样一些例子。
第一个例子:假如说你现在需要一个学习算法能自动地将邮件归类到不同的文件夹里,或者说可以自动地加上标签,那么,你也许需要一些不同的文件夹,或者不同的标签来完成这件事,来区分开来自工作的邮件、来自朋友的邮件、来自家人的邮件或者是有关兴趣爱好的邮件,那么,我们就有了这样一个分类问题:其类别有四个,分别用、、、 来代表。
第二个例子是有关药物诊断的,如果一个病人因为鼻塞来到你的诊所,他可能并没有生病,用 这个类别来代表;或者患了感冒,用 来代表;或者得了流感用来代表。
第三个例子:如果你正在做有关天气的机器学习分类问题,那么你可能想要区分哪些天是晴天、多云、雨天、或者下雪天,对上述所有的例子, 可以取一个很小的数值,一个相对"谨慎"的数值,比如1 到3、1到4或者其它数值,以上说的都是多类分类问题,顺便一提的是,对于下标是0 1 2 3,还是 1 2 3 4 都不重要,我更喜欢将分类从 1 开始标而不是0,其实怎样标注都不会影响最后的结果。
然而对于之前的一个,二元分类问题,我们的数据看起来可能是像这样:
对于一个多类分类问题,我们的数据集或许看起来像这样:
我用3种不同的符号来代表3个类别,问题就是给出3个类型的数据集,我们如何得到一个学习算法来进行分类呢?
我们现在已经知道如何进行二元分类,可以使用逻辑回归,对于直线或许你也知道,可以将数据集一分为二为正类和负类。用一对多的分类思想,我们可以将其用在多类分类问题上。
下面将介绍如何进行一对多的分类工作,有时这个方法也被称为"一对余"方法。
现在我们有一个训练集,好比上图表示的有3个类别,我们用三角形表示 ,方框表示,叉叉表示 。我们下面要做的就是使用一个训练集,将其分成3个二元分类问题。
我们先从用三角形代表的类别1开始,实际上我们可以创建一个,新的"伪"训练集,类型2和类型3定为负类,类型1设定为正类,我们创建一个新的训练集,如下图所示的那样,我们要拟合出一个合适的分类器。
这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为1,圆形的值为0,下面我们来训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。
为了能实现这样的转变,我们将多个类中的一个类标记为正向类(),然后将其他所有类都标记为负向类,这个模型记作。接着,类似地第我们选择另一个类标记为正向类(),再将其它类都标记为负向类,将这个模型记作 ,依此类推。 +最后我们得到一系列的模型简记为: 其中:
最后,在我们需要做预测时,我们将所有的分类机都运行一遍,然后对每一个输入变量,都选择最高可能性的输出变量。
总之,我们已经把要做的做完了,现在要做的就是训练这个逻辑回归分类器:, 其中 对应每一个可能的 ,最后,为了做出预测,我们给出输入一个新的 值,用这个做预测。我们要做的就是在我们三个分类器里面输入 ,然后我们选择一个让 最大的,即。
你现在知道了基本的挑选分类器的方法,选择出哪一个分类器是可信度最高效果最好的,那么就可认为得到一个正确的分类,无论值是多少,我们都有最高的概率值,我们预测就是那个值。这就是多类别分类问题,以及一对多的方法,通过这个小方法,你现在也可以将逻辑回归分类器用在多类分类的问题上。
参考视频: 7 - 1 - The Problem of Overfitting (10 min).mkv
到现在为止,我们已经学习了几种不同的学习算法,包括线性回归和逻辑回归,它们能够有效地解决许多问题,但是当将它们应用到某些特定的机器学习应用时,会遇到过拟合(over-fitting)的问题,可能会导致它们效果很差。
在这段视频中,我将为你解释什么是过度拟合问题,并且在此之后接下来的几个视频中,我们将谈论一种称为正则化(regularization)的技术,它可以改善或者减少过度拟合问题。
如果我们有非常多的特征,我们通过学习得到的假设可能能够非常好地适应训练集(代价函数可能几乎为0),但是可能会不能推广到新的数据。
下图是一个回归问题的例子:
第一个模型是一个线性模型,欠拟合,不能很好地适应我们的训练集;第三个模型是一个四次方的模型,过于强调拟合原始数据,而丢失了算法的本质:预测新数据。我们可以看出,若给出一个新的值使之预测,它将表现的很差,是过拟合,虽然能非常好地适应我们的训练集但在新输入变量进行预测时可能会效果不好;而中间的模型似乎最合适。
分类问题中也存在这样的问题:
就以多项式理解, 的次数越高,拟合的越好,但相应的预测的能力就可能变差。
问题是,如果我们发现了过拟合问题,应该如何处理?
参考视频: 7 - 2 - Cost Function (10 min).mkv
上面的回归问题中如果我们的模型是: + 我们可以从之前的事例中看出,正是那些高次项导致了过拟合的产生,所以如果我们能让这些高次项的系数接近于0的话,我们就能很好的拟合了。 -所以我们要做的就是在一定程度上减小这些参数 的值,这就是正则化的基本方法。我们决定要减少和的大小,我们要做的便是修改代价函数,在其中和 设置一点惩罚。这样做的话,我们在尝试最小化代价时也需要将这个惩罚纳入考虑中,并最终导致选择较小一些的和。 -修改后的代价函数如下:
通过这样的代价函数选择出的和 对预测结果的影响就比之前要小许多。假如我们有非常多的特征,我们并不知道其中哪些特征我们要惩罚,我们将对所有的特征进行惩罚,并且让代价函数最优化的软件来选择这些惩罚的程度。这样的结果是得到了一个较为简单的能防止过拟合问题的假设:
其中又称为正则化参数(Regularization Parameter)。 注:根据惯例,我们不对 进行惩罚。经过正则化处理的模型与原模型的可能对比如下图所示:
如果选择的正则化参数λ过大,则会把所有的参数都最小化了,导致模型变成 ,也就是上图中红色直线所示的情况,造成欠拟合。 -那为什么增加的一项 可以使的值减小呢? -因为如果我们令 的值很大的话,为了使Cost Function 尽可能的小,所有的 的值(不包括)都会在一定程度上减小。 -但若λ的值太大了,那么(不包括)都会趋近于0,这样我们所得到的只能是一条平行于轴的直线。 -所以对于正则化,我们要取一个合理的 的值,这样才能更好的应用正则化。 -回顾一下代价函数,为了使用正则化,让我们把这些概念应用到到线性回归和逻辑回归中去,那么我们就可以让他们避免过度拟合了。
参考视频: 7 - 3 - Regularized Linear Regression (11 min).mkv
对于线性回归的求解,我们之前推导了两种学习算法:一种基于梯度下降,一种基于正规方程。
正则化线性回归的代价函数为:
如果我们要使用梯度下降法令这个代价函数最小化,因为我们未对进行正则化,所以梯度下降算法将分两种情形:
{
}
对上面的算法中 时的更新式子进行调整可得:
-可以看出,正则化线性回归的梯度下降算法的变化在于,每次都在原有算法更新规则的基础上令值减少了一个额外的值。
我们同样也可以利用正规方程来求解正则化线性回归模型,方法如下所示:
图中的矩阵尺寸为 。
参考视频: 7 - 4 - Regularized Logistic Regression (9 min).mkv
针对逻辑回归问题,我们在之前的课程已经学习过两种优化算法:我们首先学习了使用梯度下降法来优化代价函数,接下来学习了更高级的优化算法,这些高级优化算法需要你自己设计代价函数。
自己计算导数同样对于逻辑回归,我们也给代价函数增加一个正则化的表达式,得到代价函数:
Python代码:
xxxxxxxxxx
import numpy as np
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X*theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X*theta.T)))
reg = (learningRate / (2 * len(X))* np.sum(np.power(theta[:,1:theta.shape[1]],2))
return np.sum(first - second) / (len(X)) + reg
要最小化该代价函数,通过求导,得出梯度下降算法为:
{
}
注:看上去同线性回归一样,但是知道 ,所以与线性回归不同。
-Octave 中,我们依旧可以用 fminuc
函数来求解代价函数最小化的参数,值得注意的是参数的更新规则与其他情况不同。
-注意:
目前大家对机器学习算法可能还只是略懂,但是一旦你精通了线性回归、高级优化算法和正则化技术,坦率地说,你对机器学习的理解可能已经比许多工程师深入了。现在,你已经有了丰富的机器学习知识,目测比那些硅谷工程师还厉害,或者用机器学习算法来做产品。
接下来的课程中,我们将学习一个非常强大的非线性分类器,无论是线性回归问题,还是逻辑回归问题,都可以构造多项式来解决。你将逐渐发现还有更强大的非线性分类器,可以用来解决多项式回归问题。我们接下来将将学会,比现在解决问题的方法强大N倍的学习算法。
通过这样的代价函数选择出的和 对预测结果的影响就比之前要小许多。假如我们有非常多的特征,我们并不知道其中哪些特征我们要惩罚,我们将对所有的特征进行惩罚,并且让代价函数最优化的软件来选择这些惩罚的程度。这样的结果是得到了一个较为简单的能防止过拟合问题的假设:
其中又称为正则化参数(Regularization Parameter)。 注:根据惯例,我们不对 进行惩罚。经过正则化处理的模型与原模型的可能对比如下图所示:
如果选择的正则化参数 过大,则会把所有的参数都最小化了,导致模型变成 ,也就是上图中红色直线所示的情况,造成欠拟合。 +那为什么增加的一项 可以使的值减小呢? +因为如果我们令 的值很大的话,为了使Cost Function 尽可能的小,所有的 的值(不包括)都会在一定程度上减小。 +但若 的值太大了,那么(不包括)都会趋近于0,这样我们所得到的只能是一条平行于轴的直线。 +所以对于正则化,我们要取一个合理的 的值,这样才能更好的应用正则化。 +回顾一下代价函数,为了使用正则化,让我们把这些概念应用到到线性回归和逻辑回归中去,那么我们就可以让他们避免过度拟合了。
参考视频: 7 - 3 - Regularized Linear Regression (11 min).mkv
对于线性回归的求解,我们之前推导了两种学习算法:一种基于梯度下降,一种基于正规方程。
正则化线性回归的代价函数为:
如果我们要使用梯度下降法令这个代价函数最小化,因为我们未对进行正则化,所以梯度下降算法将分两种情形:
{
xxxxxxxxxx
${\theta_0}:={\theta_0}-a\frac{1}{m}\sum\limits_{i=1}^{m}{(({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{0}^{(i)}})$
${\theta_j}:={\theta_j}-a[\frac{1}{m}\sum\limits_{i=1}^{m}{(({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{j}^{\left( i \right)}}+\frac{\lambda }{m}{\theta_j}]$
$for$ $j=1,2,...n$
}
对上面的算法中 时的更新式子进行调整可得:
+可以看出,正则化线性回归的梯度下降算法的变化在于,每次都在原有算法更新规则的基础上令值减少了一个额外的值。
我们同样也可以利用正规方程来求解正则化线性回归模型,方法如下所示:
图中的矩阵尺寸为 。
参考视频: 7 - 4 - Regularized Logistic Regression (9 min).mkv
针对逻辑回归问题,我们在之前的课程已经学习过两种优化算法:我们首先学习了使用梯度下降法来优化代价函数,接下来学习了更高级的优化算法,这些高级优化算法需要你自己设计代价函数。
自己计算导数同样对于逻辑回归,我们也给代价函数增加一个正则化的表达式,得到代价函数:
Python代码:
xxxxxxxxxx
import numpy as np
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X*theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X*theta.T)))
reg = (learningRate / (2 * len(X))* np.sum(np.power(theta[:,1:theta.shape[1]],2))
return np.sum(first - second) / (len(X)) + reg
要最小化该代价函数,通过求导,得出梯度下降算法为:
{
xxxxxxxxxx
${\theta_0}:={\theta_0}-a\frac{1}{m}\sum\limits_{i=1}^{m}{(({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{0}^{(i)}})$
${\theta_j}:={\theta_j}-a[\frac{1}{m}\sum\limits_{i=1}^{m}{({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{j}^{\left( i \right)}}+\frac{\lambda }{m}{\theta_j}]$
$for$ $j=1,2,...n$
}
注:看上去同线性回归一样,但是知道 ,所以与线性回归不同。
+Octave 中,我们依旧可以用 fminuc
函数来求解代价函数最小化的参数,值得注意的是参数的更新规则与其他情况不同。
+注意:
目前大家对机器学习算法可能还只是略懂,但是一旦你精通了线性回归、高级优化算法和正则化技术,坦率地说,你对机器学习的理解可能已经比许多工程师深入了。现在,你已经有了丰富的机器学习知识,目测比那些硅谷工程师还厉害,或者用机器学习算法来做产品。
接下来的课程中,我们将学习一个非常强大的非线性分类器,无论是线性回归问题,还是逻辑回归问题,都可以构造多项式来解决。你将逐渐发现还有更强大的非线性分类器,可以用来解决多项式回归问题。我们接下来将将学会,比现在解决问题的方法强大N倍的学习算法。
第4周第八、神经网络:表述(Neural Networks: Representation)8.1 非线性假设8.2 神经元和大脑8.3 模型表示18.4 模型表示28.5 特征和直观理解18.6 样本和直观理解II8.7 多类分类
参考视频: 8 - 1 - Non-linear Hypotheses (10 min).mkv
我们之前学的,无论是线性回归还是逻辑回归都有这样一个缺点,即:当特征太多时,计算的负荷会非常大。
下面是一个例子:
当我们使用, 的多次项式进行预测时,我们可以应用的很好。 -之前我们已经看到过,使用非线性的多项式项,能够帮助我们建立更好的分类模型。假设我们有非常多的特征,例如大于100个变量,我们希望用这100个特征来构建一个非线性的多项式模型,结果将是数量非常惊人的特征组合,即便我们只采用两两特征的组合,我们也会有接近5000个组合而成的特征。这对于一般的逻辑回归来说需要计算的特征太多了。
假设我们希望训练一个模型来识别视觉对象(例如识别一张图片上是否是一辆汽车),我们怎样才能这么做呢?一种方法是我们利用很多汽车的图片和很多非汽车的图片,然后利用这些图片上一个个像素的值(饱和度或亮度)来作为特征。
假如我们只选用灰度图片,每个像素则只有一个值(而非 RGB值),我们可以选取图片上的两个不同位置上的两个像素,然后训练一个逻辑回归算法利用这两个像素的值来判断图片上是否是汽车:
假使我们采用的都是50x50像素的小图片,并且我们将所有的像素视为特征,则会有 2500个特征,如果我们要进一步将两两特征组合构成一个多项式模型,则会有约个(接近3百万个)特征。普通的逻辑回归模型,不能有效地处理这么多的特征,这时候我们需要神经网络。
参考视频: 8 - 2 - Neurons and the Brain (8 min).mkv
神经网络是一种很古老的算法,它最初产生的目的是制造能模拟大脑的机器。
在这门课中,我将向你们介绍神经网络。因为它能很好地解决不同的机器学习问题。而不只因为它们在逻辑上行得通,在这段视频中,我想告诉你们一些神经网络的背景知识,由此我们能知道可以用它们来做什么。不管是将其应用到现代的机器学习问题上,还是应用到那些你可能会感兴趣的问题中。也许,这一伟大的人工智能梦想在未来能制造出真正的智能机器。另外,我们还将讲解神经网络是怎么涉及这些问题的神经网络产生的原因是人们想尝试设计出模仿大脑的算法,从某种意义上说如果我们想要建立学习系统,那为什么不去模仿我们所认识的最神奇的学习机器——人类的大脑呢?
神经网络逐渐兴起于二十世纪八九十年代,应用得非常广泛。但由于各种原因,在90年代的后期应用减少了。但是最近,神经网络又东山再起了。其中一个原因是:神经网络是计算量有些偏大的算法。然而大概由于近些年计算机的运行速度变快,才足以真正运行起大规模的神经网络。正是由于这个原因和其他一些我们后面会讨论到的技术因素,如今的神经网络对于许多应用来说是最先进的技术。当你想模拟大脑时,是指想制造出与人类大脑作用效果相同的机器。大脑可以学会去以看而不是听的方式处理图像,学会处理我们的触觉。
我们能学习数学,学着做微积分,而且大脑能处理各种不同的令人惊奇的事情。似乎如果你想要模仿它,你得写很多不同的软件来模拟所有这些五花八门的奇妙的事情。不过能不能假设大脑做所有这些,不同事情的方法,不需要用上千个不同的程序去实现。相反的,大脑处理的方法,只需要一个单一的学习算法就可以了?尽管这只是一个假设,不过让我和你分享,一些这方面的证据。
大脑的这一部分这一小片红色区域是你的听觉皮层,你现在正在理解我的话,这靠的是耳朵。耳朵接收到声音信号,并把声音信号传递给你的听觉皮层,正因如此,你才能明白我的话。
神经系统科学家做了下面这个有趣的实验,把耳朵到听觉皮层的神经切断。在这种情况下,将其重新接到一个动物的大脑上,这样从眼睛到视神经的信号最终将传到听觉皮层。如果这样做了。那么结果表明听觉皮层将会学会“看”。这里的“看”代表了我们所知道的每层含义。所以,如果你对动物这样做,那么动物就可以完成视觉辨别任务,它们可以看图像,并根据图像做出适当的决定。它们正是通过脑组织中的这个部分完成的。下面再举另一个例子,这块红色的脑组织是你的躯体感觉皮层,这是你用来处理触觉的,如果你做一个和刚才类似的重接实验,那么躯体感觉皮层也能学会“看”。这个实验和其它一些类似的实验,被称为神经重接实验,从这个意义上说,如果人体有同一块脑组织可以处理光、声或触觉信号,那么也许存在一种学习算法,可以同时处理视觉、听觉和触觉,而不是需要运行上千个不同的程序,或者上千个不同的算法来做这些大脑所完成的成千上万的美好事情。也许我们需要做的就是找出一些近似的或实际的大脑学习算法,然后实现它大脑通过自学掌握如何处理这些不同类型的数据。在很大的程度上,可以猜想如果我们把几乎任何一种传感器接入到大脑的几乎任何一个部位的话,大脑就会学会处理它。
下面再举几个例子:
这张图是用舌头学会“看”的一个例子。它的原理是:这实际上是一个名为BrainPort的系统,它现在正在FDA -(美国食品和药物管理局)的临床试验阶段,它能帮助失明人士看见事物。它的原理是,你在前额上带一个灰度摄像头,面朝前,它就能获取你面前事物的低分辨率的灰度图像。你连一根线到舌头上安装的电极阵列上,那么每个像素都被映射到你舌头的某个位置上,可能电压值高的点对应一个暗像素电压值低的点。对应于亮像素,即使依靠它现在的功能,使用这种系统就能让你我在几十分钟里就学会用我们的舌头“看”东西。
这是第二个例子,关于人体回声定位或者说人体声纳。你有两种方法可以实现:你可以弹响指,或者咂舌头。不过现在有失明人士,确实在学校里接受这样的培训,并学会解读从环境反弹回来的声波模式—这就是声纳。如果你搜索YouTube之后,就会发现有些视频讲述了一个令人称奇的孩子,他因为癌症眼球惨遭移除,虽然失去了眼球,但是通过打响指,他可以四处走动而不撞到任何东西,他能滑滑板,他可以将篮球投入篮框中。注意这是一个没有眼球的孩子。
第三个例子是触觉皮带,如果你把它戴在腰上,蜂鸣器会响,而且总是朝向北时发出嗡嗡声。它可以使人拥有方向感,用类似于鸟类感知方向的方式。
还有一些离奇的例子:
如果你在青蛙身上插入第三只眼,青蛙也能学会使用那只眼睛。因此,这将会非常令人惊奇。如果你能把几乎任何传感器接入到大脑中,大脑的学习算法就能找出学习数据的方法,并处理这些数据。从某种意义上来说,如果我们能找出大脑的学习算法,然后在计算机上执行大脑学习算法或与之相似的算法,也许这将是我们向人工智能迈进做出的最好的尝试。人工智能的梦想就是:有一天能制造出真正的智能机器。
神经网络可能为我们打开一扇进入遥远的人工智能梦的窗户,但我在这节课中讲授神经网络的原因,主要是对于现代机器学习应用。它是最有效的技术方法。因此在接下来的一些课程中,我们将开始深入到神经网络的技术细节。
参考视频: 8 - 3 - Model Representation I (12 min).mkv
为了构建神经网络模型,我们需要首先思考大脑中的神经网络是怎样的?每一个神经元都可以被认为是一个处理单元/神经核(processing unit/Nucleus),它含有许多输入/树突(input/Dendrite),并且有一个输出/轴突(output/Axon)。神经网络是大量神经元相互链接并通过电脉冲来交流的一个网络。
下面是一组神经元的示意图,神经元利用微弱的电流进行沟通。这些弱电流也称作动作电位,其实就是一些微弱的电流。所以如果神经元想要传递一个消息,它就会就通过它的轴突,发送一段微弱电流给其他神经元,这就是轴突。
这里是一条连接到输入神经,或者连接另一个神经元树突的神经,接下来这个神经元接收这条消息,做一些计算,它有可能会反过来将在轴突上的自己的消息传给其他神经元。这就是所有人类思考的模型:我们的神经元把自己的收到的消息进行计算,并向其他神经元传递消息。这也是我们的感觉和肌肉运转的原理。如果你想活动一块肌肉,就会触发一个神经元给你的肌肉发送脉冲,并引起你的肌肉收缩。如果一些感官:比如说眼睛想要给大脑传递一个消息,那么它就像这样发送电脉冲给大脑的。
神经网络模型建立在很多神经元之上,每一个神经元又是一个个学习模型。这些神经元(也叫激活单元,activation unit)采纳一些特征作为输出,并且根据本身的模型提供一个输出。下图是一个以逻辑回归模型作为自身学习模型的神经元示例,在神经网络中,参数又可被成为权重(weight)。
我们设计出了类似于神经元的神经网络,效果如下:
其中, , 是输入单元(input units),我们将原始数据输入给它们。 +
第4周第八、神经网络:表述(Neural Networks: Representation)8.1 非线性假设8.2 神经元和大脑8.3 模型表示18.4 模型表示28.5 特征和直观理解18.6 样本和直观理解II8.7 多类分类
参考视频: 8 - 1 - Non-linear Hypotheses (10 min).mkv
我们之前学的,无论是线性回归还是逻辑回归都有这样一个缺点,即:当特征太多时,计算的负荷会非常大。
下面是一个例子:
当我们使用, 的多次项式进行预测时,我们可以应用的很好。 +之前我们已经看到过,使用非线性的多项式项,能够帮助我们建立更好的分类模型。假设我们有非常多的特征,例如大于100个变量,我们希望用这100个特征来构建一个非线性的多项式模型,结果将是数量非常惊人的特征组合,即便我们只采用两两特征的组合,我们也会有接近5000个组合而成的特征。这对于一般的逻辑回归来说需要计算的特征太多了。
假设我们希望训练一个模型来识别视觉对象(例如识别一张图片上是否是一辆汽车),我们怎样才能这么做呢?一种方法是我们利用很多汽车的图片和很多非汽车的图片,然后利用这些图片上一个个像素的值(饱和度或亮度)来作为特征。
假如我们只选用灰度图片,每个像素则只有一个值(而非 RGB值),我们可以选取图片上的两个不同位置上的两个像素,然后训练一个逻辑回归算法利用这两个像素的值来判断图片上是否是汽车:
假使我们采用的都是50x50像素的小图片,并且我们将所有的像素视为特征,则会有 2500个特征,如果我们要进一步将两两特征组合构成一个多项式模型,则会有约个(接近3百万个)特征。普通的逻辑回归模型,不能有效地处理这么多的特征,这时候我们需要神经网络。
参考视频: 8 - 2 - Neurons and the Brain (8 min).mkv
神经网络是一种很古老的算法,它最初产生的目的是制造能模拟大脑的机器。
在这门课中,我将向你们介绍神经网络。因为它能很好地解决不同的机器学习问题。而不只因为它们在逻辑上行得通,在这段视频中,我想告诉你们一些神经网络的背景知识,由此我们能知道可以用它们来做什么。不管是将其应用到现代的机器学习问题上,还是应用到那些你可能会感兴趣的问题中。也许,这一伟大的人工智能梦想在未来能制造出真正的智能机器。另外,我们还将讲解神经网络是怎么涉及这些问题的神经网络产生的原因是人们想尝试设计出模仿大脑的算法,从某种意义上说如果我们想要建立学习系统,那为什么不去模仿我们所认识的最神奇的学习机器——人类的大脑呢?
神经网络逐渐兴起于二十世纪八九十年代,应用得非常广泛。但由于各种原因,在90年代的后期应用减少了。但是最近,神经网络又东山再起了。其中一个原因是:神经网络是计算量有些偏大的算法。然而大概由于近些年计算机的运行速度变快,才足以真正运行起大规模的神经网络。正是由于这个原因和其他一些我们后面会讨论到的技术因素,如今的神经网络对于许多应用来说是最先进的技术。当你想模拟大脑时,是指想制造出与人类大脑作用效果相同的机器。大脑可以学会去以看而不是听的方式处理图像,学会处理我们的触觉。
我们能学习数学,学着做微积分,而且大脑能处理各种不同的令人惊奇的事情。似乎如果你想要模仿它,你得写很多不同的软件来模拟所有这些五花八门的奇妙的事情。不过能不能假设大脑做所有这些,不同事情的方法,不需要用上千个不同的程序去实现。相反的,大脑处理的方法,只需要一个单一的学习算法就可以了?尽管这只是一个假设,不过让我和你分享,一些这方面的证据。
大脑的这一部分这一小片红色区域是你的听觉皮层,你现在正在理解我的话,这靠的是耳朵。耳朵接收到声音信号,并把声音信号传递给你的听觉皮层,正因如此,你才能明白我的话。
神经系统科学家做了下面这个有趣的实验,把耳朵到听觉皮层的神经切断。在这种情况下,将其重新接到一个动物的大脑上,这样从眼睛到视神经的信号最终将传到听觉皮层。如果这样做了。那么结果表明听觉皮层将会学会“看”。这里的“看”代表了我们所知道的每层含义。所以,如果你对动物这样做,那么动物就可以完成视觉辨别任务,它们可以看图像,并根据图像做出适当的决定。它们正是通过脑组织中的这个部分完成的。下面再举另一个例子,这块红色的脑组织是你的躯体感觉皮层,这是你用来处理触觉的,如果你做一个和刚才类似的重接实验,那么躯体感觉皮层也能学会“看”。这个实验和其它一些类似的实验,被称为神经重接实验,从这个意义上说,如果人体有同一块脑组织可以处理光、声或触觉信号,那么也许存在一种学习算法,可以同时处理视觉、听觉和触觉,而不是需要运行上千个不同的程序,或者上千个不同的算法来做这些大脑所完成的成千上万的美好事情。也许我们需要做的就是找出一些近似的或实际的大脑学习算法,然后实现它大脑通过自学掌握如何处理这些不同类型的数据。在很大的程度上,可以猜想如果我们把几乎任何一种传感器接入到大脑的几乎任何一个部位的话,大脑就会学会处理它。
下面再举几个例子:
这张图是用舌头学会“看”的一个例子。它的原理是:这实际上是一个名为BrainPort的系统,它现在正在FDA +(美国食品和药物管理局)的临床试验阶段,它能帮助失明人士看见事物。它的原理是,你在前额上带一个灰度摄像头,面朝前,它就能获取你面前事物的低分辨率的灰度图像。你连一根线到舌头上安装的电极阵列上,那么每个像素都被映射到你舌头的某个位置上,可能电压值高的点对应一个暗像素电压值低的点。对应于亮像素,即使依靠它现在的功能,使用这种系统就能让你我在几十分钟里就学会用我们的舌头“看”东西。
这是第二个例子,关于人体回声定位或者说人体声纳。你有两种方法可以实现:你可以弹响指,或者咂舌头。不过现在有失明人士,确实在学校里接受这样的培训,并学会解读从环境反弹回来的声波模式—这就是声纳。如果你搜索YouTube之后,就会发现有些视频讲述了一个令人称奇的孩子,他因为癌症眼球惨遭移除,虽然失去了眼球,但是通过打响指,他可以四处走动而不撞到任何东西,他能滑滑板,他可以将篮球投入篮框中。注意这是一个没有眼球的孩子。
第三个例子是触觉皮带,如果你把它戴在腰上,蜂鸣器会响,而且总是朝向北时发出嗡嗡声。它可以使人拥有方向感,用类似于鸟类感知方向的方式。
还有一些离奇的例子:
如果你在青蛙身上插入第三只眼,青蛙也能学会使用那只眼睛。因此,这将会非常令人惊奇。如果你能把几乎任何传感器接入到大脑中,大脑的学习算法就能找出学习数据的方法,并处理这些数据。从某种意义上来说,如果我们能找出大脑的学习算法,然后在计算机上执行大脑学习算法或与之相似的算法,也许这将是我们向人工智能迈进做出的最好的尝试。人工智能的梦想就是:有一天能制造出真正的智能机器。
神经网络可能为我们打开一扇进入遥远的人工智能梦的窗户,但我在这节课中讲授神经网络的原因,主要是对于现代机器学习应用。它是最有效的技术方法。因此在接下来的一些课程中,我们将开始深入到神经网络的技术细节。
参考视频: 8 - 3 - Model Representation I (12 min).mkv
为了构建神经网络模型,我们需要首先思考大脑中的神经网络是怎样的?每一个神经元都可以被认为是一个处理单元/神经核(processing unit/Nucleus),它含有许多输入/树突(input/Dendrite),并且有一个输出/轴突(output/Axon)。神经网络是大量神经元相互链接并通过电脉冲来交流的一个网络。
下面是一组神经元的示意图,神经元利用微弱的电流进行沟通。这些弱电流也称作动作电位,其实就是一些微弱的电流。所以如果神经元想要传递一个消息,它就会就通过它的轴突,发送一段微弱电流给其他神经元,这就是轴突。
这里是一条连接到输入神经,或者连接另一个神经元树突的神经,接下来这个神经元接收这条消息,做一些计算,它有可能会反过来将在轴突上的自己的消息传给其他神经元。这就是所有人类思考的模型:我们的神经元把自己的收到的消息进行计算,并向其他神经元传递消息。这也是我们的感觉和肌肉运转的原理。如果你想活动一块肌肉,就会触发一个神经元给你的肌肉发送脉冲,并引起你的肌肉收缩。如果一些感官:比如说眼睛想要给大脑传递一个消息,那么它就像这样发送电脉冲给大脑的。
神经网络模型建立在很多神经元之上,每一个神经元又是一个个学习模型。这些神经元(也叫激活单元,activation unit)采纳一些特征作为输出,并且根据本身的模型提供一个输出。下图是一个以逻辑回归模型作为自身学习模型的神经元示例,在神经网络中,参数又可被成为权重(weight)。
我们设计出了类似于神经元的神经网络,效果如下:
其中, , 是输入单元(input units),我们将原始数据输入给它们。 , , 是中间单元,它们负责将数据进行处理,然后呈递到下一层。 最后是输出单元,它负责计算。
神经网络模型是许多逻辑单元按照不同层级组织起来的网络,每一层的输出变量都是下一层的输入变量。下图为一个3层的神经网络,第一层成为输入层(Input Layer),最后一层称为输出层(Output Layer),中间一层成为隐藏层(Hidden Layers)。我们为每一层都增加一个偏差单位(bias unit):
下面引入一些标记法来帮助描述模型: 代表第 层的第 个激活单元。代表从第 层映射到第 层时的权重的矩阵,例如代表从第一层映射到第二层的权重的矩阵。其尺寸为:以第 层的激活单元数量为行数,以第 层的激活单元数加一为列数的矩阵。例如:上图所示的神经网络中的尺寸为 3*4。
对于上图所示的模型,激活单元和输出分别表达为:
-
上面进行的讨论中只是将特征矩阵中的一行(一个训练实例)喂给了神经网络,我们需要将整个训练集都喂给我们的神经网络算法来学习模型。
我们可以知道:每一个都是由上一层所有的和每一个所对应的决定的。
(我们把这样从左到右的算法称为前向传播算法( FORWARD PROPAGATION ))
把, , 分别用矩阵表示:
我们可以得到 。
参考视频: 8 - 4 - Model Representation II (12 min).mkv
( FORWARD PROPAGATION ) +
上面进行的讨论中只是将特征矩阵中的一行(一个训练实例)喂给了神经网络,我们需要将整个训练集都喂给我们的神经网络算法来学习模型。
我们可以知道:每一个都是由上一层所有的和每一个所对应的决定的。
(我们把这样从左到右的算法称为前向传播算法( FORWARD PROPAGATION ))
把, , 分别用矩阵表示:
我们可以得到 。
参考视频: 8 - 4 - Model Representation II (12 min).mkv
( FORWARD PROPAGATION ) 相对于使用循环来编码,利用向量化的方法会使得计算更为简便。以上面的神经网络为例,试着计算第二层的值:
我们令 ,则 ,计算后添加 。 计算输出的值为:
我们令 ,则 。 这只是针对训练集中一个训练实例所进行的计算。如果我们要对整个训练集进行计算,我们需要将训练集特征矩阵进行转置,使得同一个实例的特征都在同一列里。即: -
为了更好了了解Neuron Networks的工作原理,我们先把左半部分遮住:
右半部分其实就是以, 按照Logistic Regression的方式输出:
其实神经网络就像是logistic regression,只不过我们把logistic regression中的输入向量 变成了中间层的, 即: -我们可以把看成更为高级的特征值,也就是的进化体,并且它们是由 与决定的,因为是梯度下降的,所以是变化的,并且变得越来越厉害,所以这些更高级的特征值远比仅仅将 次方厉害,也能更好的预测新数据。 -这就是神经网络相比于逻辑回归和线性回归的优势。
参考视频: 8 - 5 - Examples and Intuitions I (7 min).mkv
从本质上讲,神经网络能够通过学习得出其自身的一系列特征。在普通的逻辑回归中,我们被限制为使用数据中的原始特征,我们虽然可以使用一些二项式项来组合这些特征,但是我们仍然受到这些原始特征的限制。在神经网络中,原始特征只是输入层,在我们上面三层的神经网络例子中,第三层也就是输出层做出的预测利用的是第二层的特征,而非输入层中的原始特征,我们可以认为第二层中的特征是神经网络通过学习后自己得出的一系列用于预测输出变量的新特征。
神经网络中,单层神经元(无中间层)的计算可用来表示逻辑运算,比如逻辑与(AND)、逻辑或(OR)。
举例说明:逻辑与(AND);下图中左半部分是神经网络的设计与output层表达式,右边上部分是sigmod函数,下半部分是真值表。
我们可以用这样的一个神经网络表示AND 函数:
其中 -我们的输出函数即为:
我们知道的图像是:
所以我们有:
所以我们的:
这就是AND函数。
接下来再介绍一个OR函数:
OR与AND整体一样,区别只在于的取值不同。
参考视频: 8 - 6 - Examples and Intuitions II (10 min).mkv
二元逻辑运算符(BINARY LOGICAL OPERATORS)当输入特征为布尔值(0或1)时,我们可以用一个单一的激活层可以作为二元逻辑运算符,为了表示不同的运算符,我们只需要选择不同的权重即可。
下图的神经元(三个权重分别为-30,20,20)可以被视为作用同于逻辑与(AND):
下图的神经元(三个权重分别为-10,20,20)可以被视为作用等同于逻辑或(OR):
下图的神经元(两个权重分别为 10,-20)可以被视为作用等同于逻辑非(NOT):
我们可以利用神经元来组合成更为复杂的神经网络以实现更复杂的运算。例如我们要实现XNOR 功能(输入的两个值必须一样,均为1或均为0),即 -首先构造一个能表达部分的神经元:
然后将表示 AND 的神经元和表示的神经元以及表示 OR 的神经元进行组合:
我们就得到了一个能实现 运算符功能的神经网络。
按这种方法我们可以逐渐构造出越来越复杂的函数,也能得到更加厉害的特征值。
这就是神经网络的厉害之处。
参考视频: 8 - 7 - Multiclass Classification (4 min).mkv
当我们有不止两种分类时(也就是),比如以下这种情况,该怎么办?如果我们要训练一个神经网络算法来识别路人、汽车、摩托车和卡车,在输出层我们应该有4个值。例如,第一个值为1或0用于预测是否是行人,第二个值用于判断是否为汽车。
输入向量有三个维度,两个中间层,输出层4个神经元分别用来表示4类,也就是每一个数据在输出层都会出现,且中仅有一个为1,表示当前类。下面是该神经网络的可能结构示例:
神经网络算法的输出结果为四种可能情形之一:
为了更好了了解Neuron Networks的工作原理,我们先把左半部分遮住:
右半部分其实就是以, 按照Logistic Regression的方式输出:
其实神经网络就像是logistic regression,只不过我们把logistic regression中的输入向量 变成了中间层的, 即: +我们可以把看成更为高级的特征值,也就是的进化体,并且它们是由 与决定的,因为是梯度下降的,所以是变化的,并且变得越来越厉害,所以这些更高级的特征值远比仅仅将 次方厉害,也能更好的预测新数据。 +这就是神经网络相比于逻辑回归和线性回归的优势。
参考视频: 8 - 5 - Examples and Intuitions I (7 min).mkv
从本质上讲,神经网络能够通过学习得出其自身的一系列特征。在普通的逻辑回归中,我们被限制为使用数据中的原始特征,我们虽然可以使用一些二项式项来组合这些特征,但是我们仍然受到这些原始特征的限制。在神经网络中,原始特征只是输入层,在我们上面三层的神经网络例子中,第三层也就是输出层做出的预测利用的是第二层的特征,而非输入层中的原始特征,我们可以认为第二层中的特征是神经网络通过学习后自己得出的一系列用于预测输出变量的新特征。
神经网络中,单层神经元(无中间层)的计算可用来表示逻辑运算,比如逻辑与(AND)、逻辑或(OR)。
举例说明:逻辑与(AND);下图中左半部分是神经网络的设计与output层表达式,右边上部分是sigmod函数,下半部分是真值表。
我们可以用这样的一个神经网络表示AND 函数:
其中 +我们的输出函数即为:
我们知道的图像是:
所以我们有:
所以我们的:
这就是AND函数。
接下来再介绍一个OR函数:
OR与AND整体一样,区别只在于的取值不同。
参考视频: 8 - 6 - Examples and Intuitions II (10 min).mkv
二元逻辑运算符(BINARY LOGICAL OPERATORS)当输入特征为布尔值(0或1)时,我们可以用一个单一的激活层可以作为二元逻辑运算符,为了表示不同的运算符,我们只需要选择不同的权重即可。
下图的神经元(三个权重分别为-30,20,20)可以被视为作用同于逻辑与(AND):
下图的神经元(三个权重分别为-10,20,20)可以被视为作用等同于逻辑或(OR):
下图的神经元(两个权重分别为 10,-20)可以被视为作用等同于逻辑非(NOT):
我们可以利用神经元来组合成更为复杂的神经网络以实现更复杂的运算。例如我们要实现XNOR 功能(输入的两个值必须一样,均为1或均为0),即 +首先构造一个能表达部分的神经元:
然后将表示 AND 的神经元和表示的神经元以及表示 OR 的神经元进行组合:
我们就得到了一个能实现 运算符功能的神经网络。
按这种方法我们可以逐渐构造出越来越复杂的函数,也能得到更加厉害的特征值。
这就是神经网络的厉害之处。
参考视频: 8 - 7 - Multiclass Classification (4 min).mkv
当我们有不止两种分类时(也就是),比如以下这种情况,该怎么办?如果我们要训练一个神经网络算法来识别路人、汽车、摩托车和卡车,在输出层我们应该有4个值。例如,第一个值为1或0用于预测是否是行人,第二个值用于判断是否为汽车。
输入向量有三个维度,两个中间层,输出层4个神经元分别用来表示4类,也就是每一个数据在输出层都会出现,且中仅有一个为1,表示当前类。下面是该神经网络的可能结构示例:
神经网络算法的输出结果为四种可能情形之一:
第5周九、神经网络的学习(Neural Networks: Learning)9.1 代价函数9.2 反向传播算法9.3 反向传播算法的直观理解9.4 实现注意:展开参数9.5 梯度检验9.6 随机初始化9.7 综合起来9.8 自主驾驶
参考视频: 9 - 1 - Cost Function (7 min).mkv
首先引入一些便于稍后讨论的新标记方法:
假设神经网络的训练样本有个,每个包含一组输入和一组输出信号,表示神经网络层数,表示每层的neuron个数(表示输出层神经元个数),代表最后一层中处理单元的个数。
将神经网络的分类定义为两种情况:二类分类和多类分类,
二类分类:表示哪一类;
类分类:表示分到第类;
我们回顾逻辑回归问题中我们的代价函数为:
在逻辑回归中,我们只有一个输出变量,又称标量(scalar),也只有一个因变量,但是在神经网络中,我们可以有很多输出变量,我们的是一个维度为的向量,并且我们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂一些,为: -
这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出个预测,基本上我们可以利用循环,对每一行特征都预测个不同结果,然后在利用循环在个预测中选择可能性最高的一个,将其与中的实际数据进行比较。
正则化的那一项只是排除了每一层后,每一层的 矩阵的和。最里层的循环循环所有的行(由 +1 层的激活单元数决定),循环则循环所有的列,由该层(层)的激活单元数所决定。即:与真实值之间的距离为每个样本-每个类输出的加和,对参数进行regularization的bias项处理所有参数的平方和。
参考视频: 9 - 2 - Backpropagation Algorithm (12 min).mkv
之前我们在计算神经网络预测结果的时候我们采用了一种正向传播方法,我们从第一层开始正向一层一层进行计算,直到最后一层的。
现在,为了计算代价函数的偏导数,我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。 -以一个例子来说明反向传播算法。
假设我们的训练集只有一个实例,我们的神经网络是一个四层的神经网络,其中:
前向传播算法:
我们从最后一层的误差开始计算,误差是激活单元的预测()与实际值()之间的误差,()。 -我们用来表示误差,则: -我们利用这个误差值来计算前一层的误差: -其中 是 形函数的导数,。而则是权重导致的误差的和。下一步是继续计算第二层的误差: - -因为第一层是输入变量,不存在误差。我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设,即我们不做任何正则化处理时有: -
重要的是清楚地知道上面式子中上下标的含义:
代表目前所计算的是第几层。
代表目前计算层中的激活单元的下标,也将是下一层的第个输入变量的下标。
代表下一层中误差单元的下标,是受到权重矩阵中第行影响的下一层中的误差单元的下标。
如果我们考虑正则化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,我们用来表示这个误差矩阵。第 层的第 个激活单元受到第 个参数影响而导致的误差。
我们的算法表示为:
即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。
在求出了之后,我们便可以计算代价函数的偏导数了,计算方法如下: -
在Octave 中,如果我们要使用 fminuc
这样的优化算法来求解求出权重矩阵,我们需要将矩阵首先展开成为向量,在利用算法求出最优解后再重新转换回矩阵。
假设我们有三个权重矩阵,Theta1,Theta2 和 Theta3,尺寸分别为 10*11,10*11 和1*11, -下面的代码可以实现这样的转换:
xthetaVec = [Theta1(:) ; Theta2(:) ; Theta3(:)]
...optimization using functions like fminuc...
Theta1 = reshape(thetaVec(1:110, 10, 11);
Theta2 = reshape(thetaVec(111:220, 10, 11);
Theta1 = reshape(thetaVec(221:231, 1, 11);
参考视频: 9 - 3 - Backpropagation Intuition (13 min).mkv
在上一段视频中,我们介绍了反向传播算法,对很多人来说,当第一次看到这种算法时,第一印象通常是,这个算法需要那么多繁杂的步骤,简直是太复杂了,实在不知道这些步骤,到底应该如何合在一起使用。就好像一个黑箱,里面充满了复杂的步骤。如果你对反向传播算法也有这种感受的话,这其实是正常的,相比于线性回归算法和逻辑回归算法而言,从数学的角度上讲,反向传播算法似乎并不简洁,对于反向传播这种算法,其实我已经使用了很多年了,但即便如此,即使是现在,我也经常感觉自己对反向传播算法的理解并不是十分深入,对于反向传播算法究竟是如何执行的,并没有一个很直观的理解。做过编程练习的同学应该可以感受到这些练习或多或少能帮助你,将这些复杂的步骤梳理了一遍,巩固了反向传播算法具体是如何实现的,这样你才能自己掌握这种算法。
在这段视频中,我想更加深入地讨论一下反向传播算法的这些复杂的步骤,并且希望给你一个更加全面直观的感受,理解这些步骤究竟是在做什么,也希望通过这段视频,你能理解,它至少还是一个合理的算法。但可能你即使看了这段视频,你还是觉得反向传播依然很复杂,依然像一个黑箱,太多复杂的步骤,依然感到有点神奇,这也是没关系的。即使是我接触反向传播这么多年了,有时候仍然觉得这是一个难以理解的算法,但还是希望这段视频能有些许帮助,为了更好地理解反向传播算法,我们再来仔细研究一下前向传播的原理:
前向传播算法:
反向传播算法做的是:
参考视频: 9 - 4 - Implementation Note_ Unrolling Parameters (8 min).mkv
在上一段视频中,我们谈到了怎样使用反向传播算法计算代价函数的导数。在这段视频中,我想快速地向你介绍一个细节的实现过程,怎样把你的参数从矩阵展开成向量,以便我们在高级最优化步骤中的使用需要。
参考视频: 9 - 5 - Gradient Checking (12 min).mkv
当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。
为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。
对梯度的估计采用的方法是在代价函数上沿着切线的方向选择离两个非常近的点然后计算两个点的平均值用以估计梯度。即对于某个特定的 ,我们计算出在 - 处和 + 的代价值(是一个非常小的值,通常选取 0.001),然后求两个代价的平均,用以估计在 处的代价值。
Octave 中代码如下:
gradApprox = (J(theta + eps) – J(theta - eps)) / (2*eps)
当是一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对进行检验的示例: -
最后我们还需要对通过反向传播方法计算出的偏导数进行检验。
根据上面的算法,计算出的偏导数存储在矩阵 中。检验时,我们要将该矩阵展开成为向量,同时我们也将 矩阵展开为向量,我们针对每一个 都计算一个近似的梯度值,将这些值存储于一个近似梯度矩阵中,最终将得出的这个矩阵同 进行比较。
参考视频: 9 - 6 - Random Initialization (7 min).mkv
任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非0的数,结果也是一样的。
我们通常初始参数为正负ε之间的随机值,假设我们要随机初始一个尺寸为10×11的参数矩阵,代码如下:
Theta1 = rand(10, 11) * (2*eps) – eps
参考视频: 9 - 7 - Putting It Together (14 min).mkv
小结一下使用神经网络时的步骤:
网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。
第一层的单元数即我们训练集的特征数量。
最后一层的单元数是我们训练集的结果的类的数量。
如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。
我们真正要决定的是隐藏层的层数和每个中间层的单元数。
训练神经网络:
参考视频: 9 - 8 - Autonomous Driving (7 min).mkv
在这段视频中,我想向你介绍一个具有历史意义的神经网络学习的重要例子。那就是使用神经网络来实现自动驾驶,也就是说使汽车通过学习来自己驾驶。接下来我将演示的这段视频是我从 Dean Pomerleau那里拿到的,他是我的同事,任职于美国东海岸的卡耐基梅隆大学。在这部分视频中,你就会明白可视化技术到底是什么?在看这段视频之前,我会告诉你可视化技术是什么。
在下面也就是左下方,就是汽车所看到的前方的路况图像。
在图中你依稀能看出一条道路,朝左延伸了一点,又向右了一点,然后上面的这幅图,你可以看到一条水平的菜单栏显示的是驾驶操作人选择的方向。就是这里的这条白亮的区段显示的就是人类驾驶者选择的方向。比如:最左边的区段,对应的操作就是向左急转,而最右端则对应向右急转的操作。因此,稍微靠左的区段,也就是中心稍微向左一点的位置,则表示在这一点上人类驾驶者的操作是慢慢的向左拐。
这幅图的第二部分对应的就是学习算法选出的行驶方向。并且,类似的,这一条白亮的区段显示的就是神经网络在这里选择的行驶方向,是稍微的左转,并且实际上在神经网络开始学习之前,你会看到网络的输出是一条灰色的区段,就像这样的一条灰色区段覆盖着整个区域这些均称的灰色区域,显示出神经网络已经随机初始化了,并且初始化时,我们并不知道汽车如何行驶,或者说我们并不知道所选行驶方向。只有在学习算法运行了足够长的时间之后,才会有这条白色的区段出现在整条灰色区域之中。显示出一个具体的行驶方向这就表示神经网络算法,在这时候已经选出了一个明确的行驶方向,不像刚开始的时候,输出一段模糊的浅灰色区域,而是输出一条白亮的区段,表示已经选出了明确的行驶方向。
ALVINN (Autonomous Land Vehicle In a Neural Network)是一个基于神经网络的智能系统,通过观察人类的驾驶来学习驾驶,ALVINN能够控制NavLab,装在一辆改装版军用悍马,这辆悍马装载了传感器、计算机和驱动器用来进行自动驾驶的导航试验。实现ALVINN功能的第一步,是对它进行训练,也就是训练一个人驾驶汽车。
然后让ALVINN观看,ALVINN每两秒将前方的路况图生成一张数字化图片,并且记录驾驶者的驾驶方向,得到的训练集图片被压缩为30x32像素,并且作为输入提供给ALVINN的三层神经网络,通过使用反向传播学习算法,ALVINN会训练得到一个与人类驾驶员操纵方向基本相近的结果。一开始,我们的网络选择出的方向是随机的,大约经过两分钟的训练后,我们的神经网络便能够准确地模拟人类驾驶者的驾驶方向,对其他道路类型,也重复进行这个训练过程,当网络被训练完成后,操作者就可按下运行按钮,车辆便开始行驶了。
每秒钟ALVINN生成12次数字化图片,并且将图像传送给神经网络进行训练,多个神经网络同时工作,每一个网络都生成一个行驶方向,以及一个预测自信度的参数,预测自信度最高的那个神经网络得到的行驶方向。比如这里,在这条单行道上训练出的网络将被最终用于控制车辆方向,车辆前方突然出现了一个交叉十字路口,当车辆到达这个十字路口时,我们单行道网络对应的自信度骤减,当它穿过这个十字路口时,前方的双车道将进入其视线,双车道网络的自信度便开始上升,当它的自信度上升时,双车道的网络,将被选择来控制行驶方向,车辆将被安全地引导进入双车道路。
这就是基于神经网络的自动驾驶技术。当然,我们还有很多更加先进的试验来实现自动驾驶技术。在美国,欧洲等一些国家和地区,他们提供了一些比这个方法更加稳定的驾驶控制技术。但我认为,使用这样一个简单的基于反向传播的神经网络,训练出如此强大的自动驾驶汽车,的确是一次令人惊讶的成就。
第5周九、神经网络的学习(Neural Networks: Learning)9.1 代价函数9.2 反向传播算法9.3 反向传播算法的直观理解9.4 实现注意:展开参数9.5 梯度检验9.6 随机初始化9.7 综合起来9.8 自主驾驶
参考视频: 9 - 1 - Cost Function (7 min).mkv
首先引入一些便于稍后讨论的新标记方法:
假设神经网络的训练样本有个,每个包含一组输入和一组输出信号,表示神经网络层数,表示每层的neuron个数(表示输出层神经元个数),代表最后一层中处理单元的个数。
将神经网络的分类定义为两种情况:二类分类和多类分类,
二类分类:表示哪一类;
类分类:表示分到第类;
我们回顾逻辑回归问题中我们的代价函数为:
在逻辑回归中,我们只有一个输出变量,又称标量(scalar),也只有一个因变量,但是在神经网络中,我们可以有很多输出变量,我们的是一个维度为的向量,并且我们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂一些,为: +
这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出个预测,基本上我们可以利用循环,对每一行特征都预测个不同结果,然后在利用循环在个预测中选择可能性最高的一个,将其与中的实际数据进行比较。
正则化的那一项只是排除了每一层后,每一层的 矩阵的和。最里层的循环循环所有的行(由 +1 层的激活单元数决定),循环则循环所有的列,由该层(层)的激活单元数所决定。即:与真实值之间的距离为每个样本-每个类输出的加和,对参数进行regularization的bias项处理所有参数的平方和。
参考视频: 9 - 2 - Backpropagation Algorithm (12 min).mkv
之前我们在计算神经网络预测结果的时候我们采用了一种正向传播方法,我们从第一层开始正向一层一层进行计算,直到最后一层的。
现在,为了计算代价函数的偏导数,我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。 +以一个例子来说明反向传播算法。
假设我们的训练集只有一个样本,我们的神经网络是一个四层的神经网络,其中:
前向传播算法:
我们从最后一层的误差开始计算,误差是激活单元的预测()与实际值()之间的误差,()。 +我们用来表示误差,则: +我们利用这个误差值来计算前一层的误差: +其中 是 形函数的导数,。而则是权重导致的误差的和。下一步是继续计算第二层的误差: + +因为第一层是输入变量,不存在误差。我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设,即我们不做任何正则化处理时有: +
重要的是清楚地知道上面式子中上下标的含义:
代表目前所计算的是第几层。
代表目前计算层中的激活单元的下标,也将是下一层的第个输入变量的下标。
代表下一层中误差单元的下标,是受到权重矩阵中第行影响的下一层中的误差单元的下标。
如果我们考虑正则化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,我们用来表示这个误差矩阵。第 层的第 个激活单元受到第 个参数影响而导致的误差。
我们的算法表示为:
即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。
在求出了之后,我们便可以计算代价函数的偏导数了,计算方法如下: +
在Octave 中,如果我们要使用 fminuc
这样的优化算法来求解求出权重矩阵,我们需要将矩阵首先展开成为向量,在利用算法求出最优解后再重新转换回矩阵。
假设我们有三个权重矩阵,Theta1,Theta2 和 Theta3,尺寸分别为 10*11,10*11 和1*11, +下面的代码可以实现这样的转换:
xthetaVec = [Theta1(:) ; Theta2(:) ; Theta3(:)]
...optimization using functions like fminuc...
Theta1 = reshape(thetaVec(1:110, 10, 11);
Theta2 = reshape(thetaVec(111:220, 10, 11);
Theta1 = reshape(thetaVec(221:231, 1, 11);
参考视频: 9 - 3 - Backpropagation Intuition (13 min).mkv
在上一段视频中,我们介绍了反向传播算法,对很多人来说,当第一次看到这种算法时,第一印象通常是,这个算法需要那么多繁杂的步骤,简直是太复杂了,实在不知道这些步骤,到底应该如何合在一起使用。就好像一个黑箱,里面充满了复杂的步骤。如果你对反向传播算法也有这种感受的话,这其实是正常的,相比于线性回归算法和逻辑回归算法而言,从数学的角度上讲,反向传播算法似乎并不简洁,对于反向传播这种算法,其实我已经使用了很多年了,但即便如此,即使是现在,我也经常感觉自己对反向传播算法的理解并不是十分深入,对于反向传播算法究竟是如何执行的,并没有一个很直观的理解。做过编程练习的同学应该可以感受到这些练习或多或少能帮助你,将这些复杂的步骤梳理了一遍,巩固了反向传播算法具体是如何实现的,这样你才能自己掌握这种算法。
在这段视频中,我想更加深入地讨论一下反向传播算法的这些复杂的步骤,并且希望给你一个更加全面直观的感受,理解这些步骤究竟是在做什么,也希望通过这段视频,你能理解,它至少还是一个合理的算法。但可能你即使看了这段视频,你还是觉得反向传播依然很复杂,依然像一个黑箱,太多复杂的步骤,依然感到有点神奇,这也是没关系的。即使是我接触反向传播这么多年了,有时候仍然觉得这是一个难以理解的算法,但还是希望这段视频能有些许帮助,为了更好地理解反向传播算法,我们再来仔细研究一下前向传播的原理:
前向传播算法:
反向传播算法做的是:
参考视频: 9 - 4 - Implementation Note_ Unrolling Parameters (8 min).mkv
在上一段视频中,我们谈到了怎样使用反向传播算法计算代价函数的导数。在这段视频中,我想快速地向你介绍一个细节的实现过程,怎样把你的参数从矩阵展开成向量,以便我们在高级最优化步骤中的使用需要。
参考视频: 9 - 5 - Gradient Checking (12 min).mkv
当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。
为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。
对梯度的估计采用的方法是在代价函数上沿着切线的方向选择离两个非常近的点然后计算两个点的平均值用以估计梯度。即对于某个特定的 ,我们计算出在 - 处和 + 的代价值(是一个非常小的值,通常选取 0.001),然后求两个代价的平均,用以估计在 处的代价值。
Octave 中代码如下:
gradApprox = (J(theta + eps) – J(theta - eps)) / (2*eps)
当是一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对进行检验的示例: +
最后我们还需要对通过反向传播方法计算出的偏导数进行检验。
根据上面的算法,计算出的偏导数存储在矩阵 中。检验时,我们要将该矩阵展开成为向量,同时我们也将 矩阵展开为向量,我们针对每一个 都计算一个近似的梯度值,将这些值存储于一个近似梯度矩阵中,最终将得出的这个矩阵同 进行比较。
参考视频: 9 - 6 - Random Initialization (7 min).mkv
任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非0的数,结果也是一样的。
我们通常初始参数为正负ε之间的随机值,假设我们要随机初始一个尺寸为10×11的参数矩阵,代码如下:
Theta1 = rand(10, 11) * (2*eps) – eps
参考视频: 9 - 7 - Putting It Together (14 min).mkv
小结一下使用神经网络时的步骤:
网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。
第一层的单元数即我们训练集的特征数量。
最后一层的单元数是我们训练集的结果的类的数量。
如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。
我们真正要决定的是隐藏层的层数和每个中间层的单元数。
训练神经网络:
参考视频: 9 - 8 - Autonomous Driving (7 min).mkv
在这段视频中,我想向你介绍一个具有历史意义的神经网络学习的重要例子。那就是使用神经网络来实现自动驾驶,也就是说使汽车通过学习来自己驾驶。接下来我将演示的这段视频是我从 Dean Pomerleau那里拿到的,他是我的同事,任职于美国东海岸的卡耐基梅隆大学。在这部分视频中,你就会明白可视化技术到底是什么?在看这段视频之前,我会告诉你可视化技术是什么。
在下面也就是左下方,就是汽车所看到的前方的路况图像。
在图中你依稀能看出一条道路,朝左延伸了一点,又向右了一点,然后上面的这幅图,你可以看到一条水平的菜单栏显示的是驾驶操作人选择的方向。就是这里的这条白亮的区段显示的就是人类驾驶者选择的方向。比如:最左边的区段,对应的操作就是向左急转,而最右端则对应向右急转的操作。因此,稍微靠左的区段,也就是中心稍微向左一点的位置,则表示在这一点上人类驾驶者的操作是慢慢的向左拐。
这幅图的第二部分对应的就是学习算法选出的行驶方向。并且,类似的,这一条白亮的区段显示的就是神经网络在这里选择的行驶方向,是稍微的左转,并且实际上在神经网络开始学习之前,你会看到网络的输出是一条灰色的区段,就像这样的一条灰色区段覆盖着整个区域这些均称的灰色区域,显示出神经网络已经随机初始化了,并且初始化时,我们并不知道汽车如何行驶,或者说我们并不知道所选行驶方向。只有在学习算法运行了足够长的时间之后,才会有这条白色的区段出现在整条灰色区域之中。显示出一个具体的行驶方向这就表示神经网络算法,在这时候已经选出了一个明确的行驶方向,不像刚开始的时候,输出一段模糊的浅灰色区域,而是输出一条白亮的区段,表示已经选出了明确的行驶方向。
ALVINN (Autonomous Land Vehicle In a Neural Network)是一个基于神经网络的智能系统,通过观察人类的驾驶来学习驾驶,ALVINN能够控制NavLab,装在一辆改装版军用悍马,这辆悍马装载了传感器、计算机和驱动器用来进行自动驾驶的导航试验。实现ALVINN功能的第一步,是对它进行训练,也就是训练一个人驾驶汽车。
然后让ALVINN观看,ALVINN每两秒将前方的路况图生成一张数字化图片,并且记录驾驶者的驾驶方向,得到的训练集图片被压缩为30x32像素,并且作为输入提供给ALVINN的三层神经网络,通过使用反向传播学习算法,ALVINN会训练得到一个与人类驾驶员操纵方向基本相近的结果。一开始,我们的网络选择出的方向是随机的,大约经过两分钟的训练后,我们的神经网络便能够准确地模拟人类驾驶者的驾驶方向,对其他道路类型,也重复进行这个训练过程,当网络被训练完成后,操作者就可按下运行按钮,车辆便开始行驶了。
每秒钟ALVINN生成12次数字化图片,并且将图像传送给神经网络进行训练,多个神经网络同时工作,每一个网络都生成一个行驶方向,以及一个预测自信度的参数,预测自信度最高的那个神经网络得到的行驶方向。比如这里,在这条单行道上训练出的网络将被最终用于控制车辆方向,车辆前方突然出现了一个交叉十字路口,当车辆到达这个十字路口时,我们单行道网络对应的自信度骤减,当它穿过这个十字路口时,前方的双车道将进入其视线,双车道网络的自信度便开始上升,当它的自信度上升时,双车道的网络,将被选择来控制行驶方向,车辆将被安全地引导进入双车道路。
这就是基于神经网络的自动驾驶技术。当然,我们还有很多更加先进的试验来实现自动驾驶技术。在美国,欧洲等一些国家和地区,他们提供了一些比这个方法更加稳定的驾驶控制技术。但我认为,使用这样一个简单的基于反向传播的神经网络,训练出如此强大的自动驾驶汽车,的确是一次令人惊讶的成就。
第6周十、应用机器学习的建议(Advice for Applying Machine Learning)10.1 决定下一步做什么10.2 评估一个假设10.3 模型选择和交叉验证集10.4 诊断偏差和方差10.5 正则化和偏差/方差10.6 学习曲线10.7 决定下一步做什么十一、机器学习系统的设计(Machine Learning System Design)11.1 首先要做什么11.2 误差分析11.3 类偏斜的误差度量11.4 查准率和查全率之间的权衡11.5 机器学习的数据
参考视频: 10 - 1 - Deciding What to Try Next (6 min).mkv
到目前为止,我们已经介绍了许多不同的学习算法,如果你一直跟着这些视频的进度学习,你会发现自己已经不知不觉地成为一个了解许多先进机器学习技术的专家了。
然而,在懂机器学习的人当中依然存在着很大的差距,一部分人确实掌握了怎样高效有力地运用这些学习算法。而另一些人他们可能对我马上要讲的东西,就不是那么熟悉了。他们可能没有完全理解怎样运用这些算法。因此总是把时间浪费在毫无意义的尝试上。我想做的是确保你在设计机器学习的系统时,你能够明白怎样选择一条最合适、最正确的道路。因此,在这节视频和之后的几段视频中,我将向你介绍一些实用的建议和指导,帮助你明白怎样进行选择。具体来讲,我将重点关注的问题是假如你在开发一个机器学习系统,或者想试着改进一个机器学习系统的性能,你应如何决定接下来应该选择哪条道路?为了解释这一问题,我想仍然使用预测房价的学习例子,假如你已经完成了正则化线性回归,也就是最小化代价函数的值,假如,在你得到你的学习参数以后,如果你要将你的假设函数放到一组新的房屋样本上进行测试,假如说你发现在预测房价时产生了巨大的误差,现在你的问题是要想改进这个算法,接下来应该怎么办?
实际上你可以想出很多种方法来改进这个算法的性能,其中一种办法是使用更多的训练样本。具体来讲,也许你能想到通过电话调查或上门调查来获取更多的不同的房屋出售数据。遗憾的是,我看到好多人花费了好多时间想收集更多的训练样本。他们总认为,要是我有两倍甚至十倍数量的训练数据,那就一定会解决问题的是吧?但有时候获得更多的训练数据实际上并没有作用。在接下来的几段视频中,我们将解释原因。
我们也将知道怎样避免把过多的时间浪费在收集更多的训练数据上,这实际上是于事无补的。另一个方法,你也许能想到的是尝试选用更少的特征集。因此如果你有一系列特征比如等等。也许有很多特征,也许你可以花一点时间从这些特征中仔细挑选一小部分来防止过拟合。或者也许你需要用更多的特征,也许目前的特征集,对你来讲并不是很有帮助。你希望从获取更多特征的角度来收集更多的数据,同样地,你可以把这个问题扩展为一个很大的项目,比如使用电话调查来得到更多的房屋案例,或者再进行土地测量来获得更多有关,这块土地的信息等等,因此这是一个复杂的问题。同样的道理,我们非常希望在花费大量时间完成这些工作之前,我们就能知道其效果如何。我们也可以尝试增加多项式特征的方法,比如的平方,的平方,的乘积,我们可以花很多时间来考虑这一方法,我们也可以考虑其他方法减小或增大正则化参数的值。我们列出的这个单子,上面的很多方法都可以扩展开来扩展成一个六个月或更长时间的项目。遗憾的是,大多数人用来选择这些方法的标准是凭感觉的,也就是说,大多数人的选择方法是随便从这些方法中选择一种,比如他们会说“噢,我们来多找点数据吧”,然后花上六个月的时间收集了一大堆数据,然后也许另一个人说:“好吧,让我们来从这些房子的数据中多找点特征吧”。我很遗憾不止一次地看到很多人花了至少六个月时间来完成他们随便选择的一种方法,而在六个月或者更长时间后,他们很遗憾地发现自己选择的是一条不归路。幸运的是,有一系列简单的方法能让你事半功倍,排除掉单子上的至少一半的方法,留下那些确实有前途的方法,同时也有一种很简单的方法,只要你使用,就能很轻松地排除掉很多选择,从而为你节省大量不必要花费的时间。最终达到改进机器学习系统性能的目的假设我们需要用一个线性回归模型来预测房价,当我们运用训练好了的模型来预测未知数据的时候发现有较大的误差,我们下一步可以做什么?
我们不应该随机选择上面的某种方法来改进我们的算法,而是运用一些机器学习诊断法来帮助我们知道上面哪些方法对我们的算法是有效的。
在接下来的两段视频中,我首先介绍怎样评估机器学习算法的性能,然后在之后的几段视频中,我将开始讨论这些方法,它们也被称为"机器学习诊断法"。“诊断法”的意思是:这是一种测试法,你通过执行这种测试,能够深入了解某种算法到底是否有用。这通常也能够告诉你,要想改进一种算法的效果,什么样的尝试,才是有意义的。在这一系列的视频中我们将介绍具体的诊断法,但我要提前说明一点的是,这些诊断法的执行和实现,是需要花些时间的,有时候确实需要花很多时间来理解和实现,但这样做的确是把时间用在了刀刃上,因为这些方法让你在开发学习算法时,节省了几个月的时间,因此,在接下来几节课中,我将先来介绍如何评价你的学习算法。在此之后,我将介绍一些诊断法,希望能让你更清楚。在接下来的尝试中,如何选择更有意义的方法。
参考视频: 10 - 2 - Evaluating a Hypothesis (8 min).mkv
在本节视频中我想介绍一下怎样用你学过的算法来评估假设函数。在之后的课程中,我们将以此为基础来讨论如何避免过拟合和欠拟合的问题。
当我们确定学习算法的参数的时候,我们考虑的是选择参量来使训练误差最小化,有人认为得到一个非常小的训练误差一定是一件好事,但我们已经知道,仅仅是因为这个假设具有很小的训练误差,并不能说明它就一定是一个好的假设函数。而且我们也学习了过拟合假设函数的例子,所以这推广到新的训练集上是不适用的。
那么,你该如何判断一个假设函数是过拟合的呢?对于这个简单的例子,我们可以对假设函数进行画图,然后观察图形趋势,但对于特征变量不止一个的这种一般情况,还有像有很多特征变量的问题,想要通过画出假设函数来进行观察,就会变得很难甚至是不可能实现。
因此,我们需要另一种方法来评估我们的假设函数过拟合检验。
为了检验算法是否过拟合,我们将数据分成训练集和测试集,通常用70%的数据作为训练集,用剩下30%的数据作为测试集。很重要的一点是训练集和测试集均要含有各种类型的数据,通常我们要对数据进行“洗牌”,然后再分成训练集和测试集。
测试集评估在通过训练集让我们的模型学习得出其参数后,对测试集运用该模型,我们有两种方式计算误差:
误分类的比率,对于每一个测试集实例,计算:
然后对计算结果求平均。
参考视频: 10 - 3 - Model Selection and Train_Validation_Test Sets (12 min).mkv
假设我们要在10个不同次数的二项式模型之间进行选择:
显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,我们应该选择一个更能适应一般情况的模型。我们需要使用交叉验证集来帮助选择模型。
即:使用60%的数据作为训练集,使用 20%的数据作为交叉验证集,使用20%的数据作为测试集
模型选择的方法为:
使用训练集训练出10个模型
用10个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
选取代价函数值最小的模型
用步骤3中选出的模型对测试集计算得出推广误差(代价函数的值)
Train/validation/test error
Training error:
$J{train}(\theta) = \frac{1}{2m}\sum\limits{i=1}{m}(h_{\theta}(x{(i)})-y{(i)})2$
Cross Validation error:
$J{cv}(\theta) = \frac{1}{2m{cv}}\sum\limits{i=1}^{m}(h{\theta}(x{(i)}_{cv})-y{(i)}_{cv})^2$
Test error:
$J{test}(\theta)=\frac{1}{2m{test}}\sum\limits{i=1}^{m{test}}(h{\theta}(x^{(i)}{cv})-y{(i)}_{cv})2$
参考视频: 10 - 4 - Diagnosing Bias vs. Variance (8 min).mkv
当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大。换句话说,出现的情况要么是欠拟合,要么是过拟合问题。那么这两种情况,哪个和偏差有关,哪个和方差有关,或者是不是和两个都有关?搞清楚这一点非常重要,因为能判断出现的情况是这两种情况中的哪一种。其实是一个很有效的指示器,指引着可以改进算法的最有效的方法和途径。在这段视频中,我想更深入地探讨一下有关偏差和方差的问题,希望你能对它们有一个更深入的理解,并且也能弄清楚怎样评价一个学习算法,能够判断一个算法是偏差还是方差有问题,因为这个问题对于弄清如何改进学习算法的效果非常重要,高偏差和高方差的问题基本上来说是欠拟合和过拟合的问题。
我们通常会通过将训练集和交叉验证集的代价函数误差与多项式的次数绘制在同一张图表上来帮助分析:
Bias/variance
Training error:
Cross Validation error: $J{cv}(\theta) = \frac{1}{2m{cv}}\sum\limits{i=1}^{m}(h{\theta}(x{(i)}_{cv})-y{(i)}_{cv})^2$
对于训练集,当 较小时,模型拟合程度更低,误差较大;随着 的增长,拟合程度提高,误差减小。
对于交叉验证集,当 较小时,模型拟合程度低,误差较大;但是随着 的增长,误差呈现先减小后增大的趋势,转折点是我们的模型开始过拟合训练数据集的时候。
如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢?根据上面的图表,我们知道:
训练集误差和交叉验证集误差近似时:偏差/欠拟合
交叉验证集误差远大于训练集误差时:方差/过拟合
参考视频: 10 - 5 - Regularization and Bias_Variance (11 min).mkv
在我们在训练模型的过程中,一般会使用一些正则化方法来防止过拟合。但是我们可能会正则化的程度太高或太小了,即我们在选择λ的值时也需要思考与刚才选择多项式模型次数类似的问题。
我们选择一系列的想要测试的 值,通常是 0-10之间的呈现2倍关系的值(如:共12个)。 我们同样把数据分为训练集、交叉验证集和测试集。
选择的方法为:
• 当 较小时,训练集误差较小(过拟合)而交叉验证集误差较大
• 随着 的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加
参考视频: 10 - 6 - Learning Curves (12 min).mkv
学习曲线就是一种很好的工具,我经常使用学习曲线来判断某一个学习算法是否处于偏差、方差问题。学习曲线是学习算法的一个很好的合理检验(sanity check)。学习曲线是将训练集误差和交叉验证集误差作为训练集实例数量()的函数绘制的图表。
即,如果我们有100行数据,我们从1行数据开始,逐渐学习更多行的数据。思想是:当训练较少行数据的时候,训练的模型将能够非常完美地适应较少的训练数据,但是训练出来的模型却不能很好地适应交叉验证集数据或测试集数据。
如何利用学习曲线识别高偏差/欠拟合:作为例子,我们尝试用一条直线来适应下面的数据,可以看出,无论训练集有多么大误差都不会有太大改观:
也就是说在高偏差/欠拟合的情况下,增加数据到训练集不一定能有帮助。
如何利用学习曲线识别高方差/过拟合:假设我们使用一个非常高次的多项式模型,并且正则化非常小,可以看出,当交叉验证集误差远大于训练集误差时,往训练集增加更多数据可以提高模型的效果。
也就是说在高方差/过拟合的情况下,增加更多数据到训练集可能可以提高算法效果。
参考视频: 10 - 7 - Deciding What to Do Next Revisited (7 min).mkv
我们已经介绍了怎样评价一个学习算法,我们讨论了模型选择问题,偏差和方差的问题。那么这些诊断法则怎样帮助我们判断,哪些方法可能有助于改进学习算法的效果,而哪些可能是徒劳的呢?
让我们再次回到最开始的例子,在那里寻找答案,这就是我们之前的例子。回顾 1.1 中提出的六种可选的下一步,让我们来看一看我们在什么情况下应该怎样选择:
神经网络的方差和偏差: -
使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代价较小使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。
通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。
对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络, -然后选择交叉验证集代价最小的神经网络。
好的,以上就是我们介绍的偏差和方差问题,以及诊断该问题的学习曲线方法。在改进学习算法的表现时,你可以充分运用以上这些内容来判断哪些途径可能是有帮助的。而哪些方法可能是无意义的。如果你理解了以上几节视频中介绍的内容,并且懂得如何运用。那么你已经可以使用机器学习方法有效的解决实际问题了。你也能像硅谷的大部分机器学习从业者一样,他们每天的工作就是使用这些学习算法来解决众多实际问题。我希望这几节中提到的一些技巧,关于方差、偏差,以及学习曲线为代表的诊断法能够真正帮助你更有效率地应用机器学习,让它们高效地工作。
参考视频: 11 - 1 - Prioritizing What to Work On (10 min).mkv
在接下来的视频中,我将谈到机器学习系统的设计。这些视频将谈及在设计复杂的机器学习系统时,你将遇到的主要问题。同时我们会试着给出一些关于如何巧妙构建一个复杂的机器学习系统的建议。下面的课程的的数学性可能不是那么强,但是我认为我们将要讲到的这些东西是非常有用的,可能在构建大型的机器学习系统时,节省大量的时间。
本周以一个垃圾邮件分类器算法为例进行讨论。
为了解决这样一个问题,我们首先要做的决定是如何选择并表达特征向量。我们可以选择一个由100个最常出现在垃圾邮件中的词所构成的列表,根据这些词是否有在邮件中出现,来获得我们的特征向量(出现为1,不出现为0),尺寸为100×1。
为了构建这个分类器算法,我们可以做很多事,例如:
在上面这些选项中,非常难决定应该在哪一项上花费时间和精力,作出明智的选择,比随着感觉走要更好。当我们使用机器学习时,总是可以“头脑风暴”一下,想出一堆方法来试试。实际上,当你需要通过头脑风暴来想出不同方法来尝试去提高精度的时候,你可能已经超越了很多人了。大部分人并不尝试着列出可能的方法,他们做的只是某天早上醒来,因为某些原因有了一个突发奇想:"让我们来试试用Honey Pot项目收集大量的数据吧。"
我们将在随后的课程中讲误差分析,我会告诉你怎样用一个更加系统性的方法,从一堆不同的方法中,选取合适的那一个。因此,你更有可能选择一个真正的好方法,能让你花上几天几周,甚至是几个月去进行深入的研究。
参考视频: 11 - 2 - Error Analysis (13 min).mkv
在本次课程中,我们将会讲到误差分析(Error Analysis)的概念。这会帮助你更系统地做出决定。如果你准备研究机器学习的东西,或者构造机器学习应用程序,最好的实践方法不是建立一个非常复杂的系统,拥有多么复杂的变量;而是构建一个简单的算法,这样你可以很快地实现它。
每当我研究机器学习的问题时,我最多只会花一天的时间,就是字面意义上的24小时,来试图很快的把结果搞出来,即便效果不好。坦白的说,就是根本没有用复杂的系统,但是只是很快的得到的结果。即便运行得不完美,但是也把它运行一遍,最后通过交叉验证来检验数据。一旦做完,你可以画出学习曲线,通过画出学习曲线,以及检验误差,来找出你的算法是否有高偏差和高方差的问题,或者别的问题。在这样分析之后,再来决定用更多的数据训练,或者加入更多的特征变量是否有用。这么做的原因是:这在你刚接触机器学习问题时是一个很好的方法,你并不能提前知道你是否需要复杂的特征变量,或者你是否需要更多的数据,还是别的什么。提前知道你应该做什么,是非常难的,因为你缺少证据,缺少学习曲线。因此,你很难知道你应该把时间花在什么地方来提高算法的表现。但是当你实践一个非常简单即便不完美的方法时,你可以通过画出学习曲线来做出进一步的选择。你可以用这种方式来避免一种电脑编程里的过早优化问题,这种理念是:我们必须用证据来领导我们的决策,怎样分配自己的时间来优化算法,而不是仅仅凭直觉,凭直觉得出的东西一般总是错误的。除了画出学习曲线之外,一件非常有用的事是误差分析,我的意思是说:当我们在构造垃圾邮件分类器时,我会看一看我的交叉验证数据集,然后亲自看一看哪些邮件被算法错误地分类。因此,通过这些被算法错误分类的垃圾邮件与非垃圾邮件,你可以发现某些系统性的规律:什么类型的邮件总是被错误分类。经常地这样做之后,这个过程能启发你构造新的特征变量,或者告诉你:现在这个系统的短处,然后启发你如何去提高它。
构建一个学习算法的推荐方法为:
1. 从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试这个算法
2.绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他选择
3.进行误差分析:人工检查交叉验证集中我们算法中产生预测误差的实例,看看这些实例是否有某种系统化的趋势
以我们的垃圾邮件过滤器为例,误差分析要做的既是检验交叉验证集中我们的算法产生错误预测的所有邮件,看:是否能将这些邮件按照类分组。例如医药品垃圾邮件,仿冒品垃圾邮件或者密码窃取邮件等。然后看分类器对哪一组邮件的预测误差最大,并着手优化。
思考怎样能改进分类器。例如,发现是否缺少某些特征,记下这些特征出现的次数。
例如记录下错误拼写出现了多少次,异常的邮件路由情况出现了多少次等等,然后从出现次数最多的情况开始着手优化。
误差分析并不总能帮助我们判断应该采取怎样的行动。有时我们需要尝试不同的模型,然后进行比较,在模型比较时,用数值来判断哪一个模型更好更有效,通常我们是看交叉验证集的误差。
在我们的垃圾邮件分类器例子中,对于“我们是否应该将discount/discounts/discounted/discounting处理成同一个词?”如果这样做可以改善我们算法,我们会采用一些截词软件。误差分析不能帮助我们做出这类判断,我们只能尝试采用和不采用截词软件这两种不同方案,然后根据数值检验的结果来判断哪一种更好。
因此,当你在构造学习算法的时候,你总是会去尝试很多新的想法,实现出很多版本的学习算法,如果每一次你实践新想法的时候,你都要手动地检测这些例子,去看看是表现差还是表现好,那么这很难让你做出决定。到底是否使用词干提取,是否区分大小写。但是通过一个量化的数值评估,你可以看看这个数字,误差是变大还是变小了。你可以通过它更快地实践你的新想法,它基本上非常直观地告诉你:你的想法是提高了算法表现,还是让它变得更坏,这会大大提高你实践算法时的速度。所以我强烈推荐在交叉验证集上来实施误差分析,而不是在测试集上。但是,还是有一些人会在测试集上来做误差分析。即使这从数学上讲是不合适的。所以我还是推荐你在交叉验证向量上来做误差分析。
总结一下,当你在研究一个新的机器学习问题时,我总是推荐你实现一个较为简单快速、即便不是那么完美的算法。我几乎从未见过人们这样做。大家经常干的事情是:花费大量的时间在构造算法上,构造他们以为的简单的方法。因此,不要担心你的算法太简单,或者太不完美,而是尽可能快地实现你的算法。当你有了初始的实现之后,它会变成一个非常有力的工具,来帮助你决定下一步的做法。因为我们可以先看看算法造成的错误,通过误差分析,来看看他犯了什么错,然后来决定优化的方式。另一件事是:假设你有了一个快速而不完美的算法实现,又有一个数值的评估数据,这会帮助你尝试新的想法,快速地发现你尝试的这些想法是否能够提高算法的表现,从而你会更快地做出决定,在算法中放弃什么,吸收什么误差分析可以帮助我们系统化地选择该做什么。
参考视频: 11 - 3 - Error Metrics for Skewed Classes (12 min).mkv
在前面的课程中,我提到了误差分析,以及设定误差度量值的重要性。那就是,设定某个实数来评估你的学习算法,并衡量它的表现,有了算法的评估和误差度量值。有一件重要的事情要注意,就是使用一个合适的误差度量值,这有时会对于你的学习算法造成非常微妙的影响,这件重要的事情就是偏斜类(skewed classes)的问题。类偏斜情况表现为我们的训练集中有非常多的同一种类的实例,只有很少或没有其他类的实例。
例如我们希望用算法来预测癌症是否是恶性的,在我们的训练集中,只有0.5%的实例是恶性肿瘤。假设我们编写一个非学习而来的算法,在所有情况下都预测肿瘤是良性的,那么误差只有0.5%。然而我们通过训练而得到的神经网络算法却有1%的误差。这时,误差的大小是不能视为评判算法效果的依据的。
**查准率(Precision)和查全率(Recall**) 我们将算法预测的结果分成四种情况:
1. 正确肯定(True Positive,TP):预测为真,实际为真
2.正确否定(True Negative,TN):预测为假,实际为假
3.错误肯定(False Positive,FP):预测为真,实际为假
4.错误否定(False Negative,FN):预测为假,实际为真
则:查准率=TP/(TP+FP)。例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
查全率=TP/(TP+FN)。例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。
这样,对于我们刚才那个总是预测病人肿瘤为良性的算法,其查全率是0。
预测值 | |||
---|---|---|---|
Positive | Negtive | ||
实际值 | Positive | TP | FN |
Negtive | FP | TN |
参考视频: 11 - 4 - Trading Off Precision and Recall (14 min).mkv
在之前的课程中,我们谈到查准率和召回率,作为遇到偏斜类问题的评估度量值。在很多应用中,我们希望能够保证查准率和召回率的相对平衡。
在这节课中,我将告诉你应该怎么做,同时也向你展示一些查准率和召回率作为算法评估度量值的更有效的方式。继续沿用刚才预测肿瘤性质的例子。假使,我们的算法输出的结果在0-1 之间,我们使用阀值0.5 来预测真和假。
查准率(Precision)=TP/(TP+FP) -例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
查全率(Recall)=TP/(TP+FN)例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。
如果我们希望只在非常确信的情况下预测为真(肿瘤为恶性),即我们希望更高的查准率,我们可以使用比0.5更大的阀值,如0.7,0.9。这样做我们会减少错误预测病人为恶性肿瘤的情况,同时却会增加未能成功预测肿瘤为恶性的情况。
如果我们希望提高查全率,尽可能地让所有有可能是恶性肿瘤的病人都得到进一步地检查、诊断,我们可以使用比0.5更小的阀值,如0.3。
我们可以将不同阀值情况下,查全率与查准率的关系绘制成图表,曲线的形状根据数据的不同而不同:
我们希望有一个帮助我们选择这个阀值的方法。一种方法是计算F1 值(F1 Score),其计算公式为:
我们选择使得F1值最高的阀值。
参考视频: 11 - 5 - Data For Machine Learning (11 min).mkv
在之前的视频中,我们讨论了评价指标。在这个视频中,我要稍微转换一下,讨论一下机器学习系统设计中另一个重要的方面,这往往涉及到用来训练的数据有多少。在之前的一些视频中,我曾告诫大家不要盲目地开始,而是花大量的时间来收集大量的数据,因为数据有时是唯一能实际起到作用的。但事实证明,在一定条件下,我会在这个视频里讲到这些条件是什么。得到大量的数据并在某种类型的学习算法中进行训练,可以是一种有效的方法来获得一个具有良好性能的学习算法。而这种情况往往出现在这些条件对于你的问题都成立。 -并且你能够得到大量数据的情况下。这可以是一个很好的方式来获得非常高性能的学习算法。因此,在这段视频中,让我们一起讨论一下这个问题。
很多很多年前,我认识的两位研究人员Michele Banko 和Eric Brill进行了一项有趣的研究,他们尝试通过机器学习算法来区分常见的易混淆的单词,他们尝试了许多种不同的算法,并发现数据量非常大时,这些不同类型的算法效果都很好。
比如,在这样的句子中:早餐我吃了__个鸡蛋(to,two,too),在这个例子中,“早餐我吃了2个鸡蛋”,这是一个易混淆的单词的例子。于是他们把诸如这样的机器学习问题,当做一类监督学习问题,并尝试将其分类,什么样的词,在一个英文句子特定的位置,才是合适的。他们用了几种不同的学习算法,这些算法都是在他们2001年进行研究的时候,都已经被公认是比较领先的。因此他们使用了一个方差,用于逻辑回归上的一个方差,被称作"感知器"(perceptron)。他们也采取了一些过去常用,但是现在比较少用的算法,比如 Winnow算法,很类似于回归问题,但在一些方面又有所不同,过去用得比较多,但现在用得不太多。还有一种基于内存的学习算法,现在也用得比较少了,但是我稍后会讨论一点,而且他们用了一个朴素算法。这些具体算法的细节不那么重要,我们下面希望探讨,什么时候我们会希望获得更多数据,而非修改算法。他们所做的就是改变了训练数据集的大小,并尝试将这些学习算法用于不同大小的训练数据集中,这就是他们得到的结果。
这些趋势非常明显,首先大部分算法,都具有相似的性能,其次,随着训练数据集的增大,在横轴上代表以百万为单位的训练集大小,从0.1个百万到1000百万,也就是到了10亿规模的训练集的样本,这些算法的性能也都对应地增强了。
事实上,如果你选择任意一个算法,可能是选择了一个"劣等的"算法,如果你给这个劣等算法更多的数据,那么从这些例子中看起来的话,它看上去很有可能会其他算法更好,甚至会比"优等算法"更好。由于这项原始的研究非常具有影响力,因此已经有一系列许多不同的研究显示了类似的结果。这些结果表明,许多不同的学习算法有时倾向于表现出非常相似的表现,这还取决于一些细节,但是真正能提高性能的,是你能够给一个算法大量的训练数据。像这样的结果,引起了一种在机器学习中的普遍共识:"取得成功的人不是拥有最好算法的人,而是拥有最多数据的人"。
那么这种说法在什么时候是真,什么时候是假呢?因为如果我们有一个学习算法,并且如果这种说法是真的,那么得到大量的数据通常是保证我们具有一个高性能算法的最佳方式,而不是去争辩应该用什么样的算法。
假如有这样一些假设,在这些假设下有大量我们认为有用的训练集,我们假设在我们的机器学习问题中,特征值包含了足够的信息,这些信息可以帮助我们用来准确地预测,例如,如果我们采用了一些容易混淆的词,如:two、to、too,假如说它能够描述,捕捉到需要填写的空白处周围的词语,那么特征捕捉到之后,我们就希望有对于“早饭我吃了__鸡蛋”,那么这就有大量的信息来告诉我中间我需要填的词是“两个”(two),而不是单词 to 或too,因此特征捕捉,哪怕是周围词语中的一个词,就能够给我足够的信息来确定出标签 是什么。换句话说,从这三组易混淆的词中,我应该选什么词来填空。
那么让我们来看一看,大量的数据是有帮助的情况。假设特征值有足够的信息来预测值,假设我们使用一种需要大量参数的学习算法,比如有很多特征的逻辑回归或线性回归,或者用带有许多隐藏单元的神经网络,那又是另外一种带有很多参数的学习算法,这些都是非常强大的学习算法,它们有很多参数,这些参数可以拟合非常复杂的函数,因此我要调用这些,我将把这些算法想象成低偏差算法,因为我们能够拟合非常复杂的函数,而且因为我们有非常强大的学习算法,这些学习算法能够拟合非常复杂的函数。很有可能,如果我们用这些数据运行这些算法,这种算法能很好地拟合训练集,因此,训练误差就会很低了。
现在假设我们使用了非常非常大的训练集,在这种情况下,尽管我们希望有很多参数,但是如果训练集比参数的数量还大,甚至是更多,那么这些算法就不太可能会过度拟合。也就是说训练误差有希望接近测试误差。
另一种考虑这个问题的角度是为了有一个高性能的学习算法,我们希望它不要有高的偏差和方差。
因此偏差问题,我么将通过确保有一个具有很多参数的学习算法来解决,以便我们能够得到一个较低偏差的算法,并且通过用非常大的训练集来保证。
我们在此没有方差问题,我们的算法将没有方差,并且通过将这两个值放在一起,我们最终可以得到一个低误差和低方差的学习算法。这使得我们能够很好地测试测试数据集。从根本上来说,这是一个关键的假设:特征值有足够的信息量,且我们有一类很好的函数,这是为什么能保证低误差的关键所在。它有大量的训练数据集,这能保证得到更多的方差值,因此这给我们提出了一些可能的条件,如果你有大量的数据,而且你训练了一种带有很多参数的学习算法,那么这将会是一个很好的方式,来提供一个高性能的学习算法。
我觉得关键的测试:首先,一个人类专家看到了特征值 ,能很有信心的预测出值吗?因为这可以证明 可以根据特征值被准确地预测出来。其次,我们实际上能得到一组庞大的训练集,并且在这个训练集中训练一个有很多参数的学习算法吗?如果你不能做到这两者,那么更多时候,你会得到一个性能很好的学习算法。
第6周十、应用机器学习的建议(Advice for Applying Machine Learning)10.1 决定下一步做什么10.2 评估一个假设10.3 模型选择和交叉验证集10.4 诊断偏差和方差10.5 正则化和偏差/方差10.6 学习曲线10.7 决定下一步做什么十一、机器学习系统的设计(Machine Learning System Design)11.1 首先要做什么11.2 误差分析11.3 类偏斜的误差度量11.4 查准率和查全率之间的权衡11.5 机器学习的数据
参考视频: 10 - 1 - Deciding What to Try Next (6 min).mkv
x到目前为止,我们已经介绍了许多不同的学习算法,如果你一直跟着这些视频的进度学习,你会发现自己已经不知不觉地成为一个了解许多先进机器学习技术的专家了。
然而,在懂机器学习的人当中依然存在着很大的差距,一部分人确实掌握了怎样高效有力地运用这些学习算法。而另一些人他们可能对我马上要讲的东西,就不是那么熟悉了。他们可能没有完全理解怎样运用这些算法。因此总是把时间浪费在毫无意义的尝试上。我想做的是确保你在设计机器学习的系统时,你能够明白怎样选择一条最合适、最正确的道路。因此,在这节视频和之后的几段视频中,我将向你介绍一些实用的建议和指导,帮助你明白怎样进行选择。具体来讲,我将重点关注的问题是假如你在开发一个机器学习系统,或者想试着改进一个机器学习系统的性能,你应如何决定接下来应该选择哪条道路?为了解释这一问题,我想仍然使用预测房价的学习例子,假如你已经完成了正则化线性回归,也就是最小化代价函数$J$的值,假如,在你得到你的学习参数以后,如果你要将你的假设函数放到一组新的房屋样本上进行测试,假如说你发现在预测房价时产生了巨大的误差,现在你的问题是要想改进这个算法,接下来应该怎么办?
实际上你可以想出很多种方法来改进这个算法的性能,其中一种办法是使用更多的训练样本。具体来讲,也许你能想到通过电话调查或上门调查来获取更多的不同的房屋出售数据。遗憾的是,我看到好多人花费了好多时间想收集更多的训练样本。他们总认为,要是我有两倍甚至十倍数量的训练数据,那就一定会解决问题的是吧?但有时候获得更多的训练数据实际上并没有作用。在接下来的几段视频中,我们将解释原因。
我们也将知道怎样避免把过多的时间浪费在收集更多的训练数据上,这实际上是于事无补的。另一个方法,你也许能想到的是尝试选用更少的特征集。因此如果你有一系列特征比如$x_1,x_2,x_3$等等。也许有很多特征,也许你可以花一点时间从这些特征中仔细挑选一小部分来防止过拟合。或者也许你需要用更多的特征,也许目前的特征集,对你来讲并不是很有帮助。你希望从获取更多特征的角度来收集更多的数据,同样地,你可以把这个问题扩展为一个很大的项目,比如使用电话调查来得到更多的房屋案例,或者再进行土地测量来获得更多有关,这块土地的信息等等,因此这是一个复杂的问题。同样的道理,我们非常希望在花费大量时间完成这些工作之前,我们就能知道其效果如何。我们也可以尝试增加多项式特征的方法,比如$x_1$的平方,$x_2$的平方,$x_1,x_2$的乘积,我们可以花很多时间来考虑这一方法,我们也可以考虑其他方法减小或增大正则化参数$\lambda$的值。我们列出的这个单子,上面的很多方法都可以扩展开来扩展成一个六个月或更长时间的项目。遗憾的是,大多数人用来选择这些方法的标准是凭感觉的,也就是说,大多数人的选择方法是随便从这些方法中选择一种,比如他们会说“噢,我们来多找点数据吧”,然后花上六个月的时间收集了一大堆数据,然后也许另一个人说:“好吧,让我们来从这些房子的数据中多找点特征吧”。我很遗憾不止一次地看到很多人花了至少六个月时间来完成他们随便选择的一种方法,而在六个月或者更长时间后,他们很遗憾地发现自己选择的是一条不归路。幸运的是,有一系列简单的方法能让你事半功倍,排除掉单子上的至少一半的方法,留下那些确实有前途的方法,同时也有一种很简单的方法,只要你使用,就能很轻松地排除掉很多选择,从而为你节省大量不必要花费的时间。最终达到改进机器学习系统性能的目的假设我们需要用一个线性回归模型来预测房价,当我们运用训练好了的模型来预测未知数据的时候发现有较大的误差,我们下一步可以做什么?
获得更多的训练样本——通常是有效的,但代价较大,下面的方法也可能有效,可考虑先采用下面的几种方法。
尝试减少特征的数量
尝试获得更多的特征
尝试增加多项式特征
尝试减少正则化程度
尝试增加正则化程度
xxxxxxxxxx
我们不应该随机选择上面的某种方法来改进我们的算法,而是运用一些机器学习诊断法来帮助我们知道上面哪些方法对我们的算法是有效的。
在接下来的两段视频中,我首先介绍怎样评估机器学习算法的性能,然后在之后的几段视频中,我将开始讨论这些方法,它们也被称为"机器学习诊断法"。“诊断法”的意思是:这是一种测试法,你通过执行这种测试,能够深入了解某种算法到底是否有用。这通常也能够告诉你,要想改进一种算法的效果,什么样的尝试,才是有意义的。在这一系列的视频中我们将介绍具体的诊断法,但我要提前说明一点的是,这些诊断法的执行和实现,是需要花些时间的,有时候确实需要花很多时间来理解和实现,但这样做的确是把时间用在了刀刃上,因为这些方法让你在开发学习算法时,节省了几个月的时间,因此,在接下来几节课中,我将先来介绍如何评价你的学习算法。在此之后,我将介绍一些诊断法,希望能让你更清楚。在接下来的尝试中,如何选择更有意义的方法。
参考视频: 10 - 2 - Evaluating a Hypothesis (8 min).mkv
xxxxxxxxxx
在本节视频中我想介绍一下怎样用你学过的算法来评估假设函数。在之后的课程中,我们将以此为基础来讨论如何避免过拟合和欠拟合的问题。
xxxxxxxxxx
当我们确定学习算法的参数的时候,我们考虑的是选择参量来使训练误差最小化,有人认为得到一个非常小的训练误差一定是一件好事,但我们已经知道,仅仅是因为这个假设具有很小的训练误差,并不能说明它就一定是一个好的假设函数。而且我们也学习了过拟合假设函数的例子,所以这推广到新的训练集上是不适用的。
那么,你该如何判断一个假设函数是过拟合的呢?对于这个简单的例子,我们可以对假设函数$h(x)$进行画图,然后观察图形趋势,但对于特征变量不止一个的这种一般情况,还有像有很多特征变量的问题,想要通过画出假设函数来进行观察,就会变得很难甚至是不可能实现。
因此,我们需要另一种方法来评估我们的假设函数过拟合检验。
为了检验算法是否过拟合,我们将数据分成训练集和测试集,通常用70%的数据作为训练集,用剩下30%的数据作为测试集。很重要的一点是训练集和测试集均要含有各种类型的数据,通常我们要对数据进行“洗牌”,然后再分成训练集和测试集。
xxxxxxxxxx
测试集评估在通过训练集让我们的模型学习得出其参数后,对测试集运用该模型,我们有两种方式计算误差:
对于线性回归模型,我们利用测试集数据计算代价函数
对于逻辑回归模型,我们除了可以利用测试数据集来计算代价函数外:
xxxxxxxxxx
$$ J_{test}{(\theta)} = -\frac{1}{{m}_{test}}\sum_\limits{i=1}^{m_{test}}\log{h_{\theta}(x^{(i)}_{test})}+(1-{y^{(i)}_{test}})\log{h_{\theta}(x^{(i)}_{test})}$$
误分类的比率,对于每一个测试集样本,计算:
然后对计算结果求平均。
参考视频: 10 - 3 - Model Selection and Train_Validation_Test Sets (12 min).mkv
xxxxxxxxxx
假设我们要在10个不同次数的二项式模型之间进行选择:
xxxxxxxxxx
显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,我们应该选择一个更能适应一般情况的模型。我们需要使用交叉验证集来帮助选择模型。
即:使用60%的数据作为训练集,使用 20%的数据作为交叉验证集,使用20%的数据作为测试集
模型选择的方法为:
使用训练集训练出10个模型
用10个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
选取代价函数值最小的模型
用步骤3中选出的模型对测试集计算得出推广误差(代价函数的值)
Train/validation/test error
Training error:
xxxxxxxxxx
$J_{train}(\theta) = \frac{1}{2m}\sum_\limits{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})^2$
Cross Validation error:
xxxxxxxxxx
$J_{cv}(\theta) = \frac{1}{2m_{cv}}\sum_\limits{i=1}^{m}(h_{\theta}(x^{(i)}_{cv})-y^{(i)}_{cv})^2•$
Test error:
xxxxxxxxxx
$J_{test}(\theta)=\frac{1}{2m_{test}}\sum_\limits{i=1}^{m_{test}}(h_{\theta}(x^{(i)}_{cv})-y^{(i)}_{cv})^2$
参考视频: 10 - 4 - Diagnosing Bias vs. Variance (8 min).mkv
xxxxxxxxxx
当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大。换句话说,出现的情况要么是欠拟合,要么是过拟合问题。那么这两种情况,哪个和偏差有关,哪个和方差有关,或者是不是和两个都有关?搞清楚这一点非常重要,因为能判断出现的情况是这两种情况中的哪一种。其实是一个很有效的指示器,指引着可以改进算法的最有效的方法和途径。在这段视频中,我想更深入地探讨一下有关偏差和方差的问题,希望你能对它们有一个更深入的理解,并且也能弄清楚怎样评价一个学习算法,能够判断一个算法是偏差还是方差有问题,因为这个问题对于弄清如何改进学习算法的效果非常重要,高偏差和高方差的问题基本上来说是欠拟合和过拟合的问题。
xxxxxxxxxx
我们通常会通过将训练集和交叉验证集的代价函数误差与多项式的次数绘制在同一张图表上来帮助分析:
Bias/variance
Training error:
Cross Validation error:
xxxxxxxxxx
对于训练集,当 $d$ 较小时,模型拟合程度更低,误差较大;随着 $d$ 的增长,拟合程度提高,误差减小。
对于交叉验证集,当 $d$ 较小时,模型拟合程度低,误差较大;但是随着 $d$ 的增长,误差呈现先减小后增大的趋势,转折点是我们的模型开始过拟合训练数据集的时候。
如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢?根据上面的图表,我们知道:
xxxxxxxxxx
训练集误差和交叉验证集误差近似时:偏差/欠拟合
交叉验证集误差远大于训练集误差时:方差/过拟合
参考视频: 10 - 5 - Regularization and Bias_Variance (11 min).mkv
xxxxxxxxxx
在我们在训练模型的过程中,一般会使用一些正则化方法来防止过拟合。但是我们可能会正则化的程度太高或太小了,即我们在选择λ的值时也需要思考与刚才选择多项式模型次数类似的问题。
xxxxxxxxxx
我们选择一系列的想要测试的 $\lambda$ 值,通常是 0-10之间的呈现2倍关系的值(如:$0,0.01,0.02,0.04,0.08,0.15,0.32,0.64,1.28,2.56,5.12,10$共12个)。 我们同样把数据分为训练集、交叉验证集和测试集。
选择的方法为:
xxxxxxxxxx
• 当 $\lambda$ 较小时,训练集误差较小(过拟合)而交叉验证集误差较大
• 随着 $\lambda$ 的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加
参考视频: 10 - 6 - Learning Curves (12 min).mkv
xxxxxxxxxx
学习曲线就是一种很好的工具,我经常使用学习曲线来判断某一个学习算法是否处于偏差、方差问题。学习曲线是学习算法的一个很好的**合理检验**(**sanity check**)。学习曲线是将训练集误差和交叉验证集误差作为训练集样本数量($m$)的函数绘制的图表。
即,如果我们有100行数据,我们从1行数据开始,逐渐学习更多行的数据。思想是:当训练较少行数据的时候,训练的模型将能够非常完美地适应较少的训练数据,但是训练出来的模型却不能很好地适应交叉验证集数据或测试集数据。
xxxxxxxxxx
如何利用学习曲线识别高偏差/欠拟合:作为例子,我们尝试用一条直线来适应下面的数据,可以看出,无论训练集有多么大误差都不会有太大改观:
xxxxxxxxxx
也就是说在高偏差/欠拟合的情况下,增加数据到训练集不一定能有帮助。
如何利用学习曲线识别高方差/过拟合:假设我们使用一个非常高次的多项式模型,并且正则化非常小,可以看出,当交叉验证集误差远大于训练集误差时,往训练集增加更多数据可以提高模型的效果。
xxxxxxxxxx
也就是说在高方差/过拟合的情况下,增加更多数据到训练集可能可以提高算法效果。
参考视频: 10 - 7 - Deciding What to Do Next Revisited (7 min).mkv
xxxxxxxxxx
我们已经介绍了怎样评价一个学习算法,我们讨论了模型选择问题,偏差和方差的问题。那么这些诊断法则怎样帮助我们判断,哪些方法可能有助于改进学习算法的效果,而哪些可能是徒劳的呢?
让我们再次回到最开始的例子,在那里寻找答案,这就是我们之前的例子。回顾 1.1 中提出的六种可选的下一步,让我们来看一看我们在什么情况下应该怎样选择:
神经网络的方差和偏差: +
xxxxxxxxxx
使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代价较小使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。
通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。
对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络,
然后选择交叉验证集代价最小的神经网络。
xxxxxxxxxx
好的,以上就是我们介绍的偏差和方差问题,以及诊断该问题的学习曲线方法。在改进学习算法的表现时,你可以充分运用以上这些内容来判断哪些途径可能是有帮助的。而哪些方法可能是无意义的。如果你理解了以上几节视频中介绍的内容,并且懂得如何运用。那么你已经可以使用机器学习方法有效的解决实际问题了。你也能像硅谷的大部分机器学习从业者一样,他们每天的工作就是使用这些学习算法来解决众多实际问题。我希望这几节中提到的一些技巧,关于方差、偏差,以及学习曲线为代表的诊断法能够真正帮助你更有效率地应用机器学习,让它们高效地工作。
参考视频: 11 - 1 - Prioritizing What to Work On (10 min).mkv
xxxxxxxxxx
在接下来的视频中,我将谈到机器学习系统的设计。这些视频将谈及在设计复杂的机器学习系统时,你将遇到的主要问题。同时我们会试着给出一些关于如何巧妙构建一个复杂的机器学习系统的建议。下面的课程的的数学性可能不是那么强,但是我认为我们将要讲到的这些东西是非常有用的,可能在构建大型的机器学习系统时,节省大量的时间。
本周以一个垃圾邮件分类器算法为例进行讨论。
为了解决这样一个问题,我们首先要做的决定是如何选择并表达特征向量$x$。我们可以选择一个由100个最常出现在垃圾邮件中的词所构成的列表,根据这些词是否有在邮件中出现,来获得我们的特征向量(出现为1,不出现为0),尺寸为100×1。
为了构建这个分类器算法,我们可以做很多事,例如:
收集更多的数据,让我们有更多的垃圾邮件和非垃圾邮件的样本
基于邮件的路由信息开发一系列复杂的特征
基于邮件的正文信息开发一系列复杂的特征,包括考虑截词的处理
为探测刻意的拼写错误(把watch 写成w4tch)开发复杂的算法
xxxxxxxxxx
在上面这些选项中,非常难决定应该在哪一项上花费时间和精力,作出明智的选择,比随着感觉走要更好。当我们使用机器学习时,总是可以“头脑风暴”一下,想出一堆方法来试试。实际上,当你需要通过头脑风暴来想出不同方法来尝试去提高精度的时候,你可能已经超越了很多人了。大部分人并不尝试着列出可能的方法,他们做的只是某天早上醒来,因为某些原因有了一个突发奇想:"让我们来试试用**Honey Pot**项目收集大量的数据吧。"
我们将在随后的课程中讲误差分析,我会告诉你怎样用一个更加系统性的方法,从一堆不同的方法中,选取合适的那一个。因此,你更有可能选择一个真正的好方法,能让你花上几天几周,甚至是几个月去进行深入的研究。
参考视频: 11 - 2 - Error Analysis (13 min).mkv
xxxxxxxxxx
在本次课程中,我们将会讲到误差分析(**Error Analysis**)的概念。这会帮助你更系统地做出决定。如果你准备研究机器学习的东西,或者构造机器学习应用程序,最好的实践方法不是建立一个非常复杂的系统,拥有多么复杂的变量;而是构建一个简单的算法,这样你可以很快地实现它。
每当我研究机器学习的问题时,我最多只会花一天的时间,就是字面意义上的24小时,来试图很快的把结果搞出来,即便效果不好。坦白的说,就是根本没有用复杂的系统,但是只是很快的得到的结果。即便运行得不完美,但是也把它运行一遍,最后通过交叉验证来检验数据。一旦做完,你可以画出学习曲线,通过画出学习曲线,以及检验误差,来找出你的算法是否有高偏差和高方差的问题,或者别的问题。在这样分析之后,再来决定用更多的数据训练,或者加入更多的特征变量是否有用。这么做的原因是:这在你刚接触机器学习问题时是一个很好的方法,你并不能提前知道你是否需要复杂的特征变量,或者你是否需要更多的数据,还是别的什么。提前知道你应该做什么,是非常难的,因为你缺少证据,缺少学习曲线。因此,你很难知道你应该把时间花在什么地方来提高算法的表现。但是当你实践一个非常简单即便不完美的方法时,你可以通过画出学习曲线来做出进一步的选择。你可以用这种方式来避免一种电脑编程里的过早优化问题,这种理念是:我们必须用证据来领导我们的决策,怎样分配自己的时间来优化算法,而不是仅仅凭直觉,凭直觉得出的东西一般总是错误的。除了画出学习曲线之外,一件非常有用的事是误差分析,我的意思是说:当我们在构造垃圾邮件分类器时,我会看一看我的交叉验证数据集,然后亲自看一看哪些邮件被算法错误地分类。因此,通过这些被算法错误分类的垃圾邮件与非垃圾邮件,你可以发现某些系统性的规律:什么类型的邮件总是被错误分类。经常地这样做之后,这个过程能启发你构造新的特征变量,或者告诉你:现在这个系统的短处,然后启发你如何去提高它。
构建一个学习算法的推荐方法为:
1. 从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试这个算法
2.绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他选择
3.进行误差分析:人工检查交叉验证集中我们算法中产生预测误差的样本,看看这些样本是否有某种系统化的趋势
以我们的垃圾邮件过滤器为例,误差分析要做的既是检验交叉验证集中我们的算法产生错误预测的所有邮件,看:是否能将这些邮件按照类分组。例如医药品垃圾邮件,仿冒品垃圾邮件或者密码窃取邮件等。然后看分类器对哪一组邮件的预测误差最大,并着手优化。
思考怎样能改进分类器。例如,发现是否缺少某些特征,记下这些特征出现的次数。
例如记录下错误拼写出现了多少次,异常的邮件路由情况出现了多少次等等,然后从出现次数最多的情况开始着手优化。
误差分析并不总能帮助我们判断应该采取怎样的行动。有时我们需要尝试不同的模型,然后进行比较,在模型比较时,用数值来判断哪一个模型更好更有效,通常我们是看交叉验证集的误差。
在我们的垃圾邮件分类器例子中,对于“我们是否应该将**discount/discounts/discounted/discounting**处理成同一个词?”如果这样做可以改善我们算法,我们会采用一些截词软件。误差分析不能帮助我们做出这类判断,我们只能尝试采用和不采用截词软件这两种不同方案,然后根据数值检验的结果来判断哪一种更好。
因此,当你在构造学习算法的时候,你总是会去尝试很多新的想法,实现出很多版本的学习算法,如果每一次你实践新想法的时候,你都要手动地检测这些例子,去看看是表现差还是表现好,那么这很难让你做出决定。到底是否使用词干提取,是否区分大小写。但是通过一个量化的数值评估,你可以看看这个数字,误差是变大还是变小了。你可以通过它更快地实践你的新想法,它基本上非常直观地告诉你:你的想法是提高了算法表现,还是让它变得更坏,这会大大提高你实践算法时的速度。所以我强烈推荐在交叉验证集上来实施误差分析,而不是在测试集上。但是,还是有一些人会在测试集上来做误差分析。即使这从数学上讲是不合适的。所以我还是推荐你在交叉验证向量上来做误差分析。
总结一下,当你在研究一个新的机器学习问题时,我总是推荐你实现一个较为简单快速、即便不是那么完美的算法。我几乎从未见过人们这样做。大家经常干的事情是:花费大量的时间在构造算法上,构造他们以为的简单的方法。因此,不要担心你的算法太简单,或者太不完美,而是尽可能快地实现你的算法。当你有了初始的实现之后,它会变成一个非常有力的工具,来帮助你决定下一步的做法。因为我们可以先看看算法造成的错误,通过误差分析,来看看他犯了什么错,然后来决定优化的方式。另一件事是:假设你有了一个快速而不完美的算法实现,又有一个数值的评估数据,这会帮助你尝试新的想法,快速地发现你尝试的这些想法是否能够提高算法的表现,从而你会更快地做出决定,在算法中放弃什么,吸收什么误差分析可以帮助我们系统化地选择该做什么。
参考视频: 11 - 3 - Error Metrics for Skewed Classes (12 min).mkv
xxxxxxxxxx
在前面的课程中,我提到了误差分析,以及设定误差度量值的重要性。那就是,设定某个实数来评估你的学习算法,并衡量它的表现,有了算法的评估和误差度量值。有一件重要的事情要注意,就是使用一个合适的误差度量值,这有时会对于你的学习算法造成非常微妙的影响,这件重要的事情就是偏斜类(skewed classes)的问题。类偏斜情况表现为我们的训练集中有非常多的同一种类的样本,只有很少或没有其他类的样本。
例如我们希望用算法来预测癌症是否是恶性的,在我们的训练集中,只有0.5%的实例是恶性肿瘤。假设我们编写一个非学习而来的算法,在所有情况下都预测肿瘤是良性的,那么误差只有0.5%。然而我们通过训练而得到的神经网络算法却有1%的误差。这时,误差的大小是不能视为评判算法效果的依据的。
**查准率**(**Precision**)和**查全率**(**Recall**) 我们将算法预测的结果分成四种情况:
1. **正确肯定**(**True Positive,TP**):预测为真,实际为真
2.**正确否定**(**True Negative,TN**):预测为假,实际为假
3.**错误肯定**(**False Positive,FP**):预测为真,实际为假
4.**错误否定**(**False Negative,FN**):预测为假,实际为真
则:查准率=**TP/(TP+FP)**。例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
查全率=**TP/(TP+FN)**。例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。
这样,对于我们刚才那个总是预测病人肿瘤为良性的算法,其查全率是0。
预测值 | |||
---|---|---|---|
Positive | Negtive | ||
实际值 | Positive | TP | FN |
Negtive | FP | TN |
参考视频: 11 - 4 - Trading Off Precision and Recall (14 min).mkv
xxxxxxxxxx
在之前的课程中,我们谈到查准率和召回率,作为遇到偏斜类问题的评估度量值。在很多应用中,我们希望能够保证查准率和召回率的相对平衡。
在这节课中,我将告诉你应该怎么做,同时也向你展示一些查准率和召回率作为算法评估度量值的更有效的方式。继续沿用刚才预测肿瘤性质的例子。假使,我们的算法输出的结果在0-1 之间,我们使用阀值0.5 来预测真和假。
查准率**(Precision)=TP/(TP+FP)** +
例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
查全率**(Recall)=TP/(TP+FN)**例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。 + +如果我们希望只在非常确信的情况下预测为真(肿瘤为恶性),即我们希望更高的查准率,我们可以使用比0.5更大的阀值,如0.7,0.9。这样做我们会减少错误预测病人为恶性肿瘤的情况,同时却会增加未能成功预测肿瘤为恶性的情况。 + +如果我们希望提高查全率,尽可能地让所有有可能是恶性肿瘤的病人都得到进一步地检查、诊断,我们可以使用比0.5更小的阀值,如0.3。 + +我们可以将不同阀值情况下,查全率与查准率的关系绘制成图表,曲线的形状根据数据的不同而不同: +
我们希望有一个帮助我们选择这个阀值的方法。一种方法是计算**F1 值**(**F1 Score**),其计算公式为: +
我们选择使得F1值最高的阀值。
参考视频: 11 - 5 - Data For Machine Learning (11 min).mkv
在之前的视频中,我们讨论了评价指标。在这个视频中,我要稍微转换一下,讨论一下机器学习系统设计中另一个重要的方面,这往往涉及到用来训练的数据有多少。在之前的一些视频中,我曾告诫大家不要盲目地开始,而是花大量的时间来收集大量的数据,因为数据有时是唯一能实际起到作用的。但事实证明,在一定条件下,我会在这个视频里讲到这些条件是什么。得到大量的数据并在某种类型的学习算法中进行训练,可以是一种有效的方法来获得一个具有良好性能的学习算法。而这种情况往往出现在这些条件对于你的问题都成立。 +
并且你能够得到大量数据的情况下。这可以是一个很好的方式来获得非常高性能的学习算法。因此,在这段视频中,让我们一起讨论一下这个问题。
很多很多年前,我认识的两位研究人员**Michele Banko** 和**Eric Brill**进行了一项有趣的研究,他们尝试通过机器学习算法来区分常见的易混淆的单词,他们尝试了许多种不同的算法,并发现数据量非常大时,这些不同类型的算法效果都很好。 +
比如,在这样的句子中:早餐我吃了__个鸡蛋(**to**,**two**,**too**),在这个例子中,“早餐我吃了2个鸡蛋”,这是一个易混淆的单词的例子。于是他们把诸如这样的机器学习问题,当做一类监督学习问题,并尝试将其分类,什么样的词,在一个英文句子特定的位置,才是合适的。他们用了几种不同的学习算法,这些算法都是在他们2001年进行研究的时候,都已经被公认是比较领先的。因此他们使用了一个方差,用于逻辑回归上的一个方差,被称作"感知器"(**perceptron**)。他们也采取了一些过去常用,但是现在比较少用的算法,比如 **Winnow**算法,很类似于回归问题,但在一些方面又有所不同,过去用得比较多,但现在用得不太多。还有一种基于内存的学习算法,现在也用得比较少了,但是我稍后会讨论一点,而且他们用了一个朴素算法。这些具体算法的细节不那么重要,我们下面希望探讨,什么时候我们会希望获得更多数据,而非修改算法。他们所做的就是改变了训练数据集的大小,并尝试将这些学习算法用于不同大小的训练数据集中,这就是他们得到的结果。 +
这些趋势非常明显,首先大部分算法,都具有相似的性能,其次,随着训练数据集的增大,在横轴上代表以百万为单位的训练集大小,从0.1个百万到1000百万,也就是到了10亿规模的训练集的样本,这些算法的性能也都对应地增强了。 + +事实上,如果你选择任意一个算法,可能是选择了一个"劣等的"算法,如果你给这个劣等算法更多的数据,那么从这些例子中看起来的话,它看上去很有可能会其他算法更好,甚至会比"优等算法"更好。由于这项原始的研究非常具有影响力,因此已经有一系列许多不同的研究显示了类似的结果。这些结果表明,许多不同的学习算法有时倾向于表现出非常相似的表现,这还取决于一些细节,但是真正能提高性能的,是你能够给一个算法大量的训练数据。像这样的结果,引起了一种在机器学习中的普遍共识:"取得成功的人不是拥有最好算法的人,而是拥有最多数据的人"。 + +那么这种说法在什么时候是真,什么时候是假呢?因为如果我们有一个学习算法,并且如果这种说法是真的,那么得到大量的数据通常是保证我们具有一个高性能算法的最佳方式,而不是去争辩应该用什么样的算法。 + +假如有这样一些假设,在这些假设下有大量我们认为有用的训练集,我们假设在我们的机器学习问题中,特征值$x$包含了足够的信息,这些信息可以帮助我们用来准确地预测$y$,例如,如果我们采用了一些容易混淆的词,如:**two**、**to**、**too**,假如说它能够描述$x$,捕捉到需要填写的空白处周围的词语,那么特征捕捉到之后,我们就希望有对于“早饭我吃了__鸡蛋”,那么这就有大量的信息来告诉我中间我需要填的词是“两个”(**two**),而不是单词 **to** 或**too**,因此特征捕捉,哪怕是周围词语中的一个词,就能够给我足够的信息来确定出标签 $y$是什么。换句话说,从这三组易混淆的词中,我应该选什么词来填空。 + +那么让我们来看一看,大量的数据是有帮助的情况。假设特征值有足够的信息来预测$y$值,假设我们使用一种需要大量参数的学习算法,比如有很多特征的逻辑回归或线性回归,或者用带有许多隐藏单元的神经网络,那又是另外一种带有很多参数的学习算法,这些都是非常强大的学习算法,它们有很多参数,这些参数可以拟合非常复杂的函数,因此我要调用这些,我将把这些算法想象成低偏差算法,因为我们能够拟合非常复杂的函数,而且因为我们有非常强大的学习算法,这些学习算法能够拟合非常复杂的函数。很有可能,如果我们用这些数据运行这些算法,这种算法能很好地拟合训练集,因此,训练误差就会很低了。 + +现在假设我们使用了非常非常大的训练集,在这种情况下,尽管我们希望有很多参数,但是如果训练集比参数的数量还大,甚至是更多,那么这些算法就不太可能会过度拟合。也就是说训练误差有希望接近测试误差。 + +另一种考虑这个问题的角度是为了有一个高性能的学习算法,我们希望它不要有高的偏差和方差。 + +因此偏差问题,我么将通过确保有一个具有很多参数的学习算法来解决,以便我们能够得到一个较低偏差的算法,并且通过用非常大的训练集来保证。 +
我们在此没有方差问题,我们的算法将没有方差,并且通过将这两个值放在一起,我们最终可以得到一个低误差和低方差的学习算法。这使得我们能够很好地测试测试数据集。从根本上来说,这是一个关键的假设:特征值有足够的信息量,且我们有一类很好的函数,这是为什么能保证低误差的关键所在。它有大量的训练数据集,这能保证得到更多的方差值,因此这给我们提出了一些可能的条件,如果你有大量的数据,而且你训练了一种带有很多参数的学习算法,那么这将会是一个很好的方式,来提供一个高性能的学习算法。 + +我觉得关键的测试:首先,一个人类专家看到了特征值 $x$,能很有信心的预测出$y$值吗?因为这可以证明 $ y$ 可以根据特征值$x$被准确地预测出来。其次,我们实际上能得到一组庞大的训练集,并且在这个训练集中训练一个有很多参数的学习算法吗?如果你不能做到这两者,那么更多时候,你会得到一个性能很好的学习算法。 +
第7周十二、支持向量机(Support Vector Machines)12.1 优化目标12.2 大边界的直观理解12.3 数学背后的大边界分类(选修)12.4 核函数112.5 核函数212.6 使用支持向量机
参考视频: 12 - 1 - Optimization Objective (15 min).mkv
到目前为止,你已经见过一系列不同的学习算法。在监督学习中,许多学习算法的性能都非常类似,因此,重要的不是你该选择使用学习算法A还是学习算法B,而更重要的是,应用这些算法时,所创建的大量数据在应用这些算法时,表现情况通常依赖于你的水平。比如:你为学习算法所设计的特征量的选择,以及如何选择正则化参数,诸如此类的事。还有一个更加强大的算法广泛的应用于工业界和学术界,它被称为支持向量机(Support Vector Machine)。与逻辑回归和神经网络相比,支持向量机,或者简称SVM,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。因此,在接下来的视频中,我会探讨这一算法。在稍后的课程中,我也会对监督学习算法进行简要的总结。当然,仅仅是作简要描述。但对于支持向量机,鉴于该算法的强大和受欢迎度,在本课中,我会花许多时间来讲解它。它也是我们所介绍的最后一个监督学习算法。
正如我们之前开发的学习算法,我们从优化目标开始。那么,我们开始学习这个算法。为了描述支持向量机,事实上,我将会从逻辑回归开始展示我们如何一点一点修改来得到本质上的支持向量机。
那么,在逻辑回归中我们已经熟悉了这里的假设函数形式,和右边的S型激励函数。然而,为了解释一些数学知识.我将用 表示。
现在考虑下我们想要逻辑回归做什么:如果有一个 的样本,我的意思是不管是在训练集中或是在测试集中,又或者在交叉验证集中,总之是 ,现在我们希望 趋近1。因为我们想要正确地将此样本分类,这就意味着当 趋近于1时, 应当远大于0,这里的意思是远远大于0。这是因为由于 表示 ,当 远大于0时,即到了该图的右边,你不难发现此时逻辑回归的输出将趋近于1。相反地,如果我们有另一个样本,即。我们希望假设函数的输出值将趋近于0,这对应于,或者就是 会远小于0,因为对应的假设函数的输出值趋近0。
如果你进一步观察逻辑回归的代价函数,你会发现每个样本 都会为总代价函数,增加这里的一项,因此,对于总代价函数通常会有对所有的训练样本求和,并且这里还有一个项,但是,在逻辑回归中,这里的这一项就是表示一个训练样本所对应的表达式。现在,如果我将完整定义的假设函数代入这里。那么,我们就会得到每一个训练样本都影响这一项。
现在,先忽略 这一项,但是这一项是影响整个总代价函数中的这一项的。
现在,一起来考虑两种情况:
一种是等于1的情况;另一种是 等于0的情况。
在第一种情况中,假设 ,此时在目标函数中只需有第一项起作用,因为时,项将等于0。因此,当在 的样本中时,即在 中 ,我们得到 这样一项,这里同上一张幻灯片一致。
我用 表示,即: 。当然,在代价函数中, 前面有负号。我们只是这样表示,如果 代价函数中,这一项也等于1。这样做是为了简化此处的表达式。如果画出关于 的函数,你会看到左下角的这条曲线,我们同样可以看到,当 增大时,也就是相当于增大时, 对应的值会变的非常小。对整个代价函数而言,影响也非常小。这也就解释了,为什么逻辑回归在观察到正样本时,试图将设置得非常大。因为,在代价函数中的这一项会变的非常小。
现在开始建立支持向量机,我们从这里开始:
我们会从这个代价函数开始,也就是一点一点修改,让我取这里的 点,我先画出将要用的代价函数。
新的代价函数将会水平的从这里到右边(图外),然后我再画一条同逻辑回归非常相似的直线,但是,在这里是一条直线,也就是我用紫红色画的曲线,就是这条紫红色的曲线。那么,到了这里已经非常接近逻辑回归中使用的代价函数了。只是这里是由两条线段组成,即位于右边的水平部分和位于左边的直线部分,先别过多的考虑左边直线部分的斜率,这并不是很重要。但是,这里我们将使用的新的代价函数,是在的前提下的。你也许能想到,这应该能做同逻辑回归中类似的事情,但事实上,在之后的优化问题中,这会变得更坚定,并且为支持向量机,带来计算上的优势。例如,更容易计算股票交易的问题等等。
目前,我们只是讨论了的情况,另外一种情况是当时,此时如果你仔细观察代价函数只留下了第二项,因为第一项被消除了。如果当时,那么这一项也就是0了。所以上述表达式只留下了第二项。因此,这个样本的代价或是代价函数的贡献。将会由这一项表示。并且,如果你将这一项作为的函数,那么,这里就会得到横轴。现在,你完成了支持向量机中的部分内容,同样地,我们要替代这一条蓝色的线,用相似的方法。
如果我们用一个新的代价函数来代替,即这条从0点开始的水平直线,然后是一条斜线,像上图。那么,现在让我给这两个方程命名,左边的函数,我称之为,同时,右边函数我称它为。这里的下标是指在代价函数中,对应的 和 的情况,拥有了这些定义后,现在,我们就开始构建支持向量机。
这是我们在逻辑回归中使用代价函数。也许这个方程看起来不是非常熟悉。这是因为之前有个负号在方程外面,但是,这里我所做的是,将负号移到了表达式的里面,这样做使得方程看起来有些不同。对于支持向量机而言,实质上我们要将这替换为,也就是,同样地,我也将这一项替换为,也就是代价。这里的代价函数,就是之前所提到的那条线。此外,代价函数,也是上面所介绍过的那条线。因此,对于支持向量机,我们得到了这里的最小化问题,即:
然后,再加上正则化参数。现在,按照支持向量机的惯例,事实上,我们的书写会稍微有些不同,代价函数的参数表示也会稍微有些不同。
首先,我们要除去这一项,当然,这仅仅是由于人们使用支持向量机时,对比于逻辑回归而言,不同的习惯所致,但这里我所说的意思是:你知道,我将要做的是仅仅除去这一项,但是,这也会得出同样的 最优值,好的,因为 仅是个常量,因此,你知道在这个最小化问题中,无论前面是否有 这一项,最终我所得到的最优值都是一样的。这里我的意思是,先给你举一个实例,假定有一最小化问题:即要求当取得最小值时的值,这时最小值为:当时取得最小值。
现在,如果我们想要将这个目标函数乘上常数10,这里我的最小化问题就变成了:求使得最小的值,然而,使得这里最小的值仍为5。因此将一些常数乘以你的最小化项,这并不会改变最小化该方程时得到值。因此,这里我所做的是删去常量。也相同的,我将目标函数乘上一个常量,并不会改变取得最小值时的值。
第二点概念上的变化,我们只是指在使用支持向量机时,一些如下的标准惯例,而不是逻辑回归。因此,对于逻辑回归,在目标函数中,我们有两项:第一个是训练样本的代价,第二个是我们的正则化项,我们不得不去用这一项来平衡。这就相当于我们想要最小化加上正则化参数,然后乘以其他项对吧?这里的表示这里的第一项,同时我用B表示第二项,但不包括,我们不是优化这里的。我们所做的是通过设置不同正则参数达到优化目的。这样,我们就能够权衡对应的项,是使得训练样本拟合的更好。即最小化。还是保证正则参数足够小,也即是对于B项而言,但对于支持向量机,按照惯例,我们将使用一个不同的参数替换这里使用的来权衡这两项。你知道,就是第一项和第二项我们依照惯例使用一个不同的参数称为,同时改为优化目标,因此,在逻辑回归中,如果给定,一个非常大的值,意味着给予B更大的权重。而这里,就对应于将 设定为非常小的值,那么,相应的将会给比给更大的权重。因此,这只是一种不同的方式来控制这种权衡或者一种不同的方法,即用参数来决定是更关心第一项的优化,还是更关心第二项的优化。当然你也可以把这里的参数 考虑成,同 所扮演的角色相同,并且这两个方程或这两个表达式并不相同,因为,但是也并不全是这样,如果当时,这两个优化目标应当得到相同的值,相同的最优值 。因此,就用它们来代替。那么,我现在删掉这里的,并且用常数来代替。因此,这就得到了在支持向量机中我们的整个优化目标函数。然后最小化这个目标函数,得到SVM 学习到的参数。
最后有别于逻辑回归输出的概率。在这里,我们的代价函数,当最小化代价函数,获得参数时,支持向量机所做的是它来直接预测的值等于1,还是等于0。因此,这个假设函数会预测1。当大于或者等于0时,或者等于0时,所以学习参数就是支持向量机假设函数的形式。那么,这就是支持向量机数学上的定义。
在接下来的视频中,让我们再回去从直观的角度看看优化目标,实际上是在做什么,以及SVM的假设函数将会学习什么,同时也会谈谈如何做些许修改,学习更加复杂、非线性的函数。
参考视频: 12 - 2 - Large Margin Intuition (11 min).mkv
人们有时将支持向量机看作是大间距分类器。在这一部分,我将介绍其中的含义,这有助于我们直观理解SVM模型的假设是什么样的。
这是我的支持向量机模型的代价函数,在左边这里我画出了关于z的代价函数,此函数用于正样本,而在右边这里我画出了关于的代价函数,横轴表示,现在让我们考虑一下,最小化这些代价函数的必要条件是什么。如果你有一个正样本,,则只有在时,代价函数才等于0。
换句话说,如果你有一个正样本,我们会希望>=1,反之,如果,我们观察一下,函数,它只有在的区间里函数值为0。这是支持向量机的一个有趣性质。事实上,如果你有一个正样本,则其实我们仅仅要求大于等于0,就能将该样本恰当分出,这是因为如果>0大的话,我们的模型代价函数值为0,类似地,如果你有一个负样本,则仅需要<=0就会将负例正确分离,但是,支持向量机的要求更高,不仅仅要能正确分开输入的样本,即不仅仅要求>0,我们需要的是比0值大很多,比如大于等于1,我也想这个比0小很多,比如我希望它小于等于-1,这就相当于在支持向量机中嵌入了一个额外的安全因子,或者说安全的间距因子。
当然,逻辑回归做了类似的事情。但是让我们看一下,在支持向量机中,这个因子会导致什么结果。具体而言,我接下来会考虑一个特例。我们将这个常数设置成一个非常大的值。比如我们假设的值为100000或者其它非常大的数,然后来观察支持向量机会给出什么结果?
如果 非常大,则最小化代价函数的时候,我们将会很希望找到一个使第一项为0的最优解。因此,让我们尝试在代价项的第一项为0的情形下理解该优化问题。比如我们可以把设置成了非常大的常数,这将给我们一些关于支持向量机模型的直观感受。
我们已经看到输入一个训练样本标签为,你想令第一项为0,你需要做的是找到一个,使得,类似地,对于一个训练样本,标签为,为了使 函数的值为0,我们需要。因此,现在考虑我们的优化问题。选择参数,使得第一项等于0,就会导致下面的优化问题,因为我们将选择参数使第一项为0,因此这个函数的第一项为0,因此是乘以0加上二分之一乘以第二项。这里第一项是乘以0,因此可以将其删去,因为我知道它是0。
这将遵从以下的约束:,如果 是等于1 的,,如果样本是一个负样本,这样当你求解这个优化问题的时候,当你最小化这个关于变量的函数的时候,你会得到一个非常有趣的决策边界。
具体而言,如果你考察这样一个数据集,其中有正样本,也有负样本,可以看到这个数据集是线性可分的。我的意思是,存在一条直线把正负样本分开。当然有多条不同的直线,可以把正样本和负样本完全分开。
比如,这就是一个决策边界可以把正样本和负样本分开。但是多多少少这个看起来并不是非常自然是么?
或者我们可以画一条更差的决策界,这是另一条决策边界,可以将正样本和负样本分开,但仅仅是勉强分开,这些决策边界看起来都不是特别好的选择,支持向量机将会选择这个黑色的决策边界,相较于之前我用粉色或者绿色画的决策界。这条黑色的看起来好得多,黑线看起来是更稳健的决策界。在分离正样本和负样本上它显得的更好。数学上来讲,这是什么意思呢?这条黑线有更大的距离,这个距离叫做间距(margin)。
当画出这两条额外的蓝线,我们看到黑色的决策界和训练样本之间有更大的最短距离。然而粉线和蓝线离训练样本就非常近,在分离样本的时候就会比黑线表现差。因此,这个距离叫做支持向量机的间距,而这是支持向量机具有鲁棒性的原因,因为它努力用一个最大间距来分离样本。因此支持向量机有时被称为大间距分类器,而这其实是求解上一页幻灯片上优化问题的结果。
我知道你也许想知道求解上一页幻灯片中的优化问题为什么会产生这个结果?它是如何产生这个大间距分类器的呢?我知道我还没有解释这一点。
我将会从直观上略述为什么这个优化问题会产生大间距分类器。总之这个图示有助于你理解支持向量机模型的做法,即努力将正样本和负样本用最大的间距分开。
在本节课中关于大间距分类器,我想讲最后一点:我们将这个大间距分类器中的正则化因子常数设置的非常大,我记得我将其设置为了100000,因此对这样的一个数据集,也许我们将选择这样的决策界,从而最大间距地分离开正样本和负样本。那么在让代价函数最小化的过程中,我们希望找出在和两种情况下都使得代价函数中左边的这一项尽量为零的参数。如果我们找到了这样的参数,则我们的最小化问题便转变成:
事实上,支持向量机现在要比这个大间距分类器所体现得更成熟,尤其是当你使用大间距分类器的时候,你的学习算法会受异常点(outlier) 的影响。比如我们加入一个额外的正样本。
在这里,如果你加了这个样本,为了将样本用最大间距分开,也许我最终会得到一条类似这样的决策界,对么?就是这条粉色的线,仅仅基于一个异常值,仅仅基于一个样本,就将我的决策界从这条黑线变到这条粉线,这实在是不明智的。而如果正则化参数,设置的非常大,这事实上正是支持向量机将会做的。它将决策界,从黑线变到了粉线,但是如果 设置的小一点,如果你将C设置的不要太大,则你最终会得到这条黑线,当然数据如果不是线性可分的,如果你在这里有一些正样本或者你在这里有一些负样本,则支持向量机也会将它们恰当分开。因此,大间距分类器的描述,仅仅是从直观上给出了正则化参数非常大的情形,同时,要提醒你的作用类似于,是我们之前使用过的正则化参数。这只是非常大的情形,或者等价地 非常小的情形。你最终会得到类似粉线这样的决策界,但是实际上应用支持向量机的时候,当不是非常非常大的时候,它可以忽略掉一些异常点的影响,得到更好的决策界。甚至当你的数据不是线性可分的时候,支持向量机也可以给出好的结果。
回顾 ,因此:
较大时,相当于 较小,可能会导致过拟合,高方差。
较小时,相当于较大,可能会导致低拟合,高偏差。
我们稍后会介绍支持向量机的偏差和方差,希望在那时候关于如何处理参数的这种平衡会变得更加清晰。我希望,这节课给出了一些关于为什么支持向量机被看做大间距分类器的直观理解。它用最大间距将样本区分开,尽管从技术上讲,这只有当参数是非常大的时候是真的,但是它对于理解支持向量机是有益的。
本节课中我们略去了一步,那就是我们在幻灯片中给出的优化问题。为什么会是这样的?它是如何得出大间距分类器的?我在本节中没有讲解,在下一节课中,我将略述这些问题背后的数学原理,来解释这个优化问题是如何得到一个大间距分类器的。
参考视频: 12 - 3 - Mathematics Behind Large Margin Classification (Optional) (20 min).mkv
在本节课中,我将介绍一些大间隔分类背后的数学原理。本节为选学部分,你完全可以跳过它,但是听听这节课可能让你对支持向量机中的优化问题,以及如何得到大间距分类器,产生更好的直观理解。
首先,让我来给大家复习一下关于向量内积的知识。假设我有两个向量,和,我将它们写在这里。两个都是二维向量,我们看一下,的结果。也叫做向量和之间的内积。由于是二维向量,我可以将它们画在这个图上。我们说,这就是向量即在横轴上,取值为某个,而在纵轴上,高度是某个作为的第二个分量。现在,很容易计算的一个量就是向量的范数。表示的范数,即的长度,即向量的欧几里得长度。根据毕达哥拉斯定理,,这是向量的长度,它是一个实数。现在你知道了这个的长度是多少了。我刚刚画的这个向量的长度就知道了。
现在让我们回头来看向量 ,因为我们想计算内积。是另一个向量,它的两个分量和是已知的。向量可以画在这里,现在让我们来看看如何计算和之间的内积。这就是具体做法,我们将向量投影到向量上,我们做一个直角投影,或者说一个90度投影将其投影到上,接下来我度量这条红线的长度。我称这条红线的长度为,因此就是长度,或者说是向量投影到向量上的量,我将它写下来,是投影到向量上的长度,因此可以将,或者说的长度。这是计算内积的一种方法。如果你从几何上画出p的值,同时画出的范数,你也会同样地计算出内积,答案是一样的。另一个计算公式是:就是 这个一行两列的矩阵乘以。因此可以得到。根据线性代数的知识,这两个公式会给出同样的结果。顺便说一句,。因此如果你将和交换位置,将投影到上,而不是将投影到上,然后做同样地计算,只是把和的位置交换一下,你事实上可以得到同样的结果。申明一点,在这个等式中的范数是一个实数,也是一个实数,因此就是两个实数正常相乘。
最后一点,需要注意的就是值,事实上是有符号的,即它可能是正值,也可能是负值。我的意思是说,如果是一个类似这样的向量,是一个类似这样的向量,和之间的夹角大于90度,则如果将投影到上,会得到这样的一个投影,这是的长度,在这个情形下我们仍然有是等于乘以的范数。唯一一点不同的是在这里是负的。在内积计算中,如果和之间的夹角小于90度,那么那条红线的长度是正值。然而如果这个夹角大于90度,则将会是负的。就是这个小线段的长度是负的。如果它们之间的夹角大于90度,两个向量之间的内积也是负的。这就是关于向量内积的知识。我们接下来将会使用这些关于向量内积的性质试图来理解支持向量机中的目标函数。
这就是我们先前给出的支持向量机模型中的目标函数。为了讲解方便,我做一点简化,仅仅是为了让目标函数更容易被分析。
我接下来忽略掉截距,令,这样更容易画示意图。我将特征数置为2,因此我们仅有两个特征,现在我们来看一下目标函数,支持向量机的优化目标函数。当我们仅有两个特征,即时,这个式子可以写作:,我们只有两个参数。你可能注意到括号里面的这一项是向量的范数,或者说是向量的长度。我的意思是如果我们将向量写出来,那么我刚刚画红线的这一项就是向量的长度或范数。这里我们用的是之前学过的向量范数的定义,事实上这就等于向量的长度。
当然你可以将其写作,如果,那就是的长度。在这里我将忽略,这样来写的范数,它仅仅和有关。但是,数学上不管你是否包含,其实并没有差别,因此在我们接下来的推导中去掉不会有影响这意味着我们的目标函数是等于。因此支持向量机做的全部事情,就是极小化参数向量范数的平方,或者说长度的平方。
现在我将要看看这些项:更深入地理解它们的含义。给定参数向量给定一个样本,这等于什么呢?在前一页幻灯片上,我们画出了在不同情形下,的示意图,我们将会使用这些概念,和就类似于和 。
让我们看一下示意图:我们考察一个单一的训练样本,我有一个正样本在这里,用一个叉来表示这个样本,意思是在水平轴上取值为,在竖直轴上取值为。这就是我画出的训练样本。尽管我没有将其真的看做向量。它事实上就是一个始于原点,终点位置在这个训练样本点的向量。现在,我们有一个参数向量我会将它也画成向量。我将画在横轴这里,将 画在纵轴这里,那么内积 将会是什么呢?
使用我们之前的方法,我们计算的方式就是我将训练样本投影到参数向量,然后我来看一看这个线段的长度,我将它画成红色。我将它称为用来表示这是第 个训练样本在参数向量上的投影。根据我们之前幻灯片的内容,我们知道的是将会等于 乘以向量 的长度或范数。这就等于。这两种方式是等价的,都可以用来计算和之间的内积。
这告诉了我们什么呢?这里表达的意思是:这个 或者的,约束是可以被这个约束所代替的。因为 ,将其写入我们的优化目标。我们将会得到没有了约束,而变成了。
需要提醒一点,我们之前曾讲过这个优化目标函数可以被写成等于。
现在让我们考虑下面这里的训练样本。现在,继续使用之前的简化,即,我们来看一下支持向量机会选择什么样的决策界。这是一种选择,我们假设支持向量机会选择这个决策边界。这不是一个非常好的选择,因为它的间距很小。这个决策界离训练样本的距离很近。我们来看一下为什么支持向量机不会选择它。
对于这样选择的参数,可以看到参数向量事实上是和决策界是90度正交的,因此这个绿色的决策界对应着一个参数向量这个方向,顺便提一句的简化仅仅意味着决策界必须通过原点。现在让我们看一下这对于优化目标函数意味着什么。
比如这个样本,我们假设它是我的第一个样本,如果我考察这个样本到参数的投影,投影是这个短的红线段,就等于,它非常短。类似地,这个样本如果它恰好是,我的第二个训练样本,则它到的投影在这里。我将它画成粉色,这个短的粉色线段是,即第二个样本到我的参数向量的投影。因此,这个投影非常短。事实上是一个负值,是在相反的方向,这个向量和参数向量的夹角大于90度,的值小于0。
我们会发现这些将会是非常小的数,因此当我们考察优化目标函数的时候,对于正样本而言,我们需要,但是如果 在这里非常小,那就意味着我们需要的范数非常大.因为如果 很小,而我们希望,令其实现的唯一的办法就是这两个数较大。如果 小,我们就希望的范数大。类似地,对于负样本而言我们需要。我们已经在这个样本中看到会是一个非常小的数,因此唯一的办法就是的范数变大。但是我们的目标函数是希望找到一个参数,它的范数是小的。因此,这看起来不像是一个好的参数向量的选择。
相反的,来看一个不同的决策边界。比如说,支持向量机选择了这个决策界,现在状况会有很大不同。如果这是决策界,这就是相对应的参数的方向,因此,在这个决策界之下,垂直线是决策界。使用线性代数的知识,可以说明,这个绿色的决策界有一个垂直于它的向量。现在如果你考察你的数据在横轴上的投影,比如这个我之前提到的样本,我的样本,当我将它投影到横轴上,或说投影到上,就会得到这样。它的长度是,另一个样本,那个样本是。我做同样的投影,我会发现,的长度是负值。你会注意到现在 和这些投影长度是长多了。如果我们仍然要满足这些约束,>1,则因为变大了,的范数就可以变小了。因此这意味着通过选择右边的决策界,而不是左边的那个,支持向量机可以使参数的范数变小很多。因此,如果我们想令的范数变小,从而令范数的平方变小,就能让支持向量机选择右边的决策界。这就是支持向量机如何能有效地产生大间距分类的原因。
看这条绿线,这个绿色的决策界。我们希望正样本和负样本投影到的值大。要做到这一点的唯一方式就是选择这条绿线做决策界。这是大间距决策界来区分开正样本和负样本这个间距的值。这个间距的值就是等等的值。通过让间距变大,即通过这些等等的值,支持向量机最终可以找到一个较小的范数。这正是支持向量机中最小化目标函数的目的。
以上就是为什么支持向量机最终会找到大间距分类器的原因。因为它试图极大化这些的范数,它们是训练样本到决策边界的距离。最后一点,我们的推导自始至终使用了这个简化假设,就是参数。
就像我之前提到的。这个的作用是:的意思是我们让决策界通过原点。如果你令不是0的话,含义就是你希望决策界不通过原点。我将不会做全部的推导。实际上,支持向量机产生大间距分类器的结论,会被证明同样成立,证明方式是非常类似的,是我们刚刚做的证明的推广。
之前视频中说过,即便不等于0,支持向量机要做的事情都是优化这个目标函数对应着值非常大的情况,但是可以说明的是,即便不等于0,支持向量机仍然会找到正样本和负样本之间的大间距分隔。
总之,我们解释了为什么支持向量机是一个大间距分类器。在下一节我们,将开始讨论如何利用支持向量机的原理,应用它们建立一个复杂的非线性分类器。
参考视频: 12 - 4 - Kernels I (16 min).mkv
回顾我们之前讨论过可以使用高级数的多项式模型来解决无法用直线进行分隔的分类问题:
为了获得上图所示的判定边界,我们的模型可能是的形式。
我们可以用一系列的新的特征f来替换模型中的每一项。例如令: -
...得到。然而,除了对原有的特征进行组合以外,有没有更好的方法来构造?我们可以利用核函数来计算出新的特征。
给定一个训练实例,我们利用的各个特征与我们预先选定的地标(landmarks)的近似程度来选取新的特征。
例如:
其中:,为实例中所有特征与地标之间的距离的和。上例中的就是核函数,具体而言,这里是一个高斯核函数(Gaussian Kernel)。 注:这个函数与正态分布没什么实际上的关系,只是看上去像而已。
这些地标的作用是什么?如果一个训练实例与地标之间的距离近似于0,则新特征 近似于,如果训练实例与地标之间距离较远,则近似于。
假设我们的训练实例含有两个特征[ ],给定地标与不同的值,见下图:
图中水平面的坐标为 ,而垂直坐标轴代表。可以看出,只有当与重合时才具有最大值。随着的改变值改变的速率受到的控制。
在下图中,当实例处于洋红色的点位置处,因为其离更近,但是离和较远,因此接近1,而,接近0。因此,因此预测。同理可以求出,对于离较近的绿色点,也预测,但是对于蓝绿色的点,因为其离三个地标都较远,预测。
这样,图中红色的封闭曲线所表示的范围,便是我们依据一个单一的训练实例和我们选取的地标所得出的判定边界,在预测时,我们采用的特征不是训练实例本身的特征,而是通过核函数计算出的新特征。
参考视频: 12 - 5 - Kernels II (16 min).mkv
在上一节视频里,我们讨论了核函数这个想法,以及怎样利用它去实现支持向量机的一些新特性。在这一节视频中,我将补充一些缺失的细节,并简单的介绍一下怎么在实际中使用应用这些想法。
如何选择地标?
我们通常是根据训练集的数量选择地标的数量,即如果训练集中有个实例,则我们选取个地标,并且令:。这样做的好处在于:现在我们得到的新特征是建立在原有特征与训练集中所有其他特征之间距离的基础之上的,即:
下面我们将核函数运用到支持向量机中,修改我们的支持向量机假设为:
• 给定,计算新特征,当 时,预测 ,否则反之。
相应地修改代价函数为:,
-在具体实施过程中,我们还需要对最后的正则化项进行些微调整,在计算时,我们用代替,其中是根据我们选择的核函数而不同的一个矩阵。这样做的原因是为了简化计算。
理论上讲,我们也可以在逻辑回归中使用核函数,但是上面使用 来简化计算的方法不适用与逻辑回归,因此计算将非常耗费时间。
在此,我们不介绍最小化支持向量机的代价函数的方法,你可以使用现有的软件包(如liblinear,libsvm等)。在使用这些软件包最小化我们的代价函数之前,我们通常需要编写核函数,并且如果我们使用高斯核函数,那么在使用之前进行特征缩放是非常必要的。
另外,支持向量机也可以不使用核函数,不使用核函数又称为线性核函数(linear kernel),当我们不采用非常复杂的函数,或者我们的训练集特征非常多而实例非常少的时候,可以采用这种不带核函数的支持向量机。
下面是支持向量机的两个参数和的影响:
较大时,相当于较小,可能会导致过拟合,高方差;
较小时,相当于较大,可能会导致低拟合,高偏差;
较大时,可能会导致低方差,高偏差;
较小时,可能会导致低偏差,高方差。
如果你看了本周的编程作业,你就能亲自实现这些想法,并亲眼看到这些效果。这就是利用核函数的支持向量机算法,希望这些关于偏差和方差的讨论,能给你一些对于算法结果预期的直观印象。
参考视频: 12 - 6 - Using An SVM (21 min).mkv
目前为止,我们已经讨论了SVM比较抽象的层面,在这个视频中我将要讨论到为了运行或者运用SVM。你实际上所需要的一些东西:支持向量机算法,提出了一个特别优化的问题。但是就如在之前的视频中我简单提到的,我真的不建议你自己写软件来求解参数,因此由于今天我们中的很少人,或者其实没有人考虑过自己写代码来转换矩阵,或求一个数的平方根等我们只是知道如何去调用库函数来实现这些功能。同样的,用以解决SVM最优化问题的软件很复杂,且已经有研究者做了很多年数值优化了。因此你提出好的软件库和好的软件包来做这样一些事儿。然后强烈建议使用高优化软件库中的一个,而不是尝试自己落实一些数据。有许多好的软件库,我正好用得最多的两个是liblinear和libsvm,但是真的有很多软件库可以用来做这件事儿。你可以连接许多你可能会用来编写学习算法的主要编程语言。
在高斯核函数之外我们还有其他一些选择,如:
多项式核函数(Polynomial Kernel)
字符串核函数(String kernel)
卡方核函数( chi-square kernel)
直方图交集核函数(histogram intersection kernel)
等等...
这些核函数的目标也都是根据训练集和地标之间的距离来构建新特征,这些核函数需要满足Mercer's定理,才能被支持向量机的优化软件正确处理。
多类分类问题
假设我们利用之前介绍的一对多方法来解决一个多类分类问题。如果一共有个类,则我们需要个模型,以及个参数向量。我们同样也可以训练k个支持向量机来解决多类分类问题。但是大多数支持向量机软件包都有内置的多类分类功能,我们只要直接使用即可。
尽管你不去写你自己的SVM的优化软件,但是你也需要做几件事:
1、是提出参数的选择。我们在之前的视频中讨论过误差/方差在这方面的性质。
2、你也需要选择内核参数或你想要使用的相似函数,其中一个选择是:我们选择不需要任何内核参数,没有内核参数的理念,也叫线性核函数。因此,如果有人说他使用了线性核的SVM(支持向量机),这就意味这他使用了不带有核函数的SVM(支持向量机)。
从逻辑回归模型,我们得到了支持向量机模型,在两者之间,我们应该如何选择呢?
下面是一些普遍使用的准则:
为特征数,为训练样本数。
(1)如果相较于而言,要大许多,即训练集数据量不够支持我们训练一个复杂的非线性模型,我们选用逻辑回归模型或者不带核函数的支持向量机。
(2)如果较小,而且大小中等,例如在 1-1000 之间,而在10-10000之间,使用高斯核函数的支持向量机。
(3)如果较小,而较大,例如在1-1000之间,而大于50000,则使用支持向量机会非常慢,解决方案是创造、增加更多的特征,然后使用逻辑回归或不带核函数的支持向量机。
值得一提的是,神经网络在以上三种情况下都可能会有较好的表现,但是训练神经网络可能非常慢,选择支持向量机的原因主要在于它的代价函数是凸函数,不存在局部最小值。
今天的SVM包会工作得很好,但是它们仍然会有一些慢。当你有非常非常大的训练集,且用高斯核函数是在这种情况下,我经常会做的是尝试手动地创建,拥有更多的特征变量,然后用逻辑回归或者不带核函数的支持向量机。如果你看到这个幻灯片,看到了逻辑回归,或者不带核函数的支持向量机。在这个两个地方,我把它们放在一起是有原因的。原因是:逻辑回归和不带核函数的支持向量机它们都是非常相似的算法,不管是逻辑回归还是不带核函数的SVM,通常都会做相似的事情,并给出相似的结果。但是根据你实现的情况,其中一个可能会比另一个更加有效。但是在其中一个算法应用的地方,逻辑回归或不带核函数的SVM另一个也很有可能很有效。但是随着SVM的复杂度增加,当你使用不同的内核函数来学习复杂的非线性函数时,这个体系,你知道的,当你有多达1万(10,000)的样本时,也可能是5万(50,000),你的特征变量的数量这是相当大的。那是一个非常常见的体系,也许在这个体系里,不带核函数的支持向量机就会表现得相当突出。你可以做比这困难得多需要逻辑回归的事情。
最后,神经网络使用于什么时候呢? 对于所有的这些问题,对于所有的这些不同体系一个设计得很好的神经网络也很有可能会非常有效。有一个缺点是,或者说是有时可能不会使用神经网络的原因是:对于许多这样的问题,神经网络训练起来可能会特别慢,但是如果你有一个非常好的SVM实现包,它可能会运行得比较快比神经网络快很多,尽管我们在此之前没有展示,但是事实证明,SVM具有的优化问题,是一种凸优化问题。因此,好的SVM优化软件包总是会找到全局最小值,或者接近它的值。对于SVM你不需要担心局部最优。在实际应用中,局部最优不是神经网络所需要解决的一个重大问题,所以这是你在使用SVM的时候不需要太去担心的一个问题。根据你的问题,神经网络可能会比SVM慢,尤其是在这样一个体系中,至于这里给出的参考,看上去有些模糊,如果你在考虑一些问题,这些参考会有一些模糊,但是我仍然不能完全确定,我是该用这个算法还是改用那个算法,这个没有太大关系,当我遇到机器学习问题的时候,有时它确实不清楚这是否是最好的算法,但是就如在之前的视频中看到的算法确实很重要。但是通常更加重要的是:你有多少数据,你有多熟练是否擅长做误差分析和排除学习算法,指出如何设定新的特征变量和找出其他能决定你学习算法的变量等方面,通常这些方面会比你使用逻辑回归还是SVM这方面更加重要。但是,已经说过了,SVM仍然被广泛认为是一种最强大的学习算法,这是一个体系,包含了什么时候一个有效的方法去学习复杂的非线性函数。因此,实际上与逻辑回归、神经网络、SVM一起使用这些方法来提高学习算法,我认为你会很好地建立很有技术的状态。(编者注:当时GPU计算比较慢,神经网络还不流行。)
机器学习系统对于一个宽泛的应用领域来说,这是另一个在你军械库里非常强大的工具,你可以把它应用到很多地方,如硅谷、在工业、学术等领域建立许多高性能的机器学习系统。
第7周十二、支持向量机(Support Vector Machines)12.1 优化目标12.2 大边界的直观理解12.3 大边界分类背后的数学(选修)12.4 核函数112.5 核函数212.6 使用支持向量机
参考视频: 12 - 1 - Optimization Objective (15 min).mkv
到目前为止,你已经见过一系列不同的学习算法。在监督学习中,许多学习算法的性能都非常类似,因此,重要的不是你该选择使用学习算法A还是学习算法B,而更重要的是,应用这些算法时,所创建的大量数据在应用这些算法时,表现情况通常依赖于你的水平。比如:你为学习算法所设计的特征量的选择,以及如何选择正则化参数,诸如此类的事。还有一个更加强大的算法广泛的应用于工业界和学术界,它被称为支持向量机(Support Vector Machine)。与逻辑回归和神经网络相比,支持向量机,或者简称SVM,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。因此,在接下来的视频中,我会探讨这一算法。在稍后的课程中,我也会对监督学习算法进行简要的总结。当然,仅仅是作简要描述。但对于支持向量机,鉴于该算法的强大和受欢迎度,在本课中,我会花许多时间来讲解它。它也是我们所介绍的最后一个监督学习算法。
正如我们之前开发的学习算法,我们从优化目标开始。那么,我们开始学习这个算法。为了描述支持向量机,事实上,我将会从逻辑回归开始展示我们如何一点一点修改来得到本质上的支持向量机。
那么,在逻辑回归中我们已经熟悉了这里的假设函数形式,和右边的S型激励函数。然而,为了解释一些数学知识.我将用 表示。
现在考虑下我们想要逻辑回归做什么:如果有一个 的样本,我的意思是不管是在训练集中或是在测试集中,又或者在交叉验证集中,总之是 ,现在我们希望 趋近1。因为我们想要正确地将此样本分类,这就意味着当 趋近于1时, 应当远大于0,这里的意思是远远大于0。这是因为由于 表示 ,当 远大于0时,即到了该图的右边,你不难发现此时逻辑回归的输出将趋近于1。相反地,如果我们有另一个样本,即。我们希望假设函数的输出值将趋近于0,这对应于,或者就是 会远小于0,因为对应的假设函数的输出值趋近0。
如果你进一步观察逻辑回归的代价函数,你会发现每个样本 都会为总代价函数,增加这里的一项,因此,对于总代价函数通常会有对所有的训练样本求和,并且这里还有一个项,但是,在逻辑回归中,这里的这一项就是表示一个训练样本所对应的表达式。现在,如果我将完整定义的假设函数代入这里。那么,我们就会得到每一个训练样本都影响这一项。
现在,先忽略 这一项,但是这一项是影响整个总代价函数中的这一项的。
现在,一起来考虑两种情况:
一种是等于1的情况;另一种是 等于0的情况。
在第一种情况中,假设 ,此时在目标函数中只需有第一项起作用,因为时,项将等于0。因此,当在 的样本中时,即在 中 ,我们得到 这样一项,这里同上一张幻灯片一致。
我用 表示,即: 。当然,在代价函数中, 前面有负号。我们只是这样表示,如果 代价函数中,这一项也等于1。这样做是为了简化此处的表达式。如果画出关于 的函数,你会看到左下角的这条曲线,我们同样可以看到,当 增大时,也就是相当于增大时, 对应的值会变的非常小。对整个代价函数而言,影响也非常小。这也就解释了,为什么逻辑回归在观察到正样本时,试图将设置得非常大。因为,在代价函数中的这一项会变的非常小。
现在开始建立支持向量机,我们从这里开始:
我们会从这个代价函数开始,也就是一点一点修改,让我取这里的 点,我先画出将要用的代价函数。
新的代价函数将会水平的从这里到右边(图外),然后我再画一条同逻辑回归非常相似的直线,但是,在这里是一条直线,也就是我用紫红色画的曲线,就是这条紫红色的曲线。那么,到了这里已经非常接近逻辑回归中使用的代价函数了。只是这里是由两条线段组成,即位于右边的水平部分和位于左边的直线部分,先别过多的考虑左边直线部分的斜率,这并不是很重要。但是,这里我们将使用的新的代价函数,是在的前提下的。你也许能想到,这应该能做同逻辑回归中类似的事情,但事实上,在之后的优化问题中,这会变得更坚定,并且为支持向量机,带来计算上的优势。例如,更容易计算股票交易的问题等等。
目前,我们只是讨论了的情况,另外一种情况是当时,此时如果你仔细观察代价函数只留下了第二项,因为第一项被消除了。如果当时,那么这一项也就是0了。所以上述表达式只留下了第二项。因此,这个样本的代价或是代价函数的贡献。将会由这一项表示。并且,如果你将这一项作为的函数,那么,这里就会得到横轴。现在,你完成了支持向量机中的部分内容,同样地,我们要替代这一条蓝色的线,用相似的方法。
如果我们用一个新的代价函数来代替,即这条从0点开始的水平直线,然后是一条斜线,像上图。那么,现在让我给这两个方程命名,左边的函数,我称之为,同时,右边函数我称它为。这里的下标是指在代价函数中,对应的 和 的情况,拥有了这些定义后,现在,我们就开始构建支持向量机。
这是我们在逻辑回归中使用代价函数。也许这个方程看起来不是非常熟悉。这是因为之前有个负号在方程外面,但是,这里我所做的是,将负号移到了表达式的里面,这样做使得方程看起来有些不同。对于支持向量机而言,实质上我们要将这替换为,也就是,同样地,我也将这一项替换为,也就是代价。这里的代价函数,就是之前所提到的那条线。此外,代价函数,也是上面所介绍过的那条线。因此,对于支持向量机,我们得到了这里的最小化问题,即:
然后,再加上正则化参数。现在,按照支持向量机的惯例,事实上,我们的书写会稍微有些不同,代价函数的参数表示也会稍微有些不同。
首先,我们要除去这一项,当然,这仅仅是由于人们使用支持向量机时,对比于逻辑回归而言,不同的习惯所致,但这里我所说的意思是:你知道,我将要做的是仅仅除去这一项,但是,这也会得出同样的 最优值,好的,因为 仅是个常量,因此,你知道在这个最小化问题中,无论前面是否有 这一项,最终我所得到的最优值都是一样的。这里我的意思是,先给你举一个样本,假定有一最小化问题:即要求当取得最小值时的值,这时最小值为:当时取得最小值。
现在,如果我们想要将这个目标函数乘上常数10,这里我的最小化问题就变成了:求使得最小的值,然而,使得这里最小的值仍为5。因此将一些常数乘以你的最小化项,这并不会改变最小化该方程时得到值。因此,这里我所做的是删去常量。也相同的,我将目标函数乘上一个常量,并不会改变取得最小值时的值。
第二点概念上的变化,我们只是指在使用支持向量机时,一些如下的标准惯例,而不是逻辑回归。因此,对于逻辑回归,在目标函数中,我们有两项:第一个是训练样本的代价,第二个是我们的正则化项,我们不得不去用这一项来平衡。这就相当于我们想要最小化加上正则化参数,然后乘以其他项对吧?这里的表示这里的第一项,同时我用B表示第二项,但不包括,我们不是优化这里的。我们所做的是通过设置不同正则参数达到优化目的。这样,我们就能够权衡对应的项,是使得训练样本拟合的更好。即最小化。还是保证正则参数足够小,也即是对于B项而言,但对于支持向量机,按照惯例,我们将使用一个不同的参数替换这里使用的来权衡这两项。你知道,就是第一项和第二项我们依照惯例使用一个不同的参数称为,同时改为优化目标,。 +因此,在逻辑回归中,如果给定,一个非常大的值,意味着给予更大的权重。而这里,就对应于将 设定为非常小的值,那么,相应的将会给比给更大的权重。因此,这只是一种不同的方式来控制这种权衡或者一种不同的方法,即用参数来决定是更关心第一项的优化,还是更关心第二项的优化。当然你也可以把这里的参数 考虑成,同 所扮演的角色相同,并且这两个方程或这两个表达式并不相同,因为,但是也并不全是这样,如果当时,这两个优化目标应当得到相同的值,相同的最优值 。因此,就用它们来代替。那么,我现在删掉这里的,并且用常数来代替。因此,这就得到了在支持向量机中我们的整个优化目标函数。然后最小化这个目标函数,得到SVM 学习到的参数。
最后有别于逻辑回归输出的概率。在这里,我们的代价函数,当最小化代价函数,获得参数时,支持向量机所做的是它来直接预测的值等于1,还是等于0。因此,这个假设函数会预测1。当大于或者等于0时,或者等于0时,所以学习参数就是支持向量机假设函数的形式。那么,这就是支持向量机数学上的定义。
在接下来的视频中,让我们再回去从直观的角度看看优化目标,实际上是在做什么,以及SVM的假设函数将会学习什么,同时也会谈谈如何做些许修改,学习更加复杂、非线性的函数。
参考视频: 12 - 2 - Large Margin Intuition (11 min).mkv
人们有时将支持向量机看作是大间距分类器。在这一部分,我将介绍其中的含义,这有助于我们直观理解SVM模型的假设是什么样的。
这是我的支持向量机模型的代价函数,在左边这里我画出了关于的代价函数,此函数用于正样本,而在右边这里我画出了关于的代价函数,横轴表示,现在让我们考虑一下,最小化这些代价函数的必要条件是什么。如果你有一个正样本,,则只有在时,代价函数才等于0。
换句话说,如果你有一个正样本,我们会希望,反之,如果,我们观察一下,函数,它只有在的区间里函数值为0。这是支持向量机的一个有趣性质。事实上,如果你有一个正样本,则其实我们仅仅要求大于等于0,就能将该样本恰当分出,这是因为如果>0大的话,我们的模型代价函数值为0,类似地,如果你有一个负样本,则仅需要<=0就会将负例正确分离,但是,支持向量机的要求更高,不仅仅要能正确分开输入的样本,即不仅仅要求>0,我们需要的是比0值大很多,比如大于等于1,我也想这个比0小很多,比如我希望它小于等于-1,这就相当于在支持向量机中嵌入了一个额外的安全因子,或者说安全的间距因子。
当然,逻辑回归做了类似的事情。但是让我们看一下,在支持向量机中,这个因子会导致什么结果。具体而言,我接下来会考虑一个特例。我们将这个常数设置成一个非常大的值。比如我们假设的值为100000或者其它非常大的数,然后来观察支持向量机会给出什么结果?
如果 非常大,则最小化代价函数的时候,我们将会很希望找到一个使第一项为0的最优解。因此,让我们尝试在代价项的第一项为0的情形下理解该优化问题。比如我们可以把设置成了非常大的常数,这将给我们一些关于支持向量机模型的直观感受。
xxxxxxxxxx
$$\min_\limits{\theta}C\sum_\limits{i=1}^{m}\left[y^{(i)}{\cos}t_{1}\left(\theta^{T}x^{(i)}\right)+\left(1-y^{(i)}\right){\cos}t\left(\theta^{T}x^{(i)}\right)\right]+\frac{1}{2}\sum_\limits{i=1}^{n}\theta^{2}_{j}$$
我们已经看到输入一个训练样本标签为,你想令第一项为0,你需要做的是找到一个,使得,类似地,对于一个训练样本,标签为,为了使 函数的值为0,我们需要。因此,现在考虑我们的优化问题。选择参数,使得第一项等于0,就会导致下面的优化问题,因为我们将选择参数使第一项为0,因此这个函数的第一项为0,因此是乘以0加上二分之一乘以第二项。这里第一项是乘以0,因此可以将其删去,因为我知道它是0。
这将遵从以下的约束:,如果 是等于1 的,,如果样本是一个负样本,这样当你求解这个优化问题的时候,当你最小化这个关于变量的函数的时候,你会得到一个非常有趣的决策边界。
具体而言,如果你考察这样一个数据集,其中有正样本,也有负样本,可以看到这个数据集是线性可分的。我的意思是,存在一条直线把正负样本分开。当然有多条不同的直线,可以把正样本和负样本完全分开。
比如,这就是一个决策边界可以把正样本和负样本分开。但是多多少少这个看起来并不是非常自然是么?
或者我们可以画一条更差的决策界,这是另一条决策边界,可以将正样本和负样本分开,但仅仅是勉强分开,这些决策边界看起来都不是特别好的选择,支持向量机将会选择这个黑色的决策边界,相较于之前我用粉色或者绿色画的决策界。这条黑色的看起来好得多,黑线看起来是更稳健的决策界。在分离正样本和负样本上它显得的更好。数学上来讲,这是什么意思呢?这条黑线有更大的距离,这个距离叫做间距(margin)。
当画出这两条额外的蓝线,我们看到黑色的决策界和训练样本之间有更大的最短距离。然而粉线和蓝线离训练样本就非常近,在分离样本的时候就会比黑线表现差。因此,这个距离叫做支持向量机的间距,而这是支持向量机具有鲁棒性的原因,因为它努力用一个最大间距来分离样本。因此支持向量机有时被称为大间距分类器,而这其实是求解上一页幻灯片上优化问题的结果。
我知道你也许想知道求解上一页幻灯片中的优化问题为什么会产生这个结果?它是如何产生这个大间距分类器的呢?我知道我还没有解释这一点。
我将会从直观上略述为什么这个优化问题会产生大间距分类器。总之这个图示有助于你理解支持向量机模型的做法,即努力将正样本和负样本用最大的间距分开。
在本节课中关于大间距分类器,我想讲最后一点:我们将这个大间距分类器中的正则化因子常数设置的非常大,我记得我将其设置为了100000,因此对这样的一个数据集,也许我们将选择这样的决策界,从而最大间距地分离开正样本和负样本。那么在让代价函数最小化的过程中,我们希望找出在和两种情况下都使得代价函数中左边的这一项尽量为零的参数。如果我们找到了这样的参数,则我们的最小化问题便转变成:
事实上,支持向量机现在要比这个大间距分类器所体现得更成熟,尤其是当你使用大间距分类器的时候,你的学习算法会受异常点(outlier) 的影响。比如我们加入一个额外的正样本。
在这里,如果你加了这个样本,为了将样本用最大间距分开,也许我最终会得到一条类似这样的决策界,对么?就是这条粉色的线,仅仅基于一个异常值,仅仅基于一个样本,就将我的决策界从这条黑线变到这条粉线,这实在是不明智的。而如果正则化参数,设置的非常大,这事实上正是支持向量机将会做的。它将决策界,从黑线变到了粉线,但是如果 设置的小一点,如果你将C设置的不要太大,则你最终会得到这条黑线,当然数据如果不是线性可分的,如果你在这里有一些正样本或者你在这里有一些负样本,则支持向量机也会将它们恰当分开。因此,大间距分类器的描述,仅仅是从直观上给出了正则化参数非常大的情形,同时,要提醒你的作用类似于,是我们之前使用过的正则化参数。这只是非常大的情形,或者等价地 非常小的情形。你最终会得到类似粉线这样的决策界,但是实际上应用支持向量机的时候,当不是非常非常大的时候,它可以忽略掉一些异常点的影响,得到更好的决策界。甚至当你的数据不是线性可分的时候,支持向量机也可以给出好的结果。
回顾 ,因此:
较大时,相当于 较小,可能会导致过拟合,高方差。
较小时,相当于较大,可能会导致低拟合,高偏差。
我们稍后会介绍支持向量机的偏差和方差,希望在那时候关于如何处理参数的这种平衡会变得更加清晰。我希望,这节课给出了一些关于为什么支持向量机被看做大间距分类器的直观理解。它用最大间距将样本区分开,尽管从技术上讲,这只有当参数是非常大的时候是真的,但是它对于理解支持向量机是有益的。
本节课中我们略去了一步,那就是我们在幻灯片中给出的优化问题。为什么会是这样的?它是如何得出大间距分类器的?我在本节中没有讲解,在下一节课中,我将略述这些问题背后的数学原理,来解释这个优化问题是如何得到一个大间距分类器的。
参考视频: 12 - 3 - Mathematics Behind Large Margin Classification (Optional) (20 min).mkv
在本节课中,我将介绍一些大间隔分类背后的数学原理。本节为选修部分,你完全可以跳过它,但是听听这节课可能让你对支持向量机中的优化问题,以及如何得到大间距分类器,产生更好的直观理解。
首先,让我来给大家复习一下关于向量内积的知识。假设我有两个向量,和,我将它们写在这里。两个都是二维向量,我们看一下,的结果。也叫做向量和之间的内积。由于是二维向量,我可以将它们画在这个图上。我们说,这就是向量即在横轴上,取值为某个,而在纵轴上,高度是某个作为的第二个分量。现在,很容易计算的一个量就是向量的范数。表示的范数,即的长度,即向量的欧几里得长度。根据毕达哥拉斯定理,,这是向量的长度,它是一个实数。现在你知道了这个的长度是多少了。我刚刚画的这个向量的长度就知道了。
现在让我们回头来看向量 ,因为我们想计算内积。是另一个向量,它的两个分量和是已知的。向量可以画在这里,现在让我们来看看如何计算和之间的内积。这就是具体做法,我们将向量投影到向量上,我们做一个直角投影,或者说一个90度投影将其投影到上,接下来我度量这条红线的长度。我称这条红线的长度为,因此就是长度,或者说是向量投影到向量上的量,我将它写下来,是投影到向量上的长度,因此可以将,或者说的长度。这是计算内积的一种方法。如果你从几何上画出的值,同时画出的范数,你也会同样地计算出内积,答案是一样的。另一个计算公式是:就是 这个一行两列的矩阵乘以。因此可以得到。根据线性代数的知识,这两个公式会给出同样的结果。顺便说一句,。因此如果你将和交换位置,将投影到上,而不是将投影到上,然后做同样地计算,只是把和的位置交换一下,你事实上可以得到同样的结果。申明一点,在这个等式中的范数是一个实数,也是一个实数,因此就是两个实数正常相乘。
最后一点,需要注意的就是值,事实上是有符号的,即它可能是正值,也可能是负值。我的意思是说,如果是一个类似这样的向量,是一个类似这样的向量,和之间的夹角大于90度,则如果将投影到上,会得到这样的一个投影,这是的长度,在这个情形下我们仍然有是等于乘以的范数。唯一一点不同的是在这里是负的。在内积计算中,如果和之间的夹角小于90度,那么那条红线的长度是正值。然而如果这个夹角大于90度,则将会是负的。就是这个小线段的长度是负的。如果它们之间的夹角大于90度,两个向量之间的内积也是负的。这就是关于向量内积的知识。我们接下来将会使用这些关于向量内积的性质试图来理解支持向量机中的目标函数。
这就是我们先前给出的支持向量机模型中的目标函数。为了讲解方便,我做一点简化,仅仅是为了让目标函数更容易被分析。
我接下来忽略掉截距,令,这样更容易画示意图。我将特征数置为2,因此我们仅有两个特征,现在我们来看一下目标函数,支持向量机的优化目标函数。当我们仅有两个特征,即时,这个式子可以写作:,我们只有两个参数。你可能注意到括号里面的这一项是向量的范数,或者说是向量的长度。我的意思是如果我们将向量写出来,那么我刚刚画红线的这一项就是向量的长度或范数。这里我们用的是之前学过的向量范数的定义,事实上这就等于向量的长度。
当然你可以将其写作,如果,那就是的长度。在这里我将忽略,这样来写的范数,它仅仅和有关。但是,数学上不管你是否包含,其实并没有差别,因此在我们接下来的推导中去掉不会有影响这意味着我们的目标函数是等于。因此支持向量机做的全部事情,就是极小化参数向量范数的平方,或者说长度的平方。
现在我将要看看这些项:更深入地理解它们的含义。给定参数向量给定一个样本,这等于什么呢?在前一页幻灯片上,我们画出了在不同情形下,的示意图,我们将会使用这些概念,和就类似于和 。
让我们看一下示意图:我们考察一个单一的训练样本,我有一个正样本在这里,用一个叉来表示这个样本,意思是在水平轴上取值为,在竖直轴上取值为。这就是我画出的训练样本。尽管我没有将其真的看做向量。它事实上就是一个始于原点,终点位置在这个训练样本点的向量。现在,我们有一个参数向量我会将它也画成向量。我将画在横轴这里,将 画在纵轴这里,那么内积 将会是什么呢?
使用我们之前的方法,我们计算的方式就是我将训练样本投影到参数向量,然后我来看一看这个线段的长度,我将它画成红色。我将它称为用来表示这是第 个训练样本在参数向量上的投影。根据我们之前幻灯片的内容,我们知道的是将会等于 乘以向量 的长度或范数。这就等于。这两种方式是等价的,都可以用来计算和之间的内积。
这告诉了我们什么呢?这里表达的意思是:这个 或者的,约束是可以被这个约束所代替的。因为 ,将其写入我们的优化目标。我们将会得到没有了约束,而变成了。
需要提醒一点,我们之前曾讲过这个优化目标函数可以被写成等于。
现在让我们考虑下面这里的训练样本。现在,继续使用之前的简化,即,我们来看一下支持向量机会选择什么样的决策界。这是一种选择,我们假设支持向量机会选择这个决策边界。这不是一个非常好的选择,因为它的间距很小。这个决策界离训练样本的距离很近。我们来看一下为什么支持向量机不会选择它。
对于这样选择的参数,可以看到参数向量事实上是和决策界是90度正交的,因此这个绿色的决策界对应着一个参数向量这个方向,顺便提一句的简化仅仅意味着决策界必须通过原点。现在让我们看一下这对于优化目标函数意味着什么。
比如这个样本,我们假设它是我的第一个样本,如果我考察这个样本到参数的投影,投影是这个短的红线段,就等于,它非常短。类似地,这个样本如果它恰好是,我的第二个训练样本,则它到的投影在这里。我将它画成粉色,这个短的粉色线段是,即第二个样本到我的参数向量的投影。因此,这个投影非常短。事实上是一个负值,是在相反的方向,这个向量和参数向量的夹角大于90度,的值小于0。
我们会发现这些将会是非常小的数,因此当我们考察优化目标函数的时候,对于正样本而言,我们需要,但是如果 在这里非常小,那就意味着我们需要的范数非常大.因为如果 很小,而我们希望,令其实现的唯一的办法就是这两个数较大。如果 小,我们就希望的范数大。类似地,对于负样本而言我们需要。我们已经在这个样本中看到会是一个非常小的数,因此唯一的办法就是的范数变大。但是我们的目标函数是希望找到一个参数,它的范数是小的。因此,这看起来不像是一个好的参数向量的选择。
相反的,来看一个不同的决策边界。比如说,支持向量机选择了这个决策界,现在状况会有很大不同。如果这是决策界,这就是相对应的参数的方向,因此,在这个决策界之下,垂直线是决策界。使用线性代数的知识,可以说明,这个绿色的决策界有一个垂直于它的向量。现在如果你考察你的数据在横轴上的投影,比如这个我之前提到的样本,我的样本,当我将它投影到横轴上,或说投影到上,就会得到这样。它的长度是,另一个样本,那个样本是。我做同样的投影,我会发现,的长度是负值。你会注意到现在 和这些投影长度是长多了。如果我们仍然要满足这些约束,>1,则因为变大了,的范数就可以变小了。因此这意味着通过选择右边的决策界,而不是左边的那个,支持向量机可以使参数的范数变小很多。因此,如果我们想令的范数变小,从而令范数的平方变小,就能让支持向量机选择右边的决策界。这就是支持向量机如何能有效地产生大间距分类的原因。
看这条绿线,这个绿色的决策界。我们希望正样本和负样本投影到的值大。要做到这一点的唯一方式就是选择这条绿线做决策界。这是大间距决策界来区分开正样本和负样本这个间距的值。这个间距的值就是等等的值。通过让间距变大,即通过这些等等的值,支持向量机最终可以找到一个较小的范数。这正是支持向量机中最小化目标函数的目的。
以上就是为什么支持向量机最终会找到大间距分类器的原因。因为它试图极大化这些的范数,它们是训练样本到决策边界的距离。最后一点,我们的推导自始至终使用了这个简化假设,就是参数。
就像我之前提到的。这个的作用是:的意思是我们让决策界通过原点。如果你令不是0的话,含义就是你希望决策界不通过原点。我将不会做全部的推导。实际上,支持向量机产生大间距分类器的结论,会被证明同样成立,证明方式是非常类似的,是我们刚刚做的证明的推广。
之前视频中说过,即便不等于0,支持向量机要做的事情都是优化这个目标函数对应着值非常大的情况,但是可以说明的是,即便不等于0,支持向量机仍然会找到正样本和负样本之间的大间距分隔。
总之,我们解释了为什么支持向量机是一个大间距分类器。在下一节我们,将开始讨论如何利用支持向量机的原理,应用它们建立一个复杂的非线性分类器。
参考视频: 12 - 4 - Kernels I (16 min).mkv
回顾我们之前讨论过可以使用高级数的多项式模型来解决无法用直线进行分隔的分类问题:
为了获得上图所示的判定边界,我们的模型可能是的形式。
我们可以用一系列的新的特征f来替换模型中的每一项。例如令: +
...得到。然而,除了对原有的特征进行组合以外,有没有更好的方法来构造?我们可以利用核函数来计算出新的特征。
给定一个训练样本,我们利用的各个特征与我们预先选定的地标(landmarks)的近似程度来选取新的特征。
例如:
其中:,为实例中所有特征与地标之间的距离的和。上例中的就是核函数,具体而言,这里是一个高斯核函数(Gaussian Kernel)。 注:这个函数与正态分布没什么实际上的关系,只是看上去像而已。
这些地标的作用是什么?如果一个训练样本与地标之间的距离近似于0,则新特征 近似于,如果训练样本与地标之间距离较远,则近似于。
假设我们的训练样本含有两个特征[ ],给定地标与不同的值,见下图:
图中水平面的坐标为 ,而垂直坐标轴代表。可以看出,只有当与重合时才具有最大值。随着的改变值改变的速率受到的控制。
在下图中,当样本处于洋红色的点位置处,因为其离更近,但是离和较远,因此接近1,而,接近0。因此,因此预测。同理可以求出,对于离较近的绿色点,也预测,但是对于蓝绿色的点,因为其离三个地标都较远,预测。
这样,图中红色的封闭曲线所表示的范围,便是我们依据一个单一的训练样本和我们选取的地标所得出的判定边界,在预测时,我们采用的特征不是训练样本本身的特征,而是通过核函数计算出的新特征。
参考视频: 12 - 5 - Kernels II (16 min).mkv
在上一节视频里,我们讨论了核函数这个想法,以及怎样利用它去实现支持向量机的一些新特性。在这一节视频中,我将补充一些缺失的细节,并简单的介绍一下怎么在实际中使用应用这些想法。
如何选择地标?
我们通常是根据训练集的数量选择地标的数量,即如果训练集中有个样本,则我们选取个地标,并且令:。这样做的好处在于:现在我们得到的新特征是建立在原有特征与训练集中所有其他特征之间距离的基础之上的,即:
下面我们将核函数运用到支持向量机中,修改我们的支持向量机假设为:
• 给定,计算新特征,当 时,预测 ,否则反之。
相应地修改代价函数为:,
+在具体实施过程中,我们还需要对最后的正则化项进行些微调整,在计算时,我们用代替,其中是根据我们选择的核函数而不同的一个矩阵。这样做的原因是为了简化计算。
理论上讲,我们也可以在逻辑回归中使用核函数,但是上面使用 来简化计算的方法不适用与逻辑回归,因此计算将非常耗费时间。
在此,我们不介绍最小化支持向量机的代价函数的方法,你可以使用现有的软件包(如liblinear,libsvm等)。在使用这些软件包最小化我们的代价函数之前,我们通常需要编写核函数,并且如果我们使用高斯核函数,那么在使用之前进行特征缩放是非常必要的。
另外,支持向量机也可以不使用核函数,不使用核函数又称为线性核函数(linear kernel),当我们不采用非常复杂的函数,或者我们的训练集特征非常多而样本非常少的时候,可以采用这种不带核函数的支持向量机。
下面是支持向量机的两个参数和的影响:
较大时,相当于较小,可能会导致过拟合,高方差;
较小时,相当于较大,可能会导致低拟合,高偏差;
较大时,可能会导致低方差,高偏差;
较小时,可能会导致低偏差,高方差。
如果你看了本周的编程作业,你就能亲自实现这些想法,并亲眼看到这些效果。这就是利用核函数的支持向量机算法,希望这些关于偏差和方差的讨论,能给你一些对于算法结果预期的直观印象。
参考视频: 12 - 6 - Using An SVM (21 min).mkv
目前为止,我们已经讨论了SVM比较抽象的层面,在这个视频中我将要讨论到为了运行或者运用SVM。你实际上所需要的一些东西:支持向量机算法,提出了一个特别优化的问题。但是就如在之前的视频中我简单提到的,我真的不建议你自己写软件来求解参数,因此由于今天我们中的很少人,或者其实没有人考虑过自己写代码来转换矩阵,或求一个数的平方根等我们只是知道如何去调用库函数来实现这些功能。同样的,用以解决SVM最优化问题的软件很复杂,且已经有研究者做了很多年数值优化了。因此你提出好的软件库和好的软件包来做这样一些事儿。然后强烈建议使用高优化软件库中的一个,而不是尝试自己落实一些数据。有许多好的软件库,我正好用得最多的两个是liblinear和libsvm,但是真的有很多软件库可以用来做这件事儿。你可以连接许多你可能会用来编写学习算法的主要编程语言。
在高斯核函数之外我们还有其他一些选择,如:
多项式核函数(Polynomial Kernel)
字符串核函数(String kernel)
卡方核函数( chi-square kernel)
直方图交集核函数(histogram intersection kernel)
等等...
这些核函数的目标也都是根据训练集和地标之间的距离来构建新特征,这些核函数需要满足Mercer's定理,才能被支持向量机的优化软件正确处理。
多类分类问题
假设我们利用之前介绍的一对多方法来解决一个多类分类问题。如果一共有个类,则我们需要个模型,以及个参数向量。我们同样也可以训练个支持向量机来解决多类分类问题。但是大多数支持向量机软件包都有内置的多类分类功能,我们只要直接使用即可。
尽管你不去写你自己的SVM的优化软件,但是你也需要做几件事:
1、是提出参数的选择。我们在之前的视频中讨论过误差/方差在这方面的性质。
2、你也需要选择内核参数或你想要使用的相似函数,其中一个选择是:我们选择不需要任何内核参数,没有内核参数的理念,也叫线性核函数。因此,如果有人说他使用了线性核的SVM(支持向量机),这就意味这他使用了不带有核函数的SVM(支持向量机)。
从逻辑回归模型,我们得到了支持向量机模型,在两者之间,我们应该如何选择呢?
下面是一些普遍使用的准则:
为特征数,为训练样本数。
(1)如果相较于而言,要大许多,即训练集数据量不够支持我们训练一个复杂的非线性模型,我们选用逻辑回归模型或者不带核函数的支持向量机。
(2)如果较小,而且大小中等,例如在 1-1000 之间,而在10-10000之间,使用高斯核函数的支持向量机。
(3)如果较小,而较大,例如在1-1000之间,而大于50000,则使用支持向量机会非常慢,解决方案是创造、增加更多的特征,然后使用逻辑回归或不带核函数的支持向量机。
值得一提的是,神经网络在以上三种情况下都可能会有较好的表现,但是训练神经网络可能非常慢,选择支持向量机的原因主要在于它的代价函数是凸函数,不存在局部最小值。
今天的SVM包会工作得很好,但是它们仍然会有一些慢。当你有非常非常大的训练集,且用高斯核函数是在这种情况下,我经常会做的是尝试手动地创建,拥有更多的特征变量,然后用逻辑回归或者不带核函数的支持向量机。如果你看到这个幻灯片,看到了逻辑回归,或者不带核函数的支持向量机。在这个两个地方,我把它们放在一起是有原因的。原因是:逻辑回归和不带核函数的支持向量机它们都是非常相似的算法,不管是逻辑回归还是不带核函数的SVM,通常都会做相似的事情,并给出相似的结果。但是根据你实现的情况,其中一个可能会比另一个更加有效。但是在其中一个算法应用的地方,逻辑回归或不带核函数的SVM另一个也很有可能很有效。但是随着SVM的复杂度增加,当你使用不同的内核函数来学习复杂的非线性函数时,这个体系,你知道的,当你有多达1万(10,000)的样本时,也可能是5万(50,000),你的特征变量的数量这是相当大的。那是一个非常常见的体系,也许在这个体系里,不带核函数的支持向量机就会表现得相当突出。你可以做比这困难得多需要逻辑回归的事情。
最后,神经网络使用于什么时候呢? 对于所有的这些问题,对于所有的这些不同体系一个设计得很好的神经网络也很有可能会非常有效。有一个缺点是,或者说是有时可能不会使用神经网络的原因是:对于许多这样的问题,神经网络训练起来可能会特别慢,但是如果你有一个非常好的SVM实现包,它可能会运行得比较快比神经网络快很多,尽管我们在此之前没有展示,但是事实证明,SVM具有的优化问题,是一种凸优化问题。因此,好的SVM优化软件包总是会找到全局最小值,或者接近它的值。对于SVM你不需要担心局部最优。在实际应用中,局部最优不是神经网络所需要解决的一个重大问题,所以这是你在使用SVM的时候不需要太去担心的一个问题。根据你的问题,神经网络可能会比SVM慢,尤其是在这样一个体系中,至于这里给出的参考,看上去有些模糊,如果你在考虑一些问题,这些参考会有一些模糊,但是我仍然不能完全确定,我是该用这个算法还是改用那个算法,这个没有太大关系,当我遇到机器学习问题的时候,有时它确实不清楚这是否是最好的算法,但是就如在之前的视频中看到的算法确实很重要。但是通常更加重要的是:你有多少数据,你有多熟练是否擅长做误差分析和排除学习算法,指出如何设定新的特征变量和找出其他能决定你学习算法的变量等方面,通常这些方面会比你使用逻辑回归还是SVM这方面更加重要。但是,已经说过了,SVM仍然被广泛认为是一种最强大的学习算法,这是一个体系,包含了什么时候一个有效的方法去学习复杂的非线性函数。因此,实际上与逻辑回归、神经网络、SVM一起使用这些方法来提高学习算法,我认为你会很好地建立很有技术的状态。(编者注:当时GPU计算比较慢,神经网络还不流行。)
机器学习系统对于一个宽泛的应用领域来说,这是另一个在你军械库里非常强大的工具,你可以把它应用到很多地方,如硅谷、在工业、学术等领域建立许多高性能的机器学习系统。