稀疏自编码器

稀疏自编码器

自编码器

传统反向传播神经网络缺点:

  • 梯度越来越稀疏(梯度弥散):从顶层越往下,误差校正信号越来越小;
  • 容易收敛到局部最小值,尤其是从远离最优区域开始的时候(将参数初始化为随机值会导致这种情况发生);
  • 只能进行有监督训练,但大部分的数据是没有标签的,而人类的大脑可以从没有标签的数据中学习。

1986 年,Rumelhart 提出了自动编码器的概念,并将其用于高维复杂数据的处理,促进了神经网络的发展。自编码神经网络是一种无监督(自监督)学习算法,它使用了反向传播算法,并让目标值等于输入值,即自编码神经网络尝试学习一个 hW,b(x)xh_{W, b}(x) \approx x 的函数。

image-20230127000157707

自编码器分类:

  • 浅层自编码(Autoencoder)
  • 稀疏自编码(Sparse Autoencoder)
  • 栈式自编码(Stacked Autoencoder)
  • 去噪自编码(Denoising Autoencoder)
  • 变分自编码(Variational Autoencoder)

自编码器的共同点:学习一个与输入相同的输出,并尽可能的让其具有较强的泛化能力

自编码器的构成:
image-20230127000203567

编码器是把高维度数据有损的映射成低维度数据,减少数据量,要实现这种映射关系需要学习数据间的相关性,对输入 xx 编码,得到新的特征 yy

y=f(W1x+b1)y = f(W_1x + b_1)

解码器和编码器完全相反,是把低维度数据映射成高维度数据,增加数据量,使经过压缩的数据恢复成原来的样子,即利用新的特征 yy,得到一个重构的数据 xx'

x=g(W2y+b2)x' = g(W_2y + b_2)

损失函数用来衡量由于压缩而损失掉的信息。编码器和解码器一般都是参数化的方程,且关于损失函数可导,典型的情况是使用最小均方误差

MSE=1ni=1n(xx)2\text{MSE} = \dfrac 1n \sum\limits_{i=1}^n (x - x')^2

来作为损失函数。

image-20230127000208726

深度自编码器(DAE)

image-20230127000215118

2006 年,Hinton 对原型自动编码器的结构进行了改进,进而产生了 DAE,先用无监督逐层贪心训练算法完成对隐含层的预训练,然后用反向传播算法对整个神经网络进行系统性参数优化调整,显著降低了神经网络的训练复杂程度,有效改善了反向传播算法容易陷入局部最小的不良状况。

将三层浅层自编码器扩展成具有多个隐藏层的编码器即为深度自编码器,能更好的学习数据更高维度的特征。

逐层学习

在深度自编码器中,对其中的多个隐藏层,我们需要进行逐层自编码学习。具体地,每一个编码层中都会包含一个解码器,用来输出当前层的解码结果,我们贪心地希望每一层的解码结果都与前一层向其输入的结果尽可能的相似,如下图所示:
image-20230127000225444

深度自编码器特点:具有强大的表达能力及深度神经网络的所有优点。它通常能够获取到输入的“层次性分组”或者“部分-整体分解”结构。自编码器倾向于学习得到能更好地表示输入数据的特征

稀疏表示和稀疏编码

稀疏表示

稀疏表示的目的是在给定的超完备字典中用尽可能少的原子来表示信号,可以获得信号更为简洁的表示方式,从而使我们更容易地获取信号中所蕴含的信息,更方便进一步对信号进行加工处理,如压缩、编码等。

我们可以寻找一个系数矩阵 uu 和一个字典矩阵 VV,使得 V×uV \times u 尽可能的还原 xx,且 uu 尽可能地稀疏,则 uu 就是 xx 的稀疏表示。我们将一个大矩阵变成两个小矩阵,从而达到压缩的目的。

image-20230127000231342

给定数据集 {x1,x2,,xm}\left\{\boldsymbol{x}_1, \boldsymbol{x}_2, \dots, \boldsymbol{x}_m\right\},字典学习的最简单形式为

J(B,α)=minB,αii=1mxiBαi22+λi=1mαi1J(\mathbf B, \boldsymbol{\alpha}) = \min_{\mathbf B, \boldsymbol{\alpha}_i} \sum_{i=1}^m\left\|x_i - \mathbf B \boldsymbol{\alpha}_i\right\|_2^2 + \lambda\sum_{i=1}^m\left\|\boldsymbol{\alpha}_i\right\|_1

其中 BRd×k\mathbf B \in \mathbb{R}^{d \times k} 为字典矩阵,kk 称为字典的词汇量,通常由用户指定。αiRk\boldsymbol{\alpha}_i \in \mathbb{R}^k 则是样本 xiRd\boldsymbol{x}_i \in \mathbb{R}^d 的稀疏表示。显然,上式的第一项是希望 αi\boldsymbol{\alpha}_i 能较好地重构 xi\boldsymbol{x}_i,第二项则是希望 αi\boldsymbol{\alpha}_i 尽量稀疏,可以再加入一项 +βrcBrc2+ \beta\sum_r\sum_c \mathbf B_{rc}^2,表示希望字典中每项也尽可能小。

为了较为简单的最小化上述二元函数,我们通过变量交替优化的策略来进行:

  • 首先随机初始化字典矩阵 B\mathbf B
  • 然后通过梯度下降,得到 B\mathbf B 确定时使得函数 J(,)J(\cdot, \cdot) 取得最小值时的 α\boldsymbol{\alpha}
  • 再通过梯度下降,得到 α\boldsymbol{\alpha} 确定时使得函数 J(,)J(\cdot, \cdot) 取得最小值时的 B\mathbf B
  • 不断重复上述两步,直至结果确定。

稀疏自编码

一个神经网络的稀疏性可以被简单的解释为,这里假设神经元的激活函数为 sigmoid 函数,则当神经元的输出接近为 1 时,我们认为它是被激活的;而当其接近为 0 时,我们认为它是被抑制的。那么一个神经网络中,使得神经元在大部分的时间内都是被抑制的限制称为稀疏性限制

考虑一个最简单的自编码器,其神经网络只有三层,那么 aj(2)a_j^{(2)} 表示隐藏层中的隐藏神经元 jj 的激活值,但这种表示方法无法表示是哪一个输入 xx 带来的激活值,所以我们改用 aj(2)(x)a_j^{(2)}(x) 表示在给定输入为 xx 的情况下,隐藏层中的隐藏神经元 jj 的激活值。

ρ^j=1mi=1maj(2)(x(i))\hat{\rho}_j = \dfrac 1m \sum_{i=1}^m{a_j^{(2)}(x^{(i)})}

表示隐藏神经元 jjmm 个输入样本上的平均激活度,举例如下:
image-20230127000239409

我们可以近似的加入一条限制:ρ^j=ρ\hat{\rho}_j = \rho,其中 ρ\rho 被称为稀疏性参数,通常是一个接近 0 的较小的值,如 0.05。

为了满足这一限制,将会在优化目标函数中加入一个惩罚因子,这将惩罚那些 ρ^j\hat{\rho}_jρ\rho 有显著不同的情况,从而使得隐藏神经元的平均活跃度保持在较小范围内。

定义两分布 PPQQ 之间的相对熵(KL 散度)为

D(PQ)=xE[lnp(x)lnq(x)]=xp(x)lnp(x)q(x)D(P\|Q) = \sum_xE\left[\ln p(x) - \ln q(x)\right] = \sum_xp(x) \ln \dfrac{p(x)}{q(x)}

其中 p(x)p(x)q(x)q(x) 为两分布的概率密度函数。相对熵可以解释为“通过 qq 的编码去编码 pp后,信息丢失数的期望”,可以用相对熵来表示两个分布之间的差异。

把隐层的每个神经元的激活和未激活态看做服从二项分布,则 KL 散度可以表示为一个以 ρ\rho 为均值和一个以 ρ^j\hat{\rho}_j 为均值的两个二项分布之间的相对熵:

KL(ρρ^j)=ρlnρρ^j+(1ρ)ln1ρ1ρ^j\operatorname{KL}(\rho \| \hat{\rho}_j) = \rho\ln\dfrac{\rho}{\hat{\rho}_j} + (1 - \rho) \ln \dfrac{1 - \rho}{1 - \hat{\rho}_j}

KL 散度有两个特点:

  • KL(ρρ^j)0\operatorname{KL}(\rho \| \hat{\rho}_j) \geq 0,当且仅当 ρ=ρ^j\rho = \hat{\rho}_j 时取等号;
  • 非对称性:KL(ρρ^j)KL(ρ^jρ)\operatorname{KL}(\rho\|\hat{\rho}_j) \neq \operatorname{KL}(\hat{\rho}_j\|\rho)

下面是 ρ=0.1\rho=0.1ρ=0.3\rho=0.3 时 KL 散度的图像:
image-20230127000248057

可以发现,当 ρ^j0 or 1\hat{\rho}_j \to 0 \text{ or } 1 时,KL(ρρ^j)\operatorname{KL}(\rho\|\hat{\rho}_j) \to \infty,这很好的惩罚了二者有显著不同的情况。

现在,总体的代价函数可以表示为

Jsparse(B,α)=J(B,α)+βj=1s2KL(ρρ^j)J_{\text{sparse}}(\mathbf B, \boldsymbol{\alpha}) = J(\mathbf B, \boldsymbol{\alpha}) + \beta\sum_{j=1}^{s_2}\operatorname{KL}(\rho\|\hat{\rho}_j)

注意到

KL(ρρ^j)ρ^j=ρρ^j+1ρ1ρ^j\dfrac{\partial \operatorname{KL}(\rho \| \hat{\rho}_j)}{\partial \hat{\rho}_j} = -\dfrac{\rho}{\hat{\rho}_j} + \dfrac{1 - \rho}{1 - \hat{\rho}_j}

于是在神经网络的反向传播中,当前层误差 δ(l)\delta^{(l)} 更新为

δ(l)=((ω(l+1))Tδ(l+1)+β(ρρ^j+1ρ1ρ^j))g(z(l))\delta^{(l)} = \left((\omega^{(l+1)})^\mathrm{T}\delta^{(l+1)} + \beta\left(-\dfrac{\rho}{\hat{\rho}_j} + \dfrac{1 - \rho}{1 - \hat{\rho}_j}\right)\right) \odot g'\left(z^{(l)}\right)

即可,其中 l=nl1,nl2,,2l = n_l - 1, n_l - 2, \dots, 2

注意,在进行稀疏自编码器的训练过程中,必须要先进行一次前向传播以得到所有神经元的平均激活度 ρ^\hat{\rho}