无监督学习(unsurpervised learning)是深度学习的基础,也是大数据时代科学家们用来处理数据挖掘的主要工具。个人理解的话就是数据太多,而人们不可能给每个数据样本加标签吧,所以才有了无监督学习。当然用的最多的是用无监督学习算法训练参数,然后用一部分加了标签的数据测试。这种方法叫半监督学习(semi-unsurpervised)。最近看的几个深度学习算法是:稀疏自编码(sparse auto-encoder)、稀疏限制玻尔兹曼机器(sparse RBM)、K-means 聚类和高斯混合模型。根据论文An Analysis of Single-Layer Networks in Unsupervised Feature Learning的实验结果,K-means聚类算法是准确率最高,而且不需要超参数(hyper-parameter)。

稀疏自编码(sparse auto-encoder)

提到自编码,就必须了解BP神经网络。而稀疏自编码是在自编码基础上加入了对隐藏单元活性(activition)的限制:即稀疏性参数ρ,通常是一个接近于0的较小值(比如ρ=0.05)。如果机器学习的基础比较薄弱的话,建议先看Andrew Ng 老师讲授的《机器学习》

BP神经网络,是使用前向传播(forward propagation)、后向传播(backward propagation)来训练参数。这里给出前向传播和后向传播的公式,具体细节见参考资料:

Network3322.png

前向传播(向量表示法):

\begin{align}
z^{(2)} &= W^{(1)} x + b^{(1)} \\
a^{(2)} &= f(z^{(2)}) \\
z^{(3)} &= W^{(2)} a^{(2)} + b^{(2)} \\
h_{W,b}(x) &= a^{(3)} = f(z^{(3)})
\end{align}

其中,f(x)称为激活函数(activation function).可以或者激活函数

sigmoid函数:


f(z) = \frac{1}{1+\exp(-z)}.
取值范围[0,1].它的导数就是\textstyle f'(z) = f(z) (1-f(z)) 

 双曲正切函数:


f(z) = \tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}},  
取值范围[-1,1]。它的导数是 \textstyle f'(z) = 1- (f(z))^2

(激活函数的导数在后向传播中会经常用到)

后向传播:

前向传播中,需要用到的参数W和b,是我们要训练的参数。我们可以利用批量梯度下降的方法求得(这部分需要熟悉机器学习中梯度下降部分)。给定一个包含m个样例的数据集,我们可以定义整体代价函数为:

 
\begin{align}
J(W,b)
&= \left[ \frac{1}{m} \sum_{i=1}^m J(W,b;x^{(i)},y^{(i)}) \right]
                       + \frac{\lambda}{2} \sum_{l=1}^{n_l-1} \; \sum_{i=1}^{s_l} \; \sum_{j=1}^{s_{l+1}} \left( W^{(l)}_{ji} \right)^2
 \\
&= \left[ \frac{1}{m} \sum_{i=1}^m \left( \frac{1}{2} \left\| h_{W,b}(x^{(i)}) - y^{(i)} \right\|^2 \right) \right]
                       + \frac{\lambda}{2} \sum_{l=1}^{n_l-1} \; \sum_{i=1}^{s_l} \; \sum_{j=1}^{s_{l+1}} \left( W^{(l)}_{ji} \right)^2
\end{align}

其中,
\begin{align}
J(W,b; x,y) = \frac{1}{2} \left\| h_{W,b}(x) - y \right\|^2.
\end{align}
第一项中的 \textstyle J(W,b)是一个均方差项;第二项则是一个正规化项,其目的是减少权值的幅度,防止过度拟合。

于是就有了梯度下降法中每一次迭代对W和b的更新:


\begin{align}
W_{ij}^{(l)} &= W_{ij}^{(l)} - \alpha \frac{\partial}{\partial W_{ij}^{(l)}} J(W,b) \\
b_{i}^{(l)} &= b_{i}^{(l)} - \alpha \frac{\partial}{\partial b_{i}^{(l)}} J(W,b)
\end{align}

其中α是学习速率。而关键步骤则是计算偏导数~这个,就是我们要讲的后向传播算法了。

整体代价函数的\textstyle J(W,b)的偏导数:


\begin{align}
\frac{\partial}{\partial W_{ij}^{(l)}} J(W,b) &=
\left[ \frac{1}{m} \sum_{i=1}^m \frac{\partial}{\partial W_{ij}^{(l)}} J(W,b; x^{(i)}, y^{(i)}) \right] + \lambda W_{ij}^{(l)} \\
\frac{\partial}{\partial b_{i}^{(l)}} J(W,b) &=
\frac{1}{m}\sum_{i=1}^m \frac{\partial}{\partial b_{i}^{(l)}} J(W,b; x^{(i)}, y^{(i)})
\end{align}

现在对其分析可以知道::

于是,后向传播算法就是在说明针对第 \textstyle l 层的每一个节点 \textstyle i,我们计算出其“残差”\textstyle \delta^{(l)}_i

天才的科学家们提出了如下的计算过程:

  1. 进行前馈传导计算,利用前向传导公式,得到 \textstyle L_2, L_3, \ldots  直到输出层 \textstyle L_{n_l} 的激活值。

  2.对于第 \textstyle n_l 层(输出层)的每个输出单元 \textstyle i,我们根据以下公式计算残差:


\begin{align}
\delta^{(n_l)}_i
= \frac{\partial}{\partial z^{(n_l)}_i} \;\;
        \frac{1}{2} \left\|y - h_{W,b}(x)\right\|^2 = - (y_i - a^{(n_l)}_i) \cdot f'(z^{(n_l)}_i)
\end{align}
3.对 \textstyle l = n_l-1, n_l-2, n_l-3, \ldots, 2 的各个层,第 \textstyle l 层的第 \textstyle i 个节点的残差计算方法如下:
 
\delta^{(l)}_i = \left( \sum_{j=1}^{s_{l+1}} W^{(l)}_{ji} \delta^{(l+1)}_j \right) f'(z^{(l)}_i)

  4.计算我们需要的偏导数,计算方法如下:

 
\begin{align}
\frac{\partial}{\partial W_{ij}^{(l)}} J(W,b; x, y) &= a^{(l)}_j \delta_i^{(l+1)} \\
\frac{\partial}{\partial b_{i}^{(l)}} J(W,b; x, y) &= \delta_i^{(l+1)}.
\end{align}

最后,我们将对梯度下降算法做个全面总结。在下面的伪代码中,\textstyle \Delta W^{(l)} 是一个与矩阵 \textstyle W^{(l)} 维度相同的矩阵,\textstyle \Delta b^{(l)} 是一个与 \textstyle b^{(l)} 维度相同的向量。注意这里“\textstyle \Delta W^{(l)}”是一个矩阵,而不是“\textstyle \Delta与 \textstyle W^{(l)} 相乘”。下面,我们实现批量梯度下降法中的一次迭代:

 

  1. 对于所有 \textstyle l,令 \textstyle \Delta W^{(l)} := 0 , \textstyle \Delta b^{(l)} := 0 (设置为全零矩阵或全零向量)
  2. 对于 \textstyle i = 1 到 \textstyle m
    1. 使用反向传播算法计算 \textstyle \nabla_{W^{(l)}} J(W,b;x,y) 和 \textstyle \nabla_{b^{(l)}} J(W,b;x,y)
    2. 计算 \textstyle \Delta W^{(l)} := \Delta W^{(l)} + \nabla_{W^{(l)}} J(W,b;x,y)
    3. 计算 \textstyle \Delta b^{(l)} := \Delta b^{(l)} + \nabla_{b^{(l)}} J(W,b;x,y)
  3. 更新权重参数:
     \begin{align}
W^{(l)} &= W^{(l)} - \alpha \left[ \left(\frac{1}{m} \Delta W^{(l)} \right) + \lambda W^{(l)}\right] \\
b^{(l)} &= b^{(l)} - \alpha \left[\frac{1}{m} \Delta b^{(l)}\right]
\end{align}

於乎~就这样了。。。

下面就好办了,对于自编码,无非就是尝试学习一个 \textstyle h_{W,b}(x) \approx x 的函数。而稀疏自编码则是给隐藏神经元加入稀疏性限制。

呐:

\begin{align}
\hat\rho_j = \frac{1}{m} \sum_{i=1}^m \left[ a^{(2)}_j(x^{(i)}) \right]
\end{align}

表示隐藏神经元j的平均活跃度,而限制则是\begin{align}
\hat\rho_j = \rho,
\end{align}\textstyle \rho 是稀疏性参数,通常是一个接近于0的较小的值(比如 \textstyle \rho = 0.05 )。

于是有了惩罚因子:

\begin{align}
\sum_{j=1}^{s_2} {\rm KL}(\rho || \hat\rho_j),
\end{align}等于\begin{align}
\sum_{j=1}^{s_2} \rho \log \frac{\rho}{\hat\rho_j} + (1-\rho) \log \frac{1-\rho}{1-\hat\rho_j}.
\end{align}

这是相对熵的公式表示形式,意义在于当 \textstyle \hat\rho_j = \rho 时 \textstyle {\rm KL}(\rho || \hat\rho_j) = 0 。相对熵的三条结论:

1.对于两个完全相同的函数,它们的相对熵等于0.

2.相对熵越大,两个函数差异越大;反之,相对熵越小,差异越小。

3.对于概率分布或者概率密度分布,如果取值均大于零,相对熵可以度量两个随机分布的差异性。

(引用吴军老师《数学之美》中的结论)。

所以,稀疏自编码的总体代价函数就是:

\begin{align}
J_{\rm sparse}(W,b) = J(W,b) + \beta \sum_{j=1}^{s_2} {\rm KL}(\rho || \hat\rho_j),
\end{align}

 

而实际与后向传播不同的地方就是:

\begin{align}
\delta^{(2)}_i = \left( \sum_{j=1}^{s_{2}} W^{(2)}_{ji} \delta^{(3)}_j \right) f'(z^{(2)}_i),
\end{align}

现在我们将其换成

\begin{align}
\delta^{(2)}_i =
  \left( \left( \sum_{j=1}^{s_{2}} W^{(2)}_{ji} \delta^{(3)}_j \right)
+ \beta \left( - \frac{\rho}{\hat\rho_i} + \frac{1-\rho}{1-\hat\rho_i} \right) \right) f'(z^{(2)}_i) .
\end{align}
嗯,就此算是结束了对稀疏自编码的介绍。如果对一些概念不懂的话,请先了解Andrew Ng老师讲解的《机器学习课程》。

 

参考资料:

1,斯坦福大学关于深度学习的网站(其实你只要看这个,稀疏自编码你就明白了,我的基本算是copy这的)

http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B

2,Andrew Ng老师讲解的《机器学习课程》

http://openclassroom.stanford.edu/MainFolder/CoursePage.php?course=MachineLearning