视频课提到但没有详细解释的算法,如果选择使用这三个算法中的任何一个,都不需要手动选择学习率 α \alpha α。因为这些算法有一个“智能内循环",称为线性搜索算法,它可以自动尝试不同的学习速率 α \alpha α并自动选择好的学习速率 α \alpha α,它甚至可以为每次迭代选择不同的学习速率。
- Conjugate gradient
- BFGS
- L-BFGS
一对多的分类算法(多类别分类问题)
我们训练了一个逻辑回归分类器 h θ ( i ) ( x ) h_\theta^{(i)}(x) hθ(i)(x)预测i类别y=i的概率,最后为了做出预测,我们给出一个新的输入值x期望获得预测,我们要做的就是,在比如三个分类器运行输入x,然后选择h最大的类别,也就是要选择分类器,选择三个中可信度最高,效果最好的那个分类器,无论i值是多少,我们都能得到一个最高的概率值,我们预测y就是那个值。
- 一对多分类的原理如下:
假设我们有一个训练集,它包含三个类别,我们用三角形表示y=1,方形表示y=2,交叉表示y=3。我们要做的将这个训练集,转化为三个独立的二元分类问题,我将它分成三个独立的二元分类问题。
我们先从三角形代表的类别1开始,我们将创建一个新的”伪“训练集,其中类别2和类别3设定为负类,类别1设定为正类。我们将创建一个新的训练集,我们要拟合一个分类器,我们称其为 h θ ( 1 ) ( x ) h_\theta^{(1)}(x) hθ(1)(x),我们可以训练出一个标准的逻辑回归分类器,这样我们就得到一个判定边界。
对于类别2、类别3处理方式同类别1。
Overfitting 过度拟合
过度拟合的算法具有高方差。如果我们拟合一个高阶多项式,那么这个假设函数能拟合几乎所有的数据,这就面临可能的函数太过庞大,变量太多的问题,我们没有足够的数据来约束它,来获得一个好的假设函数,这就是过度拟合。
- 它千方百计地拟合训练集,导致它无法泛化到新的样本中,无法预测新样本的值。(泛化是指一个假设模型应用到新样本的能力,新样本数据是指没有出现在训练集的房子。)
当我们使用一维或二维数据时,我们可以通过绘出假设模型的图像来研究问题所在,再选择合适的多项式阶数。
事实上,很多时候我们的学习问题需要有很多变量,并且这不仅仅是选择多项式阶次的问题。
事实上我们有很多的特征变量时,绘图变得更难,来决定保留哪些特征变量也更难,有许多特征变量都可能有关,如果我们有过多的变量而且只有非常少量的训练数据,就会出现过度拟合的问题。
下面针对过拟合问题有两个解决方案:
- 第一种方法:减少选取变量的数量。可以人工检查清单,决定哪些特征变量可以删除,哪些特征变量应该保留。也可以使用模型选择算法,这种算法可以自动选择哪些变量应该保留,哪些变量应该舍弃。
- 第二种方法:进行正则化。正则化的思想是,如果我们的参数值较小,那么就意味着一个更简单的假设模型。
Regularization:
J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∑ j = 1 n θ j 2 ] J(\theta) = \frac {1}{2m}[\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2 + \lambda\sum_{j=1}^n\theta_j^2] J(θ)=2m1[i=1∑m(hθ(x(i))−y(i))2+λj=1∑nθj2]
式子中的 λ \lambda λ被称为正则化参数,这个 λ \lambda λ的作用就是控制两个不同目标之间的取舍。它用来控制两个目标之间的平衡关系,即更好地去拟合训练集的目标,和将参数控制的更小的目标,从而避免过拟合的情况。
欠拟合 Underfitting
算法推广至正则化线性回归
算法有基于梯度下降算法和基于正规方程算法。
- 基于梯度下降算法的式子:
Repeat:{
θ 0 : = θ 0 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x 0 ( i ) θ j : = θ j − α [ 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) + λ m θ j ] ( j = 1 , 2 , 3 , 4... n ) \theta_0 := \theta_0 - \alpha \frac{1}{m} \sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})x_0^{(i)} \\ \theta_j := \theta_j - \alpha[\frac{1}{m} \sum_{i = 1}^m(h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)} + \frac{\lambda}{m}\theta_j] \\ (j = 1,2,3,4...n) θ0:=θ0−αm1i=1∑m(hθ(x(i))−y(i))x0(i)θj:=θj−α[m1i=1∑m(hθ(x(i))−y(i))xj(i)+mλθj](j=1,2,3,4...n)
} - 基于正规方程算法的式子:
X = [ ( x ( 1 ) ) T . . . ( x ( m ) ) T ] y = [ y ( 1 ) . . . y ( m ) ] X = \begin{bmatrix} (x^{(1)})^T \\ .\\.\\.\\(x^{(m)})^T \end{bmatrix} \;\;\;\; y = \begin{bmatrix} y^{(1)}\\ .\\.\\.\\y^{(m)} \end{bmatrix} X= (x(1))T...(x(m))T y= y(1)...y(m)
如果m ≤ \leq ≤n,那么 X T X X^TX XTX是不可逆的矩阵。
非线性假设
神经网络有输入层,隐藏层和输出层。
-
α
i
(
j
)
\alpha_i^{(j)}
αi(j)表示第j层第i个神经元或单元的激活项,所谓激活项是指由一个具体神经元计算并输出的值。
- Θ ( j ) \Theta^{(j)} Θ(j)代表权重矩阵,它控制从j层到j+1 层的映射。 一般地,如果一个网络在第j层有 s j s_j sj个单元,在j+1层有 s j + 1 s_{j+1} sj+1个单元,那么 Θ ( j ) \Theta^{(j)} Θ(j)的维度为 s j + 1 × ( s j + 1 ) s_{j+1} \times (s_j+1) sj+1×(sj+1)。
如何利用神经网络解决多类别分类问题
下面与逻辑回归的代价函数对比。
-
逻辑回归的代价函数如下:
J ( θ ) = − 1 m [ ∑ i = 1 m y ( i ) l o g h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta) = - \frac{1}{m}[\sum_{i = 1}^m y^{(i)} log h_\theta(x^{(i)})+(1-y^{(i)})\log(1-h_\theta(x^{(i)}))] + \frac {\lambda}{2m} \sum _{j =1}^n\theta_j^2 J(θ)=−m1[i=1∑my(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2 -
神经网络的代价函数如下:
J ( Θ ) = − 1 m [ ∑ i = 1 m ∑ k = 1 K y k ( i ) log ( h Θ ( x ( i ) ) ) k + ( 1 − y k ( i ) ) log ( 1 − ( h Θ ( x ( i ) ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j i ( l ) ) 2 J(\Theta) = -\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}\log(h_\Theta(x^{(i)}))_k+(1-y_k^{(i)})\log(1 - (h\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\Theta_{ji}^{(l)})^2 J(Θ)=−m1[i=1∑mk=1∑Kyk(i)log(hΘ(x(i)))k+(1−yk(i))log(1−(hΘ(x(i)))k)]+2mλl=1∑L−1i=1∑slj=1∑sl+1(Θji(l))2
其中h Θ ( x ) \Theta(x) Θ(x) ∈ R K R^K RK; ( h Θ ( x ) ) i (h_\Theta(x))_i (hΘ(x))i = i t h i^{th} ith output -
让神经网络的代价函数最小化的算法如下
(省略)
梯度检验
反向传播算法含有许多细节,因此实现起来比较困难,并且它有一个不好的特性:很容易产生一些微妙的bug。
当它与梯度下降或是其他算法一同工作时,看起来它确实能正常运行,并且代价函数J( θ \theta θ)在每次梯度下降的过程中也在不断减小,虽然在反向传播的实现中存在一些bug,但运行情况看起来确实不错。
虽然J( θ \theta θ)在不断减小,但是到了最后你得到的神经网络,其误差会比无bug的情况下高出一个量级,并且你可能不知道你得到的结果是由bug导致的。
为应对此类问题,有一种思想叫做梯度检验,它能解决几乎所有这种问题。它几乎能完全保证你的前向传播以及后向传播都会是百分之百正确。
- 计算某一点导数的近似值我通常使用双侧差分,双侧差分能获得比单侧差分更加精确的结果。即:
J
(
θ
+
ϵ
)
−
J
(
θ
−
ϵ
)
2
ϵ
\frac{J(\theta + \epsilon) - J(\theta-\epsilon)}{2\epsilon}
2ϵJ(θ+ϵ)−J(θ−ϵ)
上式可以推广到如下情况:
- 实现数值上的梯度检验:
首先,通过反向传播来计算DVec;然后,计算出gradApprox要确保这两者值很接近;最后,在使用你的代码进行学习之前需要关掉梯度检验。因为梯度检验代码计算量非常大也是个非常慢的计算导数的程序。一旦通过检验确定反向传播正确就不再去使用梯度检验,关掉它。
随机初始化:
当你执行一个算法,比如梯度下降法或高级优化算法时,我们需要为变量 Θ \Theta Θ赋初值,对于高级优化算法,它们默认你为会变量 Θ \Theta Θ提供一些初始值。
对于梯度下降法,同样地,我们也需要对 Θ \Theta Θ值进行初始化,初始化完毕后我们就可以一步一步通过梯度下降来最小化代价函数J,对于初始化值,有一种想法是将 Θ \Theta Θ的初始值全部设为0。i尽管在逻辑回归中这样做是被允许的,但实际上在训练网络时,将所有参数初始化为0起不到任何作用。(具体解释:如果全部初始化为0,那么全部的隐藏单元都在计算相同的特征,所有的隐藏单元都以相同的函数作为输入,这是一种高度冗余的现象。这意味着最后的逻辑回归单元只能得到一个特征,因为所有的单元都一样,这种情况阻止了神经网络去学习任何有趣的东西。以上问题也被称为对称权重问题,也就是所有的权重都是一样的。)
为了解决这个问题,对参数进行初始化时,要使用随机初始化的思想。
训练一个神经网络的总体实现过程
- 选择一种网络架构。(决定输入单元数量,隐藏层层数和单元数以及输出层单元数量。)这取决于具体问题,输入单元的数量等于你选的特征集的维度;如果你在进行多类别的分类,那么输出层的单元数目将由分类问题中种类的数量决定(记得用向量表示);对于隐藏层,一个合理的默认选项是只是用单个隐藏层,如果使用多个隐藏层,这里还有一个合理的默认选项是每个隐藏层通常应有相同的单元数。
通常情况下,隐藏单元越多越好。但需要注意,如果有大量隐藏单元,计算量一般会比较大,并且一般来说,每个隐藏层所包含的单元数量,还应该和输入x的维度相匹配,即和特征数目相匹配,隐藏单元的数目可以和输入特征的数量相同,或者是它的两倍或者三四倍。 - 训练神经网络需要的步骤:
Step1:构建一个神经网络,然后随机初始化权重,通常我们把权重初始化为很小的值,接近于0。
Step2:执行前向传播算法,也就是对于该神经网络的任意一个输入 x ( i ) x^{(i)} x(i)计算出对应的 h Θ ( x ( i ) ) h_\Theta(x^{(i)}) hΘ(x(i))值,也就是一个输出值y的向量。
Step3:通过代码计算出代价函数J( θ \theta θ)。
Step4:执行反向传播算法,计算出这些偏导数,即 ∂ ∂ Θ j k ( l ) J ( Θ ) \frac{\partial}{\partial\Theta_{jk}^{(l)}}J(\Theta) ∂Θjk(l)∂J(Θ)
具体来说,使用反向传播,我们要对所以训练样本使用一个for循环进行遍历。但我非常不推荐在第一次使用反向传播算法的时候不使用for循环而选择更高级更复杂的方法。
执行以上步骤之后,我们就能得到神经网络每一层中每一个单元对应的激励值,和 δ \delta δ项。
Step5:使用梯度检查来比较这些已经计算得到的偏导数项,把用反向传播算法得到的偏导数值与用数值方法得到的估计值进行比较。通过梯度检测我们能确保我们的反向传播算法得到的结果是正确的。注意,检查完后需要停止梯度检查。
Step6:使用梯度下降算法或更高级的算法比如LBFGS算法,共轭梯度法,或者其他内置到fminunc函数中的方法。将这些优化方法,和反向传播算法结合,反向传播算法计算出这些偏导数项的值,这样我们就能最小化关于 θ \theta θ的代价函数。
注意:对于神经网络,代价函数是一个非凸函数,因此理论上可能停留在局部最小值的位置,实际上梯度下降算法和其他一些高级优化算法理论上都可能收敛于局部最小值(问题不大)。