领域自适应(Domain Adaptation)是迁移学习(Transfer Learning)的一个子领域,在计算机视觉里面较为常见。Domain Adaptation的实现有很多种,在深度学习未火热之前,主要有基于样本(Instance-based)的迁移、基于特征(Feature-based)的迁移以及基于参数(Parameter-based)的迁移。其中基于特征的迁移包括子空间对齐(Subspace Alignment)以及最小化分布距离比如MMD等方法。本文介绍基于自编码器(Auto Encoder)的方法。

Auto Encoder目前有很多变种,其中最为知名的是Denoising Auto Encoder和Variational Auto Encoder,分别简称为DAE和VAE,在2014年之前基本都是基于DAE的相关工作。本文围绕两篇关于Auto Encoder来做Domain Adaptation的论文来介绍。分别是:

Xavier Glorot, et al. Domain Adaptation for Large-Scale Sentiment Classi cation: A Deep Learning Approach. ICML 2011.

Minmin Chen, et al. Marginalized Denoising Autoencoders for Domain Adaptation. ICML 2012.

A

在第一篇工作里面,主要有以下几个点值得学习的地方:

  1. 为什么可以使用Auto Encoder来做Domain Adaptation?
  2. 衡量迁移性能的指标?

下面来看第一个问题,为什么可以使用Auto Encoder来做Domain Adaptation。首先,回顾一下什么是Domain Adaptation。在机器学习的经典假设中,测试集的数据和训练集的数据是同分布采样得到的,然而实际问题中往往存在分布变化的情况,比如在2010年训练的情感识别(Sentiment Classification)模型不能直接用于2012年的数据,因为随著时间的变化会出现很多热点词语;在电商领域,不同商品评论的情感表达不一样,比如在厨房家电商品中常用的情感词为「耐用」、「可靠」等,在DVD商品的评论里面常用的情感词为「好看」、「恐怖」等等,因此在不同商品对应的评价数据上训练的模型不能直接互相使用。

用一张图展示Domain Adaptation,如下图。在分布未对齐之前(左边),在源领域(Source Domain)有一个二分类问题,用红色表示,在目标领域(Target Domain)则是另外一种分布,用蓝色表示,在SD上训练的分类器(虚线代表分类边界)并不适用于TD。但是经过对齐之后,两个数据之间的分布有了一定的对齐,此时Source和Target可以认为是同一分布采样的数据,那么在SD上训练的模型自然可以直接应用到TD,对应的是右边的图。

怎么样将分布对齐呢?有很多种方法,比如基于某个线性/非线性映射之后数据在同一空间的某个距离(比如MMD)最小。这里采用基于Auto Encoder的方法,本质上是通过非线性降维,使得源域和目标域的数据分布在同一个子空间里面。

文章中使用的是Denoising Auto Encoder,简称DAE,其数学形式为最小化:

lleft(x, g_{phi}(h_{	heta}(	ilde{x}))
ight)

其中 	ilde{x} 是经过杂讯影响的数据,比如随机将一张图片中的某些元素置为零或者加高斯杂讯等等; h_{	heta} 是Encoder,其中有非线性激活函数,比如Tanh, Sigmoid, ReLU, LeakyReLU, Softplus等等; g_{phi} 是Decoder,将低维表示重构。损失函数可以采用MSE等等,最小化重构误差。

那么回到第一个问题,为什么Auto Encoder可以用来做Domain Adaptation?

首先,从Deep Learning的角度出发,深度学习的本质是学习特征,并且是有用的特征,如文章中解释,是:Intermediate concepts, Invariant properties, Underlying factors。其次,由于目标域上是无标签的,所以希望采用Unsupervised Deep Learning的方法来学习表示,那么最为常用的就是Auto Encoder。DAE在大量无标签的源域和目标域数据上进行学习低维表示,可以学习到一些潜在因子(Underlying factors),比如在商品评论中学习到「商品价值」、「服务质量」、「商品价格」等等潜在因素,这些因素在各种商品中都是通用的(Invariant properties)。因此对于厨房家电的评论数据和DVD的评论数据可能学习到如下的映射关系:

厨房家电:「可靠」、「耐用」 --> 商品质量好

DVD : 「好看」、「演技好」--> 商品质量好

那么,可以认为Source和Target在Auto Encoder的低维空间中分布对齐。具体做法是:将厨房家电的数据和DVD的数据放在一起无监督地使用Auto Encoder降维,得到对应的低维表示,然后在厨房家电的评论数据集上训练的模型就可以拿到DVD的评论数据上预测(模型建立在低维表示上)。

第二个问题,如何定义使用迁移之后的好坏?文中先定义了三种error,分别是:

  • Transfer error e(S, T) :在Source上训练的模型到Target上的error
  • In-domain error e(T, T) : 在Target上训练的模型在自身上的error
  • Baseline In-domain error e_b(T, T) : 在Target上使用Baseline模型训练得到的error

那么对于是否迁移,需要比较上面三者的关系,定义了Transfer ratio和In-domain ratio两个指标:

  • Transfer ratio : mathcal{Q} = frac{1}{n}sum_{S,T}frac{e(S, T)}{e_b(T, T)}
  • In-domain ratio : mathcal{I} = frac{1}{m}sum_S frac{e(T, T)}{e_b(T, T)}

主要评价指标是Transfer ratio,如果Transfer ratio越小,则说明在迁移之后目标域Target上的error越小,因此迁移演算法的性能越好。In-domain ratio是为了衡量相比较于baseline演算法,使用其余演算法带来的提升,没有涉及迁移,但是可以考虑不同演算法带来的影响。

总结这篇文章,就是使用了Stacked Denoising Auto Encoder引入了非线性降维,将Source和Target的数据映射到同一子空间,提取共同的特征,然后训练测试。

B

在下一篇文章中,介绍的是Marginalized DAE在迁移里面的应用,上一篇工作里面是基于Stacked DAE,需要层级训练,过程比较麻烦。但是在这篇工作中,作者提出了mSDA,主要是引入了Denoising Auto Encoder的闭式解,从而使得代码非常简介。

首先回顾一下DAE的工作方式,最小化下面的损失:

lleft(x, g_{phi}(h_{	heta}(	ilde{x}))
ight)

如果将 g_{phi}circ f_{	heta} 用一个线性层简化,并且采用MSE作为损失函数,那么得到的就是下面的优化目标:

min Vert x - W	ilde{x} Vert^2

下面引入偏置bias,即 x = [x; 1]W = [W, b] ,那么优化目标是下面的式子,i 是样本的index:

min frac{1}{2n} sum_{i=1}^n Vert x_i - W	ilde{x}_i Vert^2 \

对于 	ilde{x}_i 的实现方式是随机Mask掉一部分,每个元素按照概率 p 的可能性被设置为0。重复m次这样的随机策略,可以得到 m 次的优化目标:

min frac{1}{2mn} sum_{j=1}^m sum_{i=1}^n Vert x_i - W	ilde{x}_{i,j} Vert^2 \

为了分析方便,记 X = [x_1, x_2, cdots, x_n] in R^{d	imes n} ,每一列是一个样本,记 	ilde{X} = [	ilde{x}_1, 	ilde{x}_2, cdots, 	ilde{x}_n ] in R^{d 	imes n} 为相应的Corrupted的数据,那么随机一次的优化目标的矩阵形式为:

min_W frac{1}{2n} Trleft( (X - W	ilde{X})^T(X - W	ilde{X})
ight)

上式有闭式解,得到:

W = PQ^{-1}, Q = 	ilde{X}	ilde{X}^T, P = X	ilde{X}^T

当重复了 m 次之后,需要将矩阵扩充得到: X = [X, X, cdots, X] in R^{md 	imes n} ,以及 	ilde{X} = [	ilde{X}_1, 	ilde{X}_2, cdots, 	ilde{X}_m] in R^{md	imes n} ,然后按照上面的 Q, P 计算得到 W 。但是这样做具有随机性,不同的 m 得到的结果可能不一样,即便是同样大小的 m,也因为随机的Corrupt导致结果不一样,所以作者就取 m 
ightarrow infty ,此时得到的就是:

W = E[P]E[Q]^{-1}

S = XX^T ,根据概率计算可以得到下面的结果(具体参考论文,很简单),其中 q = [1-p, 1-p, cdots, 1-p, 1] in R^{d + 1} ,即 x 中除了偏置bias不corrupt之外,其余元素均以p的概率被设置为0,保留下来的概率就是 1 - p:

E[P]_{ij} = S_{ij}q_j

E[Q]_{ij} = S_{ij}q_i q_j, i 
eq j \ E[Q]_{ii} = S_{ii}q_i

最后贴上Matlab的伪代码:

使用Python改写的代码为:

#-*- coding : utf-8 -*-

"""
Refer paper:
Marginalized Denoising AutoEncoder for Domain Adaptation. ICML 2012.
"""

import copy
import numpy as np

class TransferMSDA():
def __init__(self, n_layers = 2, prob = 0.1, activation = "tanh"):
self.n_layers = n_layers
self.prob = prob
self.activation = "tanh"

def fit(self, SX, TX):
""" SX.shape = (ns, d)
TX.shape = (nt, d)
"""
# n = ns + nd
ns, nt = SX.shape[0], TX.shape[0]
n = ns + nt

SX, TX = copy.deepcopy(SX), copy.deepcopy(TX)
X = np.concatenate([SX, TX], axis = 0) # (n, d)
X = np.concatenate([X, np.ones((n, 1))], axis = 1) # (n, d + 1)

for l in range(self.n_layers):
X = self.mda(X)

SX = X[0 : ns]
TX = X[ns :]
return SX, TX

def mda(self, X):
""" X.shape = (n, d)
"""
X = copy.deepcopy(X)
n, d = X.shape

q = np.ones(d)
q[0 : d - 1] = 1 - self.prob

S = np.dot(X.transpose(), X) # (d, d)

# Q_ij = S_ij * q_i * q_j if i neq j
# Q_ii = S_ii * q_i
Q = S * np.dot(q.reshape((-1, 1)), q.reshape((1, -1))) # (d, d)
np.fill_diagonal(Q, q * np.diag(S))

# P_ij = S_ij * q_j
P = S * np.tile(q, (d, 1))

# W = PQ^{-1}
W = np.dot(P, np.linalg.inv(Q + 1e-5 * np.eye(d)))

# h = tanh(W * x)
if self.activation == "tanh":
h = np.tanh(np.dot(X, W))
elif self.activation == "sigmoid":
h = np.dot(X, W)
h = 1.0 / (1.0 + np.exp(-1.0 * h))
elif self.activation == "relu":
h = np.max(0, np.dot(X, W))
else:
raise ValueError("No such activation function")

return h

总结一下这篇文章的工作,主要体现在Marginalized上面,即将随机杂讯对图片进行Corrupt的过程利用期望积分掉了。文章数学形式很优美,演算法很简单,代码只有几十行,并且实验验证效果还不错。

推荐阅读:

相关文章