【論文筆記】Domain Adaptation via Transfer Component Analysis


論文題目:《Domain Adaptation via Transfer Component Analysis》

論文作者:Sinno Jialin Pan, Ivor W. Tsang, James T. Kwok and Qiang Yang

論文鏈接https://www.cse.ust.hk/~qyang/Docs/2009/TCA.pdf

會議期刊:IJCAI 2009 / IEEE Transactions on Neural Networks 2010

簡介

領域自適應(Domain Adaptation)的一個主要問題是如何減少源域和目標域之間的差異.

一個好的特征表示應該盡可能地減少域間分布差異, 同時保持原始數據重要的特性(如幾何/統計特性等).

本文提出一個新的特征提取方式, 叫做遷移成分分析(transfer component analysis, TCA).

TCA學習所有域的公共遷移成分(即不會引起域間分布變化保持原始數據固有結構的成分), 使得不同域在投影后的子空間中分布差異減少.

預備知識

問題設定

源域(source domain)中有帶標簽數據 \(\mathcal{D}_{S}\), 目標域(target domain)中只有大量無標簽數據 \(\mathcal{D}_{T}\).

  • \(\mathcal{D}_{S}=\left\{\left(x_{S_{1}}, y_{S_{1}}\right), \ldots,\left(x_{S_{n}}, y_{S_{n}}\right)\right\}\), \(x_{S_{i}} \in \mathcal{X}\) 為輸入數據, \(y_{S_{i}} \in \mathcal{Y}\)為對應的標簽.

  • \(\mathcal{D}_{T}=\left\{x_{T_{1}}, \ldots, x_{T_{n_{2}}}\right\}\), \(x_{T_{i}} \in \mathcal{X}\).

  • \(\mathcal{P(X_{S})}\)\(\mathcal{Q(X_{T})}\) 分別為 \(X_S\)\(X_T\) 的邊緣分布.

設定: 邊緣分布不同 \(\mathcal{P} \ne \mathcal{Q}\), 但類條件概率分布相同 \(P(Y_{S} | X_{S}) = P(Y_{T} | X_{T})\).

任務: 在目標域中預測輸入數據 \(x_{T_{i}}\) 對應的標簽 \(y_{T_{i}}\).

最大均值差異

我們知道, 存在很多准則可以度量不同分布之間的差異, 如, KL散度等.

但這些方法通常都需要對分布的概率密度進行估計, 因而是參數化的方法. 為了避免引入額外的參數, 我們希望尋找一種非參數化的方法來度量分布的差異.

在2006年, Borgwardt等人[1]提出了一種基於再生核希爾伯特空間(Reproducing Kernel Hilbert Space, RKHS)的分布度量准則 最大均值差異(Maximum Mean Discrepancy, MMD).

\(X = \{ x_1, \cdots, x_{n1}\}\)\(Y = \{ y_1, \cdots, y_{n2}\}\) 為兩個分布 \(\mathcal{P}\)\(\mathcal{Q}\) 的隨機變量集合, 根據MMD的定義, 兩個分布的經驗估計距離為:

\[\operatorname{Dist}(\mathrm{X}, \mathrm{Y})=\left\|\frac{1}{n_{1}} \sum_{i=1}^{n_{1}} \phi\left(x_{i}\right)-\frac{1}{n_{2}} \sum_{i=1}^{n_{2}} \phi\left(y_{i}\right)\right\|_{\mathcal{H}} \tag{1} \]

其中, \(\mathcal{H}\) 是再生核希爾伯特空間, \(\phi : \mathcal{X} \to \mathcal{H}\) 為核函數映射.

遷移成分分析

\(\phi : \mathcal{X} \to \mathcal{H}\) 為非線性映射, \(X^{\prime}_{S} = \{ x^{\prime}_{S_{i}} \} = \{ \phi(x_{S_{i}}) \}\), \(X^{\prime}_{T} = \{ x^{\prime}_{T_{i}} \} = \{ \phi(x_{T_{i}}) \}\), \(X^{\prime} = X^{\prime}_{S} \cup X^{\prime}_{T}\) 分別為源域/目標域/結合域映射后的數據.

我們希望找到這樣一個映射, 使得映射后的數據分布一致, 即 \(\mathcal{P^{\prime}}(X^{\prime}_{S}) = \mathcal{Q^{\prime}}(X^{\prime}_{T})\).

根據MMD的定義, 我們可以通過度量兩個域之間的經驗均值的距離平方作為分布的距離.

\[\operatorname{Dist}\left(X_{S}^{\prime}, X_{T}^{\prime}\right)=\left\|\frac{1}{n_{1}} \sum_{i=1}^{n_{1}} \phi\left(x_{S_{i}}\right)-\frac{1}{n_{2}} \sum_{i=1}^{n_{2}} \phi\left(x_{T_{i}}\right)\right\|_{\mathcal{H}}^{2} \tag{2} \]

通過最小化公式\((2)\), 我們可以找到想要的非線性映射 \(\phi\).

然而, 對公式\((2)\)直接優化是十分困難的, 通常會陷入局部極值點. 因此, 必須另辟蹊徑.

核學習

為了避免顯式地直接尋找非線性變換 \(\phi\), Pan等人[2]將該問題轉化為核學習(kernel learning)問題.

通過利用核技巧 \(k(x_i, x_j) = \phi(x_i)^{\prime}\phi(x_j)\), 公式\((2)\)中兩個域之間的經驗均值距離可以被寫為:

\[\begin{aligned} \operatorname{Dist}\left(X_{S}^{\prime}, X_{T}^{\prime}\right) &= \frac{1}{n^{2}_{1}} \sum_{i=1}^{n_1} \sum_{j=1}^{n_1} k\left(x_{S_i}, x_{S_j}\right)+\frac{1}{n^{2}_{2}} \sum_{i=1}^{n_2} \sum_{j=1}^{n_2} k\left(x_{T_i}, x_{T_j}\right)-\frac{2}{n_1 n_2} \sum_{i=1}^{n_1} \sum_{j=1}^{n_2} k\left(x_{S_i}, x_{T_j}\right) \\ &= \operatorname{tr}(K L) \\ \end{aligned} \tag{3} \]

其中,

\[K=\left[ \begin{array}{ll}{K_{S, S}} & {K_{S, T}} \\ {K_{T, S}} & {K_{T, T}}\end{array}\right] \tag{4} \]

\((n_1 + n_2) \times (n_1 + n_2)\) 大小的核矩陣, \(K_{S,S}\), \(K_{T,T}\), \(K_{S,T}\) 分別為由 \(k\) 定義在源域/目標域/跨域的核矩陣.

\(L = [ L_{ij} ] \succeq 0\) 為半正定矩陣, 其中

\[l_{i j}=\left\{\begin{array}{ll}{\frac{1}{n_{1}^{2}}} & {x_{i}, x_{j} \in \mathcal{D}_{s}} \\ {\frac{1}{n_{2}^{2}}} & {x_{i}, x_{j} \in \mathcal{D}_{t}} \\ {-\frac{1}{n_{1} n_{2}}} & {\text { otherwise }}\end{array}\right. \tag{5} \]

在直推學習的設置下(直推學習即假設未標記的數據就是最終要用來測試的數據, 學習的目的即為在這些數據上取得最佳泛化能力), 核函數 \(k(\cdot, \cdot)\) 可以通過求解核矩陣 \(K\) 替代.

Pan等人[2:1]將核矩陣學習問題形式化為半定規划(semi-definite program, SDP)問題. 然后, 對學習到的核矩陣使用PCA方法得到跨域的低維隱空間.

參數化核映射

MMDE[2:2]的方法存在如下局限性:

  • 它是直推式的, 不能泛化到未見的樣本中
  • 公式\((3)\)中的\(K\)需要是半正定的, 且求解SDP問題十分耗時
  • 為了構造低維表示, 需要對\(K\)進行PCA處理, 這會損失\(K\)中的信息

本文提出一種基於核特征提取來尋找非線性映射 \(\phi\) 的高效方法.

  • 避免求解SDP問題, 減輕計算負擔
  • 學習到的核函數\(k\)可以泛化到未見的樣本
  • 利用顯式的低秩表示得到統一的核學習方法

首先, 公式\((4)\)中的核矩陣 \(K\) 可以被分解為 \(K = (KK^{-1/2})(K^{-1/2}K)\), 這通常稱為經驗核映射(empirical kernel map)[3].

★注: 這個分解可由矩陣的特征分解得到, 即令 \(K = Q^{-1}\Lambda Q\) 代入.
至於為什么要對核矩陣 \(K\) 進行分解, 可以這樣理解, 核矩陣給出的是映射后數據的內積, 即 \(K_{ij} = k(x_i, x_j)\), 但我們只想知道映射后的數據 \(\phi(x)\) 該怎么辦? 便可以將矩陣分解成 \(K=A^TA\) 的形式, 使得 \(A = [ \phi(x_1), \cdots, \phi(x_{n_1 + n_2}) ]\), 即 \(A\) 中的每個元素都是映射后的數據.
在上述的分解中, \(A\) 即為 \(K^{-1/2}K\). 注意到 \(K\) 為對稱半正定矩陣, 因此 \(A^T = (K^{-1/2}K)^T = KK^{-1/2}\).

考慮使用 \((n_1 + n_2) \times m\) 維的矩陣 \(\widetilde{W}\) 將特征變化到 \(m\) 維空間 (通常 \(m \ll n_1 + n_2\)), 則得到的核矩陣為:

\[\widetilde{K} = (KK^{-1/2}\widetilde{W})(\widetilde{W}^TK^{-1/2}K) = KWW^TK \tag{6} \]

其中, \(W = K^{-1/2}\widetilde{W} \in \mathbb{R}^{(n_1 + n_2) \times m}\). 特別地, 任意兩個數據 \(x_i\)\(x_j\) 的核函數為:

\[\tilde{k}(x_i, x_j) = k^{T}_{x_i}WW^Tk_{x_j} \tag{7} \]

其中, \(k_x = [ k(x_1, x), \cdots, k(x_{n_1 + n_2}, x)]^T \in \mathbb{R}^{n_1 + n_2}\). 因此, 公式\((7)\)中的核函數給出了未見樣本的參數化核估計表示.

此外, 根據公式\((6)\)\(\widetilde{K}\)的定義, 兩個域之間的經驗均值距離可重新寫為:

\[\begin{aligned} \operatorname{Dist}\left(X_{S}^{\prime}, X_{T}^{\prime}\right) &=\operatorname{tr}\left(\left(K W W^{\top} K\right) L\right) \\ &=\operatorname{tr}\left(W^{\top} K L K W\right) \\ & {\scriptsize //利用跡循環性質:tr(ABC)=tr(BCA)=tr(CAB)} \end{aligned} \tag{8} \]

遷移成分提取

在最小化公式\((8)\)的時候, 通常需要加一個正則項 \(tr(W^TW)\) (即矩陣二范數 \(\Vert W \Vert_{2}\))來控制參數 \(W\) 的復雜度.

從而, 領域自適應的核學習問題可變為:

\[\begin{array}{cl} {\min \limits_{W}} & {\operatorname{tr}\left(W^{\top} W\right)+\mu \operatorname{tr}\left(W^{\top} K L K W\right)} \\ {\text { s.t. }} & {W^{\top} K H K W=I} \end{array} \tag{9} \]

其中, \(\mu\) 為權衡參數, \(I \in \mathbb{R}^{m \times m}\) 為單位陣, \(H = I_{n_1 + n_2} - \frac{1}{n_1 + n_2} \mathrm{1}\mathrm{1}^T\)中心矩陣(centering matrix), \(\mathrm{1} \in \mathbb{R}^{n_1 + n_2}\) 為全1列向量, \(I_{n_1 + n_2} \in \mathbb{R}^{(n_1 + n_2) \times (n_1 + n_)}\) 為單位陣.

★注: 添加 \(W^{\top} K H K W=I\) 限制條件一方面是為了避免平凡解(即\(W = 0\)), 另一方面是為了保持數據的散度(\(W^{\top} K H K W\)為投影后數據\(W^{\top} K\)的散度矩陣), 即前面簡介中所說的保持原始數據固有結構.

盡管公式\((9)\)為非凸優化問題, 但其可以轉化為跡優化問題:

\[\min _{W} \operatorname{tr}\left(\left(W^{\top} K H K W\right)^{\dagger} W^{\top}(I+\mu K L K) W\right) \tag{10} \]

或者

\[\max _{W} \operatorname{tr}\left(\left(W^{\top}(I+\mu K L K) W\right)^{-1} W^{\top} K H K W\right) \tag{11} \]

上述轉化可由拉格朗日乘子法得到, 具體證明略...

類似於核Fisher判別, 公式\((11)\)\(W\) 的解為 \((I + \mu KLK)^{-1}KHK\) 的前 \(m\) 個特征值對應的特征向量.

因此, 本文提出的方法命名為遷移成分分析(Transfer Component Analysis, TCA).

實驗結果

toy dataset

(左) toy dataset   (中) PCA   (右) TCA

跨域WiFi定位

跨域文本分類

代碼

via: jindongwang/transferlearning

# encoding=utf-8
"""
    Created on 21:29 2018/11/12 
    @author: Jindong Wang
"""
import numpy as np
import scipy.io
import scipy.linalg
import sklearn.metrics
import sklearn.neighbors


def kernel(ker, X, X2, gamma):
    if not ker or ker == 'primal':
        return X
    elif ker == 'linear':
        if not X2:
            K = np.dot(X.T, X)
        else:
            K = np.dot(X.T, X2)
    elif ker == 'rbf':
        n1sq = np.sum(X ** 2, axis=0)
        n1 = X.shape[1]
        if not X2:
            D = (np.ones((n1, 1)) * n1sq).T + \
            np.ones((n1, 1)) * n1sq - 2 * np.dot(X.T, X)
        else:
            n2sq = np.sum(X2 ** 2, axis=0)
            n2 = X2.shape[1]
            D = (np.ones((n2, 1)) * n1sq).T + \
            np.ones((n1, 1)) * n2sq - 2 * np.dot(X.T, X)
        K = np.exp(-gamma * D)
    elif ker == 'sam':
        if not X2:
            D = np.dot(X.T, X)
        else:
            D = np.dot(X.T, X2)
        K = np.exp(-gamma * np.arccos(D) ** 2)
    return K


class TCA:
    def __init__(self, kernel_type='primal', dim=30, lamb=1, gamma=1):
        '''
        Init func
        :param kernel_type: kernel, values: 'primal' | 'linear' | 'rbf' | 'sam'
        :param dim: dimension after transfer
        :param lamb: lambda value in equation
        :param gamma: kernel bandwidth for rbf kernel
        '''
        self.kernel_type = kernel_type
        self.dim = dim
        self.lamb = lamb
        self.gamma = gamma

    def fit(self, Xs, Xt):
        '''
        Transform Xs and Xt
        :param Xs: ns * n_feature, source feature
        :param Xt: nt * n_feature, target feature
        :return: Xs_new and Xt_new after TCA
        '''
        X = np.hstack((Xs.T, Xt.T))
        X /= np.linalg.norm(X, axis=0)
        m, n = X.shape
        ns, nt = len(Xs), len(Xt)
        e = np.vstack((1 / ns * np.ones((ns, 1)), -1 / nt * np.ones((nt, 1))))
        M = e * e.T
        M = M / np.linalg.norm(M, 'fro')
        H = np.eye(n) - 1 / n * np.ones((n, n))
        K = kernel(self.kernel_type, X, None, gamma=self.gamma)
        n_eye = m if self.kernel_type == 'primal' else n
        a, b = np.linalg.multi_dot([K, M, K.T]) + self.lamb * \
               np.eye(n_eye), np.linalg.multi_dot([K, H, K.T])
        w, V = scipy.linalg.eig(a, b)
        ind = np.argsort(w)
        A = V[:, ind[:self.dim]]
        Z = np.dot(A.T, K)
        Z /= np.linalg.norm(Z, axis=0)
        Xs_new, Xt_new = Z[:, :ns].T, Z[:, ns:].T
        return Xs_new, Xt_new

    def fit_predict(self, Xs, Ys, Xt, Yt):
        '''
        Transform Xs and Xt, then make predictions on target using 1NN
        :param Xs: ns * n_feature, source feature
        :param Ys: ns * 1, source label
        :param Xt: nt * n_feature, target feature
        :param Yt: nt * 1, target label
        :return: Accuracy and predicted_labels on the target domain
        '''
        Xs_new, Xt_new = self.fit(Xs, Xt)
        clf = sklearn.neighbors.KNeighborsClassifier(n_neighbors=1)
        clf.fit(Xs_new, Ys.ravel())
        y_pred = clf.predict(Xt_new)
        acc = sklearn.metrics.accuracy_score(Yt, y_pred)
        return acc, y_pred


if __name__ == '__main__':
    domains = ['caltech.mat', 'amazon.mat', 'webcam.mat', 'dslr.mat']
    for i in range(4):
        for j in range(4):
            if i != j:
                src, tar = 'data/' + domains[i], 'data/' + domains[j]
                src_domain, tar_domain = scipy.io.loadmat(src), scipy.io.loadmat(tar)
                Xs, Ys, Xt, Yt = src_domain['feas'], src_domain['label'], \
                                 tar_domain['feas'], tar_domain['label']
                tca = TCA(kernel_type='primal', dim=30, lamb=1, gamma=1)
                acc, ypre = tca.fit_predict(Xs, Ys, Xt, Yt)
                print(acc)

參考文獻


  1. Karsten M. Borgwardt, Arthur Gretton, Malte J. Rasch, Hans-Peter Kriegel, Bernhard Scholkopf, and Alexander J. Smola. Integrating structured biological data by kernel maximum mean discrepancy. In ISMB, pages 49–57, Fortaleza, Brazil, 2006 ↩︎

  2. Sinno Jialin Pan, James T. Kwok, and Qiang Yang. Transfer learning via dimensionality reduction. In Proceedings of AAAI, pages 677–682, Chicago, Illinois, USA, 2008. ↩︎ ↩︎ ↩︎

  3. Bernhard Scholkopf, Alexander Smola, and Klaus-Robert Muller. Nonlinear component analysis as a kernel eigenvalue problem. Neural Computation, 10(5):1299–1319,1998. ↩︎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM