├── _config.yml ├── png ├── tf.png ├── tf2.png ├── matlab.png └── domain _adaptation.png ├── code ├── TCA_python │ ├── da_tool │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── tca.cpython-35.pyc │ │ │ └── __init__.cpython-35.pyc │ │ └── tca.py │ ├── readme.md │ └── test.py ├── MyCORAL.m ├── MyGFK.m ├── README.md ├── MyTCA.m ├── MyARTL │ ├── MyARTL.m │ └── lapgraph.m ├── MyTJM.m ├── MyJDA.m └── MyJGSA.m ├── doc ├── 迁移学习简介.md ├── domain_adaptation.md └── dataset.md └── README.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /png/tf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/png/tf.png -------------------------------------------------------------------------------- /png/tf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/png/tf2.png -------------------------------------------------------------------------------- /png/matlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/png/matlab.png -------------------------------------------------------------------------------- /png/domain _adaptation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/png/domain _adaptation.png -------------------------------------------------------------------------------- /code/TCA_python/da_tool/__init__.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | """ 3 | Created on 17:22 2017/5/1 4 | @author: Jindong Wang 5 | """ 6 | 7 | -------------------------------------------------------------------------------- /code/TCA_python/da_tool/__pycache__/tca.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/code/TCA_python/da_tool/__pycache__/tca.cpython-35.pyc -------------------------------------------------------------------------------- /code/TCA_python/da_tool/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wantingallin/transferlearning/HEAD/code/TCA_python/da_tool/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /code/MyCORAL.m: -------------------------------------------------------------------------------- 1 | function [Xs_new] = MyCORAL(Xs,Xt) 2 | % Inputs: 3 | %%% Xs:source domain feature matrix, ns * m 4 | %%% Xt:target domain feature matrix, nt * m 5 | % Output: 6 | %%% Xs_new:transformed new source domain matrix, ns * m 7 | 8 | cov_src = cov(Xs) + eye(size(Xs,2)); 9 | cov_tar = cov(Xt) + eye(size(Xt,2)); 10 | A_coral = cov_src^(-1/2) * cov_tar^(1/2); 11 | Xs_new = Xs * A_coral; 12 | end -------------------------------------------------------------------------------- /code/TCA_python/readme.md: -------------------------------------------------------------------------------- 1 | ### Python版的迁移学习代码 2 | 3 | - - - 4 | 5 | #### TCA(Transfer component analysis) 6 | 7 | 算法出处:Pan S J, Tsang I W, Kwok J T, et al. Domain adaptation via transfer component analysis[J]. IEEE Transactions on Neural Networks, 2011, 22(2): 199-210. 8 | 9 | 用法: 10 | 11 | import da_tool.tca 12 | 13 | ```python 14 | my_tca = da_tool.tca.TCA(dim=30,kerneltype='rbf', kernelparam=1, mu=1) 15 | x_src_tca, x_tar_tca, x_tar_o_tca = my_tca.fit_transform(x_src, x_tar) 16 | ``` 17 | 18 | 测试请见test.py文件。 19 | 20 | - - - 21 | 22 | ### 未来增加的算法: 23 | 24 | #### GFK (Geodesic flow kernel) 25 | 等等。 -------------------------------------------------------------------------------- /code/TCA_python/test.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | """ 3 | Created on 17:22 2017/5/1 4 | @author: Jindong Wang 5 | """ 6 | 7 | import da_tool.tca 8 | import numpy as np 9 | 10 | file_path = 'data/test_tca_data.csv' 11 | data = np.loadtxt(file_path, delimiter=',') 12 | x_src = data[:, :81] 13 | x_tar = data[:, 81:] 14 | 15 | # example usage of TCA 16 | my_tca = da_tool.tca.TCA(dim=30,kerneltype='rbf', kernelparam=1, mu=1) 17 | x_src_tca, x_tar_tca, x_tar_o_tca = my_tca.fit_transform(x_src, x_tar) 18 | np.savetxt('x_src1.csv', x_src_tca, delimiter=',', fmt='%.6f') 19 | np.savetxt('x_tar1.csv', x_tar_tca, delimiter=',', fmt='%.6f') -------------------------------------------------------------------------------- /doc/迁移学习简介.md: -------------------------------------------------------------------------------- 1 | ### 迁移学习简介 2 | 3 | 迁移学习(transfer learning)通俗来讲,就是运用已有的知识来学习新的知识,核心是找到已有知识和新知识之间的相似性,用成语来说就是举一反三。由于直接对目标域从头开始学习成本太高,我们故而转向运用已有的相关知识来辅助尽快地学习新知识。比如,已经会下中国象棋,就可以类比着来学习国际象棋;已经会编写Java程序,就可以类比着来学习C#;已经学会英语,就可以类比着来学习法语;等等。世间万事万物皆有共性,如何合理地找寻它们之间的相似性,进而利用这个桥梁来帮助学习新知识,是迁移学习的核心问题。 4 | 5 | ![图1不同位置、不同传感器的迁移标定。已知一个房间中A点的WiFi信号与相应的人体行为,如何标定另一个房间中C点的蓝牙信号?](https://raw.githubusercontent.com/jindongwang/transferlearning/master/png/tf.png) 6 | 7 | 图1不同位置、不同传感器的迁移标定。已知一个房间中A点的WiFi信号与相应的人体行为,如何标定另一个房间中C点的蓝牙信号? 8 | 9 | 具体地,在迁移学习中,我们已有的知识叫做源域(source domain),要学习的新知识叫目标域(target domain)。迁移学习研究如何把源域的知识迁移到目标域上。特别地,在机器学习领域中,迁移学习研究如何将已有模型应用到新的不同的、但是有一定关联的领域中。传统机器学习在应对数据的分布、维度,以及模型的输出变化等任务时,模型不够灵活、结果不够好,而迁移学习放松了这些假设。在数据分布、特征维度以及模型输出变化条件下,有机地利用源域中的知识来对目标域更好地建模。另外,在有标定数据缺乏的情况下,迁移学习可以很好地利用相关领域有标定的数据完成数据的标定。 10 | 11 | ![](https://raw.githubusercontent.com/jindongwang/transferlearning/master/png/tf2.png) 12 | 13 | 图2 迁移学习与传统机器学习的不同。(a)传统机器学习对不同的学习任务建立不同的模型,(b)迁移学习利用源域中的数据将知识迁移到目标域,完成模型建立。插图来自:Sinno Jialin Pan and Qiang Yang, A survey on transfer learning. IEEE TKDE 2010. 14 | 15 | 迁移学习按照学习方式可以分为基于样本的迁移,基于特征的迁移,基于模型的迁移,以及基于关系的迁移。基于样本的迁移通过对源域中有标定样本的加权利用完成知识迁移;基于特征的迁移通过将源域和目标域映射到相同的空间(或者将其中之一映射到另一个的空间中)并最小化源域和目标域的距离来完成知识迁移;基于模型的迁移将源域和目标域的模型与样本结合起来调整模型的参数;基于关系的迁移则通过在源域中学习概念之间的关系,然后将其类比到目标域中,完成知识的迁移。 16 | 17 | 理论上,任何领域之间都可以做迁移学习。但是,如果源域和目标域之间相似度不够,迁移结果并不会理想,出现所谓的负迁移情况。比如,一个人会骑自行车,就可以类比学电动车;但是如果类比着学开汽车,那就有点天方夜谭了。如何找到相似度尽可能高的源域和目标域,是整个迁移过程最重要的前提。 18 | 19 | 迁移学习方面,代表人物有香港科技大学的Qiang Yang教授,南洋理工大学的Sinno Jialin Pan,以及第四范式的CEO戴文渊等。代表文献是Sinno Jialin Pan和Qiang Yang的A survey on transfer learning。 20 | 21 | 作者网站:http://jd92.wang. 22 | 23 | [参考资料] 24 | 25 | [1] Pan S J, Yang Q. A survey on transfer learning[J]. IEEE Transactions on knowledge and data engineering, 2010, 22(10): 1345-1359. 26 | 27 | [2] Introduction to Transfer Learning: http://jd92.wang/assets/files/l03_transferlearning.pdf。 28 | 29 | [3] Qiang Yang: http://www.cse.ust.hk/~qyang/. 30 | 31 | [4] Sinno Jialin Pan: http://www.ntu.edu.sg/home/sinnopan/. 32 | 33 | [5] Wenyuan Dai: https://scholar.google.com/citations?user=AGR9pP0AAAAJ&hl=zh-CN. 34 | 35 | -------------------------------------------------------------------------------- /code/MyGFK.m: -------------------------------------------------------------------------------- 1 | function [acc,G] = MyGFK(X_src,Y_src,X_tar,Y_tar,dim) 2 | % Inputs: 3 | %%% X_src :source feature matrix, ns * m 4 | %%% Y_src :source label vector, ns * 1 5 | %%% X_tar :target feature matrix, nt * m 6 | %%% Y_tar :target label vector, nt * 1 7 | % Outputs: 8 | %%% acc :accuracy after GFK and 1NN 9 | %%% G :geodesic flow kernel matrix 10 | 11 | Ps = pca(X_src); 12 | Pt = pca(X_tar); 13 | G = GFK_core([Ps,null(Ps')], Pt(:,1:dim)); 14 | [~, acc] = my_kernel_knn(G, X_src, Y_src, X_tar, Y_tar); 15 | end 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | function [prediction,accuracy] = my_kernel_knn(M, Xr, Yr, Xt, Yt) 19 | dist = repmat(diag(Xr*M*Xr'),1,length(Yt)) ... 20 | + repmat(diag(Xt*M*Xt')',length(Yr),1)... 21 | - 2*Xr*M*Xt'; 22 | [~, minIDX] = min(dist); 23 | prediction = Yr(minIDX); 24 | accuracy = sum( prediction==Yt ) / length(Yt); 25 | end 26 | 27 | function G = GFK_core(Q,Pt) 28 | % Input: Q = [Ps, null(Ps')], where Ps is the source subspace, column-wise orthonormal 29 | % Pt: target subsapce, column-wise orthonormal, D-by-d, d < 0.5*D 30 | % Output: G = \int_{0}^1 \Phi(t)\Phi(t)' dt 31 | 32 | % ref: Geodesic Flow Kernel for Unsupervised Domain Adaptation. 33 | % B. Gong, Y. Shi, F. Sha, and K. Grauman. 34 | % Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR), Providence, RI, June 2012. 35 | 36 | % Contact: Boqing Gong (boqinggo@usc.edu) 37 | 38 | N = size(Q,2); % 39 | dim = size(Pt,2); 40 | 41 | % compute the principal angles 42 | QPt = Q' * Pt; 43 | [V1,V2,V,Gam,Sig] = gsvd(QPt(1:dim,:), QPt(dim+1:end,:)); 44 | V2 = -V2; 45 | theta = real(acos(diag(Gam))); % theta is real in theory. Imaginary part is due to the computation issue. 46 | 47 | % compute the geodesic flow kernel 48 | eps = 1e-20; 49 | B1 = 0.5.*diag(1+sin(2*theta)./2./max(theta,eps)); 50 | B2 = 0.5.*diag((-1+cos(2*theta))./2./max(theta,eps)); 51 | B3 = B2; 52 | B4 = 0.5.*diag(1-sin(2*theta)./2./max(theta,eps)); 53 | G = Q * [V1, zeros(dim,N-dim); zeros(N-dim,dim), V2] ... 54 | * [B1,B2,zeros(dim,N-2*dim);B3,B4,zeros(dim,N-2*dim);zeros(N-2*dim,N)]... 55 | * [V1, zeros(dim,N-dim); zeros(N-dim,dim), V2]' * Q'; 56 | end -------------------------------------------------------------------------------- /code/README.md: -------------------------------------------------------------------------------- 1 | # code_transfer_learning 2 | 3 | *Transfer learning toolbox; some useful transfer learning and domain adaptation codes* 4 | 5 | > It is a waste of time looking for the codes from others. So I **clean** and **reimplement** them here in a way that you can **easily understand** and use. The following are some of the popular transfer learning (domain adaptation) methods in recent years, and I know most of them will be chosen to compare with your own method. 6 | > It is still **on the go**. You are welcome to contribute and suggest other methods. 7 | 8 | - - - 9 | 10 | ### Availiable codes for: 11 | 12 | - **TCA** (Transfer Component Anaysis)[1] 13 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyTCA.m) | [Python](https://github.com/jindongwang/transferlearning/tree/master/code/TCA_python) 14 | - **GFK** (Geodesic Flow Kernel)[2] 15 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyGFK.m) 16 | - **JDA** (Joint Distribution Adaptation)[3] 17 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyJDA.m) 18 | - **TJM** (Transfer Joint Matching)[4] 19 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyTJM.m) 20 | - **CORAL** (CORrelation ALignment) [5] 21 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyCORAL.m) 22 | - **JGSA** (Joint Geometrical and Statistical Alignment) [6] 23 | - [Matlab](https://github.com/jindongwang/transferlearning/blob/master/code/MyJGSA.m) 24 | - **ARTL** (Adaptation Regularization) [7] 25 | - [Matlab](https://github.com/jindongwang/transferlearning/tree/master/code/MyARTL) 26 | 27 | - - - 28 | 29 | #### [Code from HKUST](http://www.cse.ust.hk/TL/) [a bit old] 30 | 31 | - - - 32 | 33 | Testing **dataset** can be found [here](https://github.com/jindongwang/transferlearning/blob/master/doc/dataset.md). 34 | 35 | - - - 36 | 37 | #### References 38 | 39 | [1] Pan S J, Tsang I W, Kwok J T, et al. Domain adaptation via transfer component analysis[J]. IEEE Transactions on Neural Networks, 2011, 22(2): 199-210. 40 | 41 | [2] Gong B, Shi Y, Sha F, et al. Geodesic flow kernel for unsupervised domain adaptation[C]//Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on. IEEE, 2012: 2066-2073. 42 | 43 | [3] Long M, Wang J, Ding G, et al. Transfer feature learning with joint distribution adaptation[C]//Proceedings of the IEEE international conference on computer vision. 2013: 2200-2207. 44 | 45 | [4] Long M, Wang J, Ding G, et al. Transfer joint matching for unsupervised domain adaptation[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2014: 1410-1417. 46 | 47 | [5] Sun B, Feng J, Saenko K. Return of Frustratingly Easy Domain Adaptation[C]//AAAI. 2016, 6(7): 8. 48 | 49 | [6] Zhang J, Li W, Ogunbona P. Joint Geometrical and Statistical Alignment for Visual Domain Adaptation[C]//CVPR 2017. 50 | 51 | [7] Long M, Wang J, Ding G, et al. Adaptation regularization: A general framework for transfer learning[J]. IEEE Transactions on Knowledge and Data Engineering, 2014, 26(5): 1076-1089. 52 | -------------------------------------------------------------------------------- /code/MyTCA.m: -------------------------------------------------------------------------------- 1 | function [X_src_new,X_tar_new,A] = MyTCA(X_src,X_tar,options) 2 | % Inputs: [dim is the dimension of features] 3 | %%% X_src:source feature matrix, ns * dim 4 | %%% X_tar:target feature matrix, nt * dim 5 | %%% options:option struct 6 | % Outputs: 7 | %%% X_src_new:transformed source feature matrix, ns * dim_new 8 | %%% X_tar_new:transformed target feature matrix, nt * dim_new 9 | %%% A: adaptation matrix, (ns + nt) * (ns + nt) 10 | 11 | %% Set options 12 | lambda = options.lambda; %% lambda for the regularization 13 | dim = options.dim; %% dim is the dimension after adaptation 14 | kernel_type = options.kernel_type; %% kernel_type is the kernel name, primal|linear|rbf 15 | gamma = options.gamma; %% gamma is the bandwidth of rbf kernel 16 | 17 | %% Calculate 18 | X = [X_src',X_tar']; 19 | X = X*diag(sparse(1./sqrt(sum(X.^2)))); 20 | [m,n] = size(X); 21 | ns = size(X_src,1); 22 | nt = size(X_tar,1); 23 | e = [1/ns*ones(ns,1);-1/nt*ones(nt,1)]; 24 | M = e * e'; 25 | M = M / norm(M,'fro'); 26 | H = eye(n)-1/(n)*ones(n,n); 27 | if strcmp(kernel_type,'primal') 28 | [A,~] = eigs(X*M*X'+lambda*eye(m),X*H*X',dim,'SM'); 29 | Z = A' * X; 30 | Z = Z * diag(sparse(1./sqrt(sum(Z.^2)))); 31 | X_src_new = Z(:,1:ns)'; 32 | X_tar_new = Z(:,ns+1:end)'; 33 | else 34 | K = TCA_kernel(kernel_type,X,[],gamma); 35 | [A,~] = eigs(K*M*K'+lambda*eye(n),K*H*K',dim,'SM'); 36 | Z = A' * K; 37 | Z = Z*diag(sparse(1./sqrt(sum(Z.^2)))); 38 | X_src_new = Z(:,1:ns)'; 39 | X_tar_new = Z(:,ns+1:end)'; 40 | end 41 | end 42 | 43 | % With Fast Computation of the RBF kernel matrix 44 | % To speed up the computation, we exploit a decomposition of the Euclidean distance (norm) 45 | % 46 | % Inputs: 47 | % ker: 'linear','rbf','sam' 48 | % X: data matrix (features * samples) 49 | % gamma: bandwidth of the RBF/SAM kernel 50 | % Output: 51 | % K: kernel matrix 52 | % 53 | % Gustavo Camps-Valls 54 | % 2006(c) 55 | % Jordi (jordi@uv.es), 2007 56 | % 2007-11: if/then -> switch, and fixed RBF kernel 57 | % Modified by Mingsheng Long 58 | % 2013(c) 59 | % Mingsheng Long (longmingsheng@gmail.com), 2013 60 | function K = TCA_kernel(ker,X,X2,gamma) 61 | 62 | switch ker 63 | case 'linear' 64 | 65 | if isempty(X2) 66 | K = X'*X; 67 | else 68 | K = X'*X2; 69 | end 70 | 71 | case 'rbf' 72 | 73 | n1sq = sum(X.^2,1); 74 | n1 = size(X,2); 75 | 76 | if isempty(X2) 77 | D = (ones(n1,1)*n1sq)' + ones(n1,1)*n1sq -2*X'*X; 78 | else 79 | n2sq = sum(X2.^2,1); 80 | n2 = size(X2,2); 81 | D = (ones(n2,1)*n1sq)' + ones(n1,1)*n2sq -2*X'*X2; 82 | end 83 | K = exp(-gamma*D); 84 | 85 | case 'sam' 86 | 87 | if isempty(X2) 88 | D = X'*X; 89 | else 90 | D = X'*X2; 91 | end 92 | K = exp(-gamma*acos(D).^2); 93 | 94 | otherwise 95 | error(['Unsupported kernel ' ker]) 96 | end 97 | end -------------------------------------------------------------------------------- /doc/domain_adaptation.md: -------------------------------------------------------------------------------- 1 | ### Domain adaptation介绍及代表性文章梳理 2 | 3 | Domain adaptation,DA,中文可翻译为域适配、域匹配、域适应,是迁移学习中的一类非常重要的问题,也是一个持续的研究热点。Domain adaptation可用于计算机视觉、物体识别、文本分类、声音识别等常见应用中。这个问题的基本定义是,假设源域和目标域的类别空间一样,特征空间也一样,但是数据的分布不一样,如何利用有标定的源域数据,来学习目标域数据的标定? 4 | 5 | 事实上,根据目标域中是否有少量的标定可用,可以将domain adaptation大致分为无监督(目标域中完全无label)和半监督(目标域中有少量label)两大类。我们这里偏重介绍无监督。 6 | 7 | [视觉domain adaptation综述](https://mega.nz/#!hWQ3HLhJ!GTCIUTVDcmnn3f7-Ulhjs_MxGv6xnFyp1nayemt9Nis) 8 | 9 | 关于迁移学习的理论方面,有三篇连贯式的理论分析文章连续发表在NIPS和Machine Learning上:[理论分析](https://mega.nz/#F!ULoGFYDK!O3TQRZwrNeqTncNMIfXNTg) 10 | - - - 11 | 12 | #### 形式化 13 | 14 | 给定:有标定的![](https://latex.codecogs.com/png.latex?\mathcal{D}_{S}=\{X_{S_i},Y_{S_i}\}^{n}_{i=1}),以及无标定的![](https://latex.codecogs.com/png.latex?\mathcal{D}_{T}=\{X_{T_i},?\}^{m}_{i=1}) 15 | 16 | 求:![](https://latex.codecogs.com/png.latex?\mathcal{D}_{T})的标定![](https://latex.codecogs.com/png.latex?Y_{T}) (在实验环境中,![](https://latex.codecogs.com/png.latex?\mathcal{D}_{T})是有标定的,仅用来测试算法精度) 17 | 18 | 条件: 19 | - ![](https://latex.codecogs.com/png.latex?X_{S},X_{T}&space;\in&space;\mathbf{R}^{p&space;\times&space;d}),即源域和目标域的特征空间相同(都是![](https://latex.codecogs.com/png.latex?d)维) 20 | - ![](https://latex.codecogs.com/png.latex?\{Y_{S}\}=\{Y_{T}\}),即源域和目标域的类别空间相同 21 | - ![](https://latex.codecogs.com/png.latex?P(X_{S}))![](https://latex.codecogs.com/png.latex?\ne) ![](https://latex.codecogs.com/png.latex?P(X_T)),即源域和目标域的数据分布不同 22 | 23 | - - - 24 | 25 | #### 例子 26 | 27 | 比如说,同样都是一台电脑,在不同角度,不同光照,以及不同背景下拍照,图像的数据具有不同的分布,但是从根本上来说,都是一台电脑的图像。Domain adaptation要做的就是,如何根据这些不同分布的数据,很好地学习缺失的标定。 28 | 29 | ![Domain adaptation](https://raw.githubusercontent.com/jindongwang/transferlearning/master/png/domain%20_adaptation.png) 30 | 31 | - - - 32 | 33 | #### 代表方法与文章 34 | 35 | Domain adaptation可以算是迁移学习领域最火的研究点了。因此,试图来解决此问题的方法层出不穷。从早期的基于实例的迁移、基于模型的迁移,到偏重数学变换的基于特征的迁移,再到如今的深度迁移,诞生了许多经典的DA方法。我们不打算面面俱到,也没有必要。在这里仅列出最经典的那些方法(何为最经典?引用量大且发表会议/刊物级别高),并在之后单独写文章深入介绍每个方法。时间有限,并且为了保证质量,不可能一次做完。 36 | 37 | 代表性的方法及文章: 38 | 39 | - 迁移成分分析方法(Transfer component analysis, TCA) 40 | - [Domain adaptation via tranfer component analysis](https://mega.nz/#!JTwElLrL!j5-TanhHCMESsGBNvY6I_hX6uspsrTxyopw8bPQ2azU) 41 | - 发表在IEEE Trans. Neural Network期刊上(现改名为IEEE trans. Neural Network and Learning System),前作会议文章发在AAAI-09上 42 | - [我的解读](https://zhuanlan.zhihu.com/p/26764147?group_id=844611188275965952) 43 | 44 | - 联合分布适配方法(joint distribution adaptation,JDA) 45 | - [Transfer Feature Learning with Joint Distribution Adaptation](http://ise.thss.tsinghua.edu.cn/~mlong/doc/joint-distribution-adaptation-iccv13.pdf) 46 | - 发表在2013年的ICCV上 47 | - [我的解读](https://zhuanlan.zhihu.com/p/27336930) 48 | 49 | - 测地线流式核方法(Geodesic flow kernel, GFK) 50 | - [Geodesic flow kernel for unsupervised domain adaptation](https://mega.nz/#!tDY1lCSD!flMSgl-0uIswpSFL3sdZgKi6fOyFVLtcO8P6SE0OUPU) 51 | - 发表在CVPR-12上 52 | - [我的解读](https://zhuanlan.zhihu.com/p/27782708) 53 | - 领域不变性迁移核学习(Transfer Kernel Learning, TKL) 54 | - [Domain invariant transfer kernel learning](https://mega.nz/#!tOoCCRhB!YyoorOUcp6XIPPd6A0s7qglYnaSiRJFEQBphtZ2c58Q) 55 | - 发表在IEEE Trans. Knowledge and Data Engineering期刊上 56 | - 深度适配网络(Deep Adaptation Network, DAN) 57 | - 发表在ICML-15上:learning transferable features with deep adaptation networks 58 | - [我的解读](https://zhuanlan.zhihu.com/p/27657910) 59 | 60 | 接下来会继续添加方法,以及开始对每种方法的细致说明 61 | -------------------------------------------------------------------------------- /code/MyARTL/MyARTL.m: -------------------------------------------------------------------------------- 1 | function [acc,acc_ite,Alpha] = MyARTL(X_src,Y_src,X_tar,Y_tar,options) 2 | % Inputs: 3 | %%% X_src :source feature matrix, ns * m 4 | %%% Y_src :source label vector, ns * 1 5 | %%% X_tar :target feature matrix, nt * m 6 | %%% Y_tar :target label vector, nt * 1 7 | %%% options:option struct 8 | % Outputs: 9 | %%% acc :final accuracy using knn, float 10 | %%% acc_ite:list of all accuracies during iterations 11 | %%% A :final adaptation matrix, (ns + nt) * (ns + nt) 12 | 13 | %% Set options 14 | lambda = options.lambda; %% lambda for the regularization 15 | kernel_type = options.kernel_type; %% kernel_type is the kernel name, primal|linear|rbf 16 | T = options.T; %% iteration number 17 | n_neighbor = options.n_neighbor; 18 | sigma = options.sigma; 19 | gamma = options.gamma; 20 | 21 | X = [X_src',X_tar']; 22 | Y = [Y_src;Y_tar]; 23 | X = X*diag(sparse(1./sqrt(sum(X.^2)))); 24 | ns = size(X_src,1); 25 | nt = size(X_tar,1); 26 | nm = ns + nt; 27 | e = [1/ns*ones(ns,1);-1/nt*ones(nt,1)]; 28 | C = length(unique(Y_src)); 29 | E = diag(sparse([ones(ns,1);zeros(nt,1)])); 30 | YY = []; 31 | for c = reshape(unique(Y),1,length(unique(Y))) 32 | YY = [YY,Y==c]; 33 | end 34 | 35 | %% Construct graph laplacian 36 | manifold.k = options.n_neighbor; 37 | manifold.Metric = 'Cosine'; 38 | manifold.NeighborMode = 'KNN'; 39 | manifold.WeightMode = 'Cosine'; 40 | [W,Dw,L] = construct_lapgraph(X',manifold); 41 | %%% M0 42 | M = e * e' * C; %multiply C for better normalization 43 | 44 | acc_ite = []; 45 | Y_tar_pseudo = []; 46 | % If want to include conditional distribution in iteration 1, then open 47 | % this 48 | 49 | % if ~isfield(options,'Yt0') 50 | % % model = train(Y(1:ns),sparse(X(:,1:ns)'),'-s 0 -c 1 -q 1'); 51 | % % [Y_tar_pseudo,~] = predict(Y(ns+1:end),sparse(X(:,ns+1:end)'),model); 52 | % knn_model = fitcknn(X_src,Y_src,'NumNeighbors',1); 53 | % Y_tar_pseudo = knn_model.predict(X_tar); 54 | % else 55 | % Y_tar_pseudo = options.Yt0; 56 | % end 57 | 58 | %% Iteration 59 | for i = 1 : T 60 | %%% Mc 61 | N = 0; 62 | if ~isempty(Y_tar_pseudo) && length(Y_tar_pseudo)==nt 63 | for c = reshape(unique(Y_src),1,C) 64 | e = zeros(nm,1); 65 | e(Y_src==c) = 1 / length(find(Y_src==c)); 66 | e(ns+find(Y_tar_pseudo==c)) = -1 / length(find(Y_tar_pseudo==c)); 67 | e(isinf(e)) = 0; 68 | N = N + e*e'; 69 | end 70 | end 71 | 72 | M = M + N; 73 | M = M / norm(M,'fro'); 74 | 75 | %% Calculation 76 | K = kernel_artl(kernel_type,X,sqrt(sum(sum(X.^2).^0.5)/nm)); 77 | Alpha = ((E + lambda * M + gamma * L) * K + sigma * speye(nm,nm)) \ (E * YY); 78 | F = K * Alpha; 79 | [~,Cls] = max(F,[],2); 80 | 81 | Acc = numel(find(Cls(ns+1:end)==Y(ns+1:end)))/nt; 82 | Y_tar_pseudo = Cls(ns+1:end); 83 | fprintf('Iteration [%2d]:ARTL=%0.4f\n',i,Acc); 84 | acc_ite = [acc_ite;Acc]; 85 | end 86 | 87 | end 88 | 89 | function [W,Dw,L] = construct_lapgraph(X,options) 90 | W = lapgraph(X,options); 91 | Dw = diag(sparse(sqrt(1./sum(W)))); 92 | L = speye(size(X,1)) - Dw * W * Dw; 93 | end 94 | 95 | function K = kernel_artl(ker,X,sigma) 96 | 97 | switch ker 98 | case 'linear' 99 | 100 | K = X' * X; 101 | 102 | case 'rbf' 103 | 104 | n1sq = sum(X.^2,1); 105 | n1 = size(X,2); 106 | 107 | D = (ones(n1,1)*n1sq)' + ones(n1,1)*n1sq -2*X'*X; 108 | K = exp(-D/(2*sigma^2)); 109 | 110 | case 'sam' 111 | 112 | D = X'*X; 113 | K = exp(-acos(D).^2/(2*sigma^2)); 114 | 115 | otherwise 116 | error(['Unsupported kernel ' ker]) 117 | end 118 | end -------------------------------------------------------------------------------- /code/MyTJM.m: -------------------------------------------------------------------------------- 1 | function [acc,acc_list,A] = MyTJM(X_src,Y_src,X_tar,Y_tar,options) 2 | % Inputs: 3 | %%% X_src :source feature matrix, ns * m 4 | %%% Y_src :source label vector, ns * 1 5 | %%% X_tar :target feature matrix, nt * m 6 | %%% Y_tar :target label vector, nt * 1 7 | %%% options:option struct 8 | % Outputs: 9 | %%% acc :final accuracy using knn, float 10 | %%% acc_list:list of all accuracies during iterations 11 | %%% A :final adaptation matrix, (ns + nt) * (ns + nt) 12 | 13 | %% Set options 14 | lambda = options.lambda; %% lambda for the regularization 15 | dim = options.dim; %% dim is the dimension after adaptation, dim <= m 16 | kernel_type = options.kernel_type; %% kernel_type is the kernel name, primal|linear|rbf 17 | gamma = options.gamma; %% gamma is the bandwidth of rbf kernel 18 | T = options.T; %% iteration number 19 | 20 | fprintf('TJM: dim=%d lambda=%f\n',dim,lambda); 21 | 22 | % Set predefined variables 23 | X = [X_src',X_tar']; 24 | X = X*diag(sparse(1./sqrt(sum(X.^2)))); 25 | ns = size(X_src,1); 26 | nt = size(X_tar,1); 27 | n = ns+nt; 28 | 29 | % Construct kernel matrix 30 | K = kernel_tjm(kernel_type,X,[],gamma); 31 | 32 | % Construct centering matrix 33 | H = eye(n)-1/(n)*ones(n,n); 34 | 35 | % Construct MMD matrix 36 | e = [1/ns*ones(ns,1);-1/nt*ones(nt,1)]; 37 | C = length(unique(Y_src)); 38 | M = e*e' * C; 39 | 40 | Cls = []; 41 | % Transfer Joint Matching: JTM 42 | G = speye(n); 43 | acc_list = []; 44 | for t = 1:T 45 | %%% Mc [If want to add conditional distribution] 46 | N = 0; 47 | if ~isempty(Cls) && length(Cls)==nt 48 | for c = reshape(unique(Y_src),1,C) 49 | e = zeros(n,1); 50 | e(Y_src==c) = 1 / length(find(Y_src==c)); 51 | e(ns+find(Cls==c)) = -1 / length(find(Cls==c)); 52 | e(isinf(e)) = 0; 53 | N = N + e*e'; 54 | end 55 | end 56 | M = (1 - mu) * M + mu * N; 57 | 58 | M = M/norm(M,'fro'); 59 | 60 | [A,~] = eigs(K*M*K'+lambda*G,K*H*K',dim,'SM'); 61 | % [A,~] = eigs(X*M*X'+lambda*G,X*H*X',k,'SM'); 62 | G(1:ns,1:ns) = diag(sparse(1./(sqrt(sum(A(1:ns,:).^2,2)+eps)))); 63 | Z = A'*K; 64 | Z = Z*diag(sparse(1./sqrt(sum(Z.^2)))); 65 | Zs = Z(:,1:ns)'; 66 | Zt = Z(:,ns+1:n)'; 67 | 68 | knn_model = fitcknn(Zs,Y_src,'NumNeighbors',1); 69 | Cls = knn_model.predict(Zt); 70 | acc = sum(Cls==Y_tar)/nt; 71 | acc_list = [acc_list;acc(1)]; 72 | 73 | fprintf('[%d] acc=%f\n',t,full(acc(1))); 74 | end 75 | fprintf('Algorithm JTM terminated!!!\n\n'); 76 | 77 | end 78 | 79 | 80 | % With Fast Computation of the RBF kernel matrix 81 | % To speed up the computation, we exploit a decomposition of the Euclidean distance (norm) 82 | % 83 | % Inputs: 84 | % ker: 'linear','rbf','sam' 85 | % X: data matrix (features * samples) 86 | % gamma: bandwidth of the RBF/SAM kernel 87 | % Output: 88 | % K: kernel matrix 89 | 90 | function K = kernel_tjm(ker,X,X2,gamma) 91 | 92 | switch ker 93 | case 'linear' 94 | 95 | if isempty(X2) 96 | K = X'*X; 97 | else 98 | K = X'*X2; 99 | end 100 | 101 | case 'rbf' 102 | 103 | n1sq = sum(X.^2,1); 104 | n1 = size(X,2); 105 | 106 | if isempty(X2) 107 | D = (ones(n1,1)*n1sq)' + ones(n1,1)*n1sq -2*X'*X; 108 | else 109 | n2sq = sum(X2.^2,1); 110 | n2 = size(X2,2); 111 | D = (ones(n2,1)*n1sq)' + ones(n1,1)*n2sq -2*X'*X2; 112 | end 113 | K = exp(-gamma*D); 114 | 115 | case 'sam' 116 | 117 | if isempty(X2) 118 | D = X'*X; 119 | else 120 | D = X'*X2; 121 | end 122 | K = exp(-gamma*acos(D).^2); 123 | 124 | otherwise 125 | error(['Unsupported kernel ' ker]) 126 | end 127 | end -------------------------------------------------------------------------------- /code/MyJDA.m: -------------------------------------------------------------------------------- 1 | function [acc,acc_ite,A] = MyJDA(X_src,Y_src,X_tar,Y_tar,options) 2 | % Inputs: 3 | %%% X_src :source feature matrix, ns * m 4 | %%% Y_src :source label vector, ns * 1 5 | %%% X_tar :target feature matrix, nt * m 6 | %%% Y_tar :target label vector, nt * 1 7 | %%% options:option struct 8 | % Outputs: 9 | %%% acc :final accuracy using knn, float 10 | %%% acc_ite:list of all accuracies during iterations 11 | %%% A :final adaptation matrix, (ns + nt) * (ns + nt) 12 | 13 | %% Set options 14 | lambda = options.lambda; %% lambda for the regularization 15 | dim = options.dim; %% dim is the dimension after adaptation, dim <= m 16 | kernel_type = options.kernel_type; %% kernel_type is the kernel name, primal|linear|rbf 17 | gamma = options.gamma; %% gamma is the bandwidth of rbf kernel 18 | T = options.T; %% iteration number 19 | 20 | acc_ite = []; 21 | Y_tar_pseudo = []; 22 | %% Iteration 23 | for i = 1 : T 24 | [Z,A] = JDA_core(X_src,Y_src,X_tar,Y_tar_pseudo,options); 25 | %normalization for better classification performance 26 | Z = Z*diag(sparse(1./sqrt(sum(Z.^2)))); 27 | Zs = Z(:,1:size(X_src,1)); 28 | Zt = Z(:,size(X_src,1)+1:end); 29 | 30 | knn_model = fitcknn(Zs',Y_src,'NumNeighbors',1); 31 | Y_tar_pseudo = knn_model.predict(Zt'); 32 | acc = length(find(Y_tar_pseudo==Y_tar))/length(Y_tar); 33 | fprintf('JDA+NN=%0.4f\n',acc); 34 | acc_ite = [acc_ite;acc]; 35 | end 36 | 37 | end 38 | 39 | function [Z,A] = JDA_core(X_src,Y_src,X_tar,Y_tar_pseudo,options) 40 | %% Set options 41 | lambda = options.lambda; %% lambda for the regularization 42 | dim = options.dim; %% dim is the dimension after adaptation, dim <= m 43 | kernel_type = options.kernel_type; %% kernel_type is the kernel name, primal|linear|rbf 44 | gamma = options.gamma; %% gamma is the bandwidth of rbf kernel 45 | 46 | %% Construct MMD matrix 47 | X = [X_src',X_tar']; 48 | X = X*diag(sparse(1./sqrt(sum(X.^2)))); 49 | [m,n] = size(X); 50 | ns = size(X_src,1); 51 | nt = size(X_tar,1); 52 | e = [1/ns*ones(ns,1);-1/nt*ones(nt,1)]; 53 | C = length(unique(Y_src)); 54 | 55 | %%% M0 56 | M = e * e' * C; %multiply C for better normalization 57 | 58 | %%% Mc 59 | N = 0; 60 | if ~isempty(Y_tar_pseudo) && length(Y_tar_pseudo)==nt 61 | for c = reshape(unique(Y_src),1,C) 62 | e = zeros(n,1); 63 | e(Y_src==c) = 1 / length(find(Y_src==c)); 64 | e(ns+find(Y_tar_pseudo==c)) = -1 / length(find(Y_tar_pseudo==c)); 65 | e(isinf(e)) = 0; 66 | N = N + e*e'; 67 | end 68 | end 69 | 70 | M = M + N; 71 | M = M / norm(M,'fro'); 72 | 73 | %% Centering matrix H 74 | H = eye(n) - 1/n * ones(n,n); 75 | 76 | %% Calculation 77 | if strcmp(kernel_type,'primal') 78 | [A,~] = eigs(X*M*X'+lambda*eye(m),X*H*X',dim,'SM'); 79 | Z = A'*X; 80 | else 81 | K = kernel_jda(kernel_type,X,[],gamma); 82 | [A,~] = eigs(K*M*K'+lambda*eye(n),K*H*K',dim,'SM'); 83 | Z = A'*K; 84 | end 85 | 86 | end 87 | 88 | % With Fast Computation of the RBF kernel matrix 89 | % To speed up the computation, we exploit a decomposition of the Euclidean distance (norm) 90 | % 91 | % Inputs: 92 | % ker: 'linear','rbf','sam' 93 | % X: data matrix (features * samples) 94 | % gamma: bandwidth of the RBF/SAM kernel 95 | % Output: 96 | % K: kernel matrix 97 | % 98 | % Gustavo Camps-Valls 99 | % 2006(c) 100 | % Jordi (jordi@uv.es), 2007 101 | % 2007-11: if/then -> switch, and fixed RBF kernel 102 | % Modified by Mingsheng Long 103 | % 2013(c) 104 | % Mingsheng Long (longmingsheng@gmail.com), 2013 105 | 106 | function K = kernel_jda(ker,X,X2,gamma) 107 | 108 | switch ker 109 | case 'linear' 110 | 111 | if isempty(X2) 112 | K = X'*X; 113 | else 114 | K = X'*X2; 115 | end 116 | 117 | case 'rbf' 118 | 119 | n1sq = sum(X.^2,1); 120 | n1 = size(X,2); 121 | 122 | if isempty(X2) 123 | D = (ones(n1,1)*n1sq)' + ones(n1,1)*n1sq -2*X'*X; 124 | else 125 | n2sq = sum(X2.^2,1); 126 | n2 = size(X2,2); 127 | D = (ones(n2,1)*n1sq)' + ones(n1,1)*n2sq -2*X'*X2; 128 | end 129 | K = exp(-gamma*D); 130 | 131 | case 'sam' 132 | 133 | if isempty(X2) 134 | D = X'*X; 135 | else 136 | D = X'*X2; 137 | end 138 | K = exp(-gamma*acos(D).^2); 139 | 140 | otherwise 141 | error(['Unsupported kernel ' ker]) 142 | end 143 | end -------------------------------------------------------------------------------- /code/TCA_python/da_tool/tca.py: -------------------------------------------------------------------------------- 1 | # encoding=utf-8 2 | """ 3 | Created on 14:52 2017/4/30 4 | @author: Jindong Wang 5 | """ 6 | 7 | import numpy as np 8 | 9 | 10 | class TCA: 11 | dim = 5 12 | kerneltype = 'rbf' 13 | kernelparam = 1 14 | mu = 1 15 | 16 | def __init__(self, dim=5, kerneltype='rbf', kernelparam=1, mu=1): 17 | ''' 18 | Init function 19 | :param dim: dims after tca (dim <= d) 20 | :param kerneltype: 'rbf' | 'linear' | 'poly' (default is 'rbf') 21 | :param kernelparam: kernel param 22 | :param mu: param 23 | ''' 24 | self.dim = dim 25 | self.kernelparam = kernelparam 26 | self.kerneltype = kerneltype 27 | self.mu = mu 28 | 29 | def get_L(self, n_src, n_tar): 30 | ''' 31 | Get index matrix 32 | :param n_src: num of source domain 33 | :param n_tar: num of target domain 34 | :return: index matrix L 35 | ''' 36 | L_ss = (1. / (n_src * n_src)) * np.full((n_src, n_src), 1) 37 | L_st = (-1. / (n_src * n_tar)) * np.full((n_src, n_tar), 1) 38 | L_ts = (-1. / (n_tar * n_src)) * np.full((n_tar, n_src), 1) 39 | L_tt = (1. / (n_tar * n_tar)) * np.full((n_tar, n_tar), 1) 40 | L_up = np.hstack((L_ss, L_st)) 41 | L_down = np.hstack((L_ts, L_tt)) 42 | L = np.vstack((L_up, L_down)) 43 | return L 44 | 45 | def get_kernel(self, kerneltype, kernelparam, x1, x2=None): 46 | ''' 47 | Calculate kernel for TCA (inline func) 48 | :param kerneltype: 'rbf' | 'linear' | 'poly' 49 | :param kernelparam: param 50 | :param x1: x1 matrix (n1,d) 51 | :param x2: x2 matrix (n2,d) 52 | :return: Kernel K 53 | ''' 54 | n1, dim = x1.shape 55 | K = None 56 | if x2 is not None: 57 | n2 = x2.shape[0] 58 | if kerneltype == 'linear': 59 | if x2 is not None: 60 | K = np.dot(x2, x1.T) 61 | else: 62 | K = np.dot(x1, x1.T) 63 | elif kerneltype == 'poly': 64 | if x2 is not None: 65 | K = np.power(np.dot(x1, x2.T), kernelparam) 66 | else: 67 | K = np.power(np.dot(x1, x1.T), kernelparam) 68 | elif kerneltype == 'rbf': 69 | if x2 is not None: 70 | sum_x2 = np.sum(np.multiply(x2, x2), axis=1) 71 | sum_x2 = sum_x2.reshape((len(sum_x2), 1)) 72 | K = np.exp(-1 * ( 73 | np.tile(np.sum(np.multiply(x1, x1), axis=1).T, (n2, 1)) + np.tile(sum_x2, (1, n1)) - 2 * np.dot(x2, 74 | x1.T)) / ( 75 | dim * 2 * kernelparam)) 76 | else: 77 | P = np.sum(np.multiply(x1, x1), axis=1) 78 | P = P.reshape((len(P), 1)) 79 | K = np.exp( 80 | -1 * (np.tile(P.T, (n1, 1)) + np.tile(P, (1, n1)) - 2 * np.dot(x1, x1.T)) / (dim * 2 * kernelparam)) 81 | # more kernels can be added 82 | return K 83 | 84 | def fit_transform(self, x_src, x_tar, x_tar_o=None): 85 | ''' 86 | TCA main method. Wrapped from Sinno J. Pan and Qiang Yang's "Domain adaptation via transfer component ayalysis. IEEE TNN 2011" 87 | :param x_src: Source domain data feature matrix. Shape is (n_src,d) 88 | :param x_tar: Target domain data feature matrix. Shape is (n_tar,d) 89 | :param x_tar_o: Out-of-sample target data feature matrix. Shape is (n_tar_o,d) 90 | :return: tranformed x_src_tca,x_tar_tca,x_tar_o_tca 91 | ''' 92 | n_src = x_src.shape[0] 93 | n_tar = x_tar.shape[0] 94 | X = np.vstack((x_src, x_tar)) 95 | L = self.get_L(n_src, n_tar) 96 | L[np.isnan(L)] = 0 97 | K = self.get_kernel(self.kerneltype, self.kernelparam, X) 98 | K[np.isnan(K)] = 0 99 | if x_tar_o is not None: 100 | K_tar_o = self.get_kernel(self.kerneltype, self.kernelparam, X, x_tar_o) 101 | 102 | H = np.identity(n_src + n_tar) - 1. / (n_src + n_tar) * np.ones(shape=(n_src + n_tar, 1)) * np.ones( 103 | shape=(n_src + n_tar, 1)).T 104 | forPinv = self.mu * np.identity(n_src + n_tar) + np.dot(np.dot(K, L), K) 105 | forPinv[np.isnan(forPinv)] = 0 106 | Kc = np.dot(np.dot(np.dot(np.linalg.pinv(forPinv), K), H), K) 107 | Kc[np.isnan(Kc)] = 0 108 | 109 | D, V = np.linalg.eig(Kc) 110 | eig_values = D.reshape(len(D), 1) 111 | eig_values_sorted = np.sort(eig_values[::-1], axis=0) 112 | index_sorted = np.argsort(-eig_values, axis=0) 113 | V = V[:, index_sorted] 114 | V = V.reshape((V.shape[0], V.shape[1])) 115 | x_src_tca = np.dot(K[:n_src, :], V) 116 | x_tar_tca = np.dot(K[n_src:, :], V) 117 | if x_tar_o is not None: 118 | x_tar_o_tca = np.dot(K_tar_o, V) 119 | else: 120 | x_tar_o_tca = None 121 | 122 | x_src_tca = np.asarray(x_src_tca[:, :self.dim], dtype=float) 123 | x_tar_tca = np.asarray(x_tar_tca[:, :self.dim], dtype=float) 124 | if x_tar_o is not None: 125 | x_tar_o_tca = x_tar_o_tca[:, :self.dim] 126 | return x_src_tca, x_tar_tca, x_tar_o_tca 127 | 128 | 129 | if __name__ == '__main__': 130 | file_path = 'data/test_tca_data.csv' 131 | data = np.loadtxt(file_path, delimiter=',') 132 | x_src = data[:, :81] 133 | x_tar = data[:, 81:] 134 | 135 | # example usage 136 | my_tca = TCA(dim=30) 137 | x_src_tca, x_tar_tca, x_tar_o_tca = my_tca.fit_transform(x_src, x_tar) 138 | np.savetxt('x_src1.csv', x_src_tca, delimiter=',', fmt='%.6f') 139 | np.savetxt('x_tar1.csv', x_tar_tca, delimiter=',', fmt='%.6f') 140 | -------------------------------------------------------------------------------- /code/MyJGSA.m: -------------------------------------------------------------------------------- 1 | function [acc,acc_list,A,B] = MyJGSA(X_src,Y_src,X_tar,Y_tar,options) 2 | %% Joint Geometrical and Statistic Adaptation 3 | % Inputs: 4 | %%% X_src :source feature matrix, ns * m 5 | %%% Y_src :source label vector, ns * 1 6 | %%% X_tar :target feature matrix, nt * m 7 | %%% Y_tar :target label vector, nt * 1 8 | %%% options:option struct 9 | % Outputs: 10 | %%% acc :final accuracy using knn, float 11 | %%% acc_list:list of all accuracies during iterations 12 | %%% A :final adaptation matrix for source domain, m * dim 13 | %%% B :final adaptation matrix for target domain, m * dim 14 | 15 | alpha = options.alpha; 16 | mu = options.mu; 17 | beta = options.beta; 18 | gamma = options.gamma; 19 | kernel_type = options.kernel_type; 20 | dim = options.dim; 21 | T = options.T; 22 | 23 | X_src = X_src'; 24 | X_tar = X_tar'; 25 | 26 | m = size(X_src,1); 27 | ns = size(X_src,2); 28 | nt = size(X_tar,2); 29 | 30 | class_set = unique(Y_src); 31 | C = length(class_set); 32 | acc_list = []; 33 | Y_tar_pseudo = []; 34 | if strcmp(kernel_type,'primal') 35 | [Sw, Sb] = scatter_matrix(X_src',Y_src); 36 | P = zeros(2 * m,2 * m); 37 | P(1:m,1:m) = Sb; 38 | Q = Sw; 39 | 40 | for t = 1 : T 41 | [Ms,Mt,Mst,Mts] = construct_mmd(ns,nt,Y_src,Y_tar_pseudo,C); 42 | Ts = X_src * Ms * X_src'; 43 | Tt = X_tar * Mt * X_tar'; 44 | Tst = X_src * Mst * X_tar'; 45 | Tts = X_tar * Mts * X_src'; 46 | 47 | Ht = eye(nt) - 1 / nt * ones(nt,nt); 48 | 49 | X = [zeros(m,ns),zeros(m,nt);zeros(m,ns),X_tar]; 50 | H = [zeros(ns,ns),zeros(ns,nt);zeros(nt,ns),Ht]; 51 | 52 | Smax = mu * X * H * X' + beta * P; 53 | Smin = [Ts+alpha*eye(m)+beta*Q, Tst-alpha*eye(m) ; ... 54 | Tts-alpha*eye(m), Tt+(alpha+mu)*eye(m)]; 55 | mm = 1e-9*eye(2*m); 56 | [W,~] = eigs(Smax,Smin + mm,dim,'LM'); 57 | As = W(1:m,:); 58 | At = W(m+1:end,:); 59 | Zs = (As' * X_src)'; 60 | Zt = (At' * X_tar)'; 61 | 62 | if T > 1 63 | knn_model = fitcknn(Zs,Y_src,'NumNeighbors',1); 64 | Y_tar_pseudo = knn_model.predict(Zt); 65 | acc = length(find(Y_tar_pseudo == Y_tar)) / length(Y_tar); 66 | fprintf('acc of iter %d: %0.4f\n',t, acc); 67 | acc_list = [acc_list;acc]; 68 | end 69 | end 70 | else 71 | Xst = [X_src,X_tar]; 72 | nst = size(Xst,2); 73 | [Ks, Kt, Kst] = constructKernel(X_src,X_tar,kernel_type,gamma); 74 | [Sw, Sb] = scatter_matrix(Ks,Y_src); 75 | P = zeros(2 * nst,2 * nst); 76 | P(1:nst,1:nst) = Sb; 77 | Q = Sw; 78 | for t = 1:T 79 | 80 | % Construct MMD matrix 81 | [Ms, Mt, Mst, Mts] = construct_mmd(ns,nt,Y_src,Y_tar_pseudo,C); 82 | 83 | Ts = Ks'*Ms*Ks; 84 | Tt = Kt'*Mt*Kt; 85 | Tst = Ks'*Mst*Kt; 86 | Tts = Kt'*Mts*Ks; 87 | 88 | K = [zeros(ns,nst), zeros(ns,nst); zeros(nt,nst), Kt]; 89 | Smax = mu*K'*K+beta*P; 90 | 91 | Smin = [Ts+alpha*Kst+beta*Q, Tst-alpha*Kst;... 92 | Tts-alpha*Kst, Tt+mu*Kst+alpha*Kst]; 93 | [W,~] = eigs(Smax, Smin+1e-9*eye(2*nst), dim, 'LM'); 94 | W = real(W); 95 | 96 | As = W(1:nst, :); 97 | At = W(nst+1:end, :); 98 | 99 | Zs = (As'*Ks')'; 100 | Zt = (At'*Kt')'; 101 | 102 | if T > 1 103 | knn_model = fitcknn(Zs,Y_src,'NumNeighbors',1); 104 | Y_tar_pseudo = knn_model.predict(Zt); 105 | acc = length(find(Y_tar_pseudo == Y_tar)) / length(Y_tar); 106 | fprintf('acc of iter %d: %0.4f\n',t, full(acc)); 107 | acc_list = [acc_list;acc]; 108 | end 109 | end 110 | end 111 | A = As; 112 | B = At; 113 | end 114 | 115 | function [Sw,Sb] = scatter_matrix(X,Y) 116 | %% Within and between class Scatter matrix 117 | %% Inputs: 118 | %%% X: data matrix, length * dim 119 | %%% Y: label vector, length * 1 120 | % Outputs: 121 | %%% Sw: With-in class matrix, dim * dim 122 | %%% Sb: Between class matrix, dim * dim 123 | X = X'; 124 | dim = size(X,1); 125 | class_set = unique(Y); 126 | C = length(class_set); 127 | mean_total = mean(X,2); 128 | Sw = zeros(dim,dim); 129 | Sb = zeros(dim,dim); 130 | for i = 1 : C 131 | Xi = X(:,Y == class_set(i)); 132 | mean_class_i = mean(Xi,2); 133 | Hi = eye(size(Xi,2)) - 1/(size(Xi,2)) * ones(size(Xi,2),size(Xi,2)); 134 | Sw = Sw + Xi * Hi * Xi'; 135 | Sb = Sb + size(Xi,2) * (mean_class_i - mean_total) * (mean_class_i - mean_total)'; 136 | end 137 | end 138 | 139 | function [Ms,Mt,Mst,Mts] = construct_mmd(ns,nt,Y_src,Y_tar_pseudo,C) 140 | es = 1 / ns * ones(ns,1); 141 | et = -1 / nt * ones(nt,1); 142 | e = [es;et]; 143 | 144 | M = e * e' * C; 145 | Ms = es * es' * C; 146 | Mt = et * et' * C; 147 | Mst = es * et' * C; 148 | Mts = et * es' * C; 149 | 150 | if ~isempty(Y_tar_pseudo) && length(Y_tar_pseudo) == nt 151 | for c = reshape(unique(Y_src),1,C) 152 | es = zeros(ns,1); 153 | et = zeros(nt,1); 154 | es(Y_src == c) = 1 / length(find(Y_src == c)); 155 | et(Y_tar_pseudo == c) = -1 / length(find(Y_tar_pseudo == c)); 156 | es(isinf(es)) = 0; 157 | et(isinf(et)) = 0; 158 | Ms = Ms + es * es'; 159 | Mt = Mt + et * et'; 160 | Mst = Mst + es * et'; 161 | Mts = Mts + et * es'; 162 | end 163 | end 164 | 165 | Ms = Ms / norm(M,'fro'); 166 | Mt = Mt / norm(M,'fro'); 167 | Mst = Mst / norm(M,'fro'); 168 | Mts = Mts / norm(M,'fro'); 169 | end 170 | 171 | function [Ks, Kt, Kst] = constructKernel(Xs,Xt,ker,gamma) 172 | Xst = [Xs, Xt]; 173 | ns = size(Xs,2); 174 | nt = size(Xt,2); 175 | nst = size(Xst,2); 176 | Kst0 = km_kernel(Xst',Xst',ker,gamma); 177 | Ks0 = km_kernel(Xs',Xst',ker,gamma); 178 | Kt0 = km_kernel(Xt',Xst',ker,gamma); 179 | 180 | oneNst = ones(nst,nst)/nst; 181 | oneN=ones(ns,nst)/nst; 182 | oneMtrN=ones(nt,nst)/nst; 183 | Ks=Ks0-oneN*Kst0-Ks0*oneNst+oneN*Kst0*oneNst; 184 | Kt=Kt0-oneMtrN*Kst0-Kt0*oneNst+oneMtrN*Kst0*oneNst; 185 | Kst=Kst0-oneNst*Kst0-Kst0*oneNst+oneNst*Kst0*oneNst; 186 | end 187 | 188 | function K = km_kernel(X1,X2,ktype,kpar) 189 | % KM_KERNEL calculates the kernel matrix between two data sets. 190 | % Input: - X1, X2: data matrices in row format (data as rows) 191 | % - ktype: string representing kernel type 192 | % - kpar: vector containing the kernel parameters 193 | % Output: - K: kernel matrix 194 | % USAGE: K = km_kernel(X1,X2,ktype,kpar) 195 | % 196 | % Author: Steven Van Vaerenbergh (steven *at* gtas.dicom.unican.es), 2012. 197 | % 198 | % This file is part of the Kernel Methods Toolbox for MATLAB. 199 | % https://github.com/steven2358/kmbox 200 | 201 | switch ktype 202 | case 'gauss' % Gaussian kernel 203 | sgm = kpar; % kernel width 204 | 205 | dim1 = size(X1,1); 206 | dim2 = size(X2,1); 207 | 208 | norms1 = sum(X1.^2,2); 209 | norms2 = sum(X2.^2,2); 210 | 211 | mat1 = repmat(norms1,1,dim2); 212 | mat2 = repmat(norms2',dim1,1); 213 | 214 | distmat = mat1 + mat2 - 2*X1*X2'; % full distance matrix 215 | sgm = sgm / mean(mean(distmat)); % added by jing 24/09/2016, median-distance 216 | K = exp(-distmat/(2*sgm^2)); 217 | 218 | case 'gauss-diag' % only diagonal of Gaussian kernel 219 | sgm = kpar; % kernel width 220 | K = exp(-sum((X1-X2).^2,2)/(2*sgm^2)); 221 | 222 | case 'poly' % polynomial kernel 223 | % p = kpar(1); % polynome order 224 | % c = kpar(2); % additive constant 225 | p = kpar; % jing 226 | c = 1; % jing 227 | 228 | K = (X1*X2' + c).^p; 229 | 230 | case 'linear' % linear kernel 231 | K = X1*X2'; 232 | 233 | otherwise % default case 234 | error ('unknown kernel type') 235 | end 236 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 关于迁移学习的一些资料 2 | 3 | 关于机器学习和行为识别的资料,请见我的下面两个仓库: 4 | 5 | - [行为识别](https://github.com/jindongwang/activityrecognition)|[机器学习](https://github.com/jindongwang/MachineLearning) 6 | 7 | _ _ _ 8 | 9 | #### 目录 Table of contents 10 | 11 | * [迁移学习简介 Introduction to transfer learning](#1迁移学习简介) 12 | * [迁移学习的综述文章 Survey papers for transfer learning](#2迁移学习的综述文章) 13 | * [Matlab和Python代码 Available codes](https://github.com/jindongwang/transferlearning/tree/master/code) 14 | * [迁移学习代表性研究学者 Scholars](#4迁移学习代表性研究学者) 15 | * [迁移学习相关的硕博士论文 Thesis](#5迁移学习相关的硕博士论文) 16 | * [Domain adaptation相关的文章 Domain adaptation articles](https://github.com/jindongwang/transferlearning/blob/master/doc/domain_adaptation.md) 17 | * [代表方法及文章解读 Popular methods and my explanations](#代表性的方法及文章) 18 | * [迁移学习用于行为识别的文章总结 Transfer learningfor activity recognition](https://github.com/jindongwang/activityrecognition/blob/master/notes/%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0%E7%94%A8%E4%BA%8E%E8%A1%8C%E4%B8%BA%E8%AF%86%E5%88%AB.md) 19 | * [常用数据集 Datasets](https://github.com/jindongwang/transferlearning/blob/master/doc/dataset.md) 20 | * [Contributing](#contributing) 21 | 22 | - - - 23 | 24 | ### 1.迁移学习简介 25 | 26 | [文档](https://github.com/jindongwang/transferlearning/blob/master/doc/%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0%E7%AE%80%E4%BB%8B.md) || [PPT(英文)](http://jd92.wang/assets/files/l03_transferlearning.pdf) || [PPT(中文)](http://jd92.wang/assets/files/l08_tl_zh.pdf) 27 | 28 | 台湾大学李宏毅的视频讲解,非常不错:https://www.youtube.com/watch?v=qD6iD4TFsdQ 29 | 30 | - - - 31 | 32 | ### 2.迁移学习的综述文章 33 | 34 | [一些迁移学习的综述文章](https://mega.nz/#F!sb4ChYoa!37LU6HGJ6LhQC1OYYBglIw),中文英文都有。 35 | 36 | - 其中,最具代表性的综述是[A survey on transfer learning](https://mega.nz/#!hapCXZjQ!p9PpMK0VYWy6Li7QBZ3eVDgaHYUc1MewRFMcjfXAA7s),对迁移学习进行了比较权威的定义。 37 | 38 | - 最新的综述是[Cross-dataset recognition: a survey](https://arxiv.org/abs/1705.04396),目前刚发在arXiv上,作者是澳大利亚卧龙岗大学的在读博士生,迁移学习领域做的不错。 39 | 40 | - 来自香港科技大学Qiang Yang老师团队的最新综述[A survey on multi-task learning](https://arxiv.org/abs/1707.08114) 41 | 42 | - 还有一篇较新的综述是[A survey of transfer learning](https://mega.nz/#!RfwwiBYS!7mM4juZY-oslxNtG_mv1XhV4zJknzpDM4QkD14S91_s),写于2015-2016年。其中交代了一些比较经典的如同构、异构等学习方法代表性文章。包括了很多方法介绍,值得一看。 43 | 44 | - 此外,还包括[迁移学习应用于行为识别](https://mega.nz/#!RfwwiBYS!7mM4juZY-oslxNtG_mv1XhV4zJknzpDM4QkD14S91_s)、[迁移学习与增强学习](https://mega.nz/#!RDpiRDCL!LSMgyjV69YEiFE2D0quKkrr_t7bEOYtsnx8BkTxniKo)结合等。 45 | - 关于[多个源域进行迁移的综述](https://mega.nz/#!UPRTBIAS!HcjUwI_yGe3IrWCFfBxHF9nd8CFt0GTzjIyMMxdUuv0)、[视觉domain adaptation综述](https://mega.nz/#!hWQ3HLhJ!GTCIUTVDcmnn3f7-Ulhjs_MxGv6xnFyp1nayemt9Nis)也十分有用。 46 | - 中文方面,[迁移学习研究进展](https://mega.nz/#!xPBB2CrZ!QXfJAbmM3DgURIIqB22kgzTARxXIr3TThILgGWXOmPE)是一篇不错的中文综述。 47 | - 关于迁移学习的理论方面,有三篇连贯式的理论分析文章连续发表在NIPS和Machine Learning上:[理论分析](https://mega.nz/#F!ULoGFYDK!O3TQRZwrNeqTncNMIfXNTg) 48 | 49 | _ _ _ 50 | 51 | ### 3.代码 52 | 53 | 请见[这里](https://github.com/jindongwang/transferlearning/tree/master/code) 54 | 55 | _ _ _ 56 | 57 | ### 4.迁移学习代表性研究学者 58 | 59 | - [Qiang Yang](http://www.cs.ust.hk/~qyang/):中文名杨强。香港科技大学计算机系主任,教授,大数据中心主任。迁移学习领域世界性专家。IEEE/AAAI/IAPR/AAAS fellow。[[Google scholar](https://scholar.google.com/citations?user=1LxWZLQAAAAJ&hl=zh-CN)] 60 | - [Sinno Jialin Pan](http://www.ntu.edu.sg/home/sinnopan/):杨强的学生,香港科技大学博士,现任新加坡南阳理工大学助理教授。迁移学习领域代表性综述A survey on transfer learning的第一作者(Qiang Yang是二作)。[[Google scholar](https://scholar.google.com/citations?user=P6WcnfkAAAAJ&hl=zh-CN)] 61 | - [Wenyuan Dai](https://scholar.google.com.sg/citations?user=AGR9pP0AAAAJ&hl=zh-CN):中文名戴文渊,上海交通大学硕士,现任第四范式人工智能创业公司CEO。迁移学习领域著名的牛人,每篇论文引用量巨大,在顶级会议上发表多篇高水平文章。 62 | - [Fuzhen Zhuang](http://www.intsci.ac.cn/users/zhuangfuzhen/):中文名庄福振,中科院计算所博士,现任中科院计算所副研究员。[[Google scholar](https://scholar.google.com/citations?user=klJBYrAAAAAJ&hl=zh-CN&oi=ao)] 63 | - [Mingsheng Long](http://ise.thss.tsinghua.edu.cn/~mlong/):中文名龙明盛,清华大学博士,现任清华大学助理研究员。[[Google scholar](https://scholar.google.com/citations?view_op=search_authors&mauthors=mingsheng+long&hl=zh-CN&oi=ao)] 64 | - [Lixin Duan](http://www.lxduan.info/):中文名段立新,新加坡南阳理工大学博士,现就职于亚马逊。 65 | _ _ _ 66 | 67 | ### 5.迁移学习相关的硕博士论文 68 | 69 | 硕博士论文可以让我们很快地对迁移学习的相关领域做一些了解,同时,也能很快地了解概括相关研究者的工作。其中,比较有名的有 70 | 71 | - [Sinno Jialin Pan](https://mega.nz/#!xCwBALCb!exNKlFh6Mi_bvzmclBd6rWOeIwqUuwR7thYIsFK1J5U) 72 | - [Boqing Gong](https://pdfs.semanticscholar.org/71b0/38958df0b7855fc7b8b8e7dcde8537a7c1ad.pdf):提出GFK的 73 | - [Hao Hu](https://mega.nz/#!IaQzlIAY!HpvK6YYv37EngofqZDgdRpMLErSPAmgz8Ln9hWPAJSw) 74 | - [Wenchen Zheng](https://mega.nz/#!QDJFUA4Z!3lBYHH1YzmWI9nTecvaSsR65aWSUmTiUN6Wmjk8y-vc) 75 | 76 | 等的博士论文都是关于迁移学习的。中文方面, 77 | 78 | - 清华大学[龙明盛](https://mega.nz/#!kDBTjDQZ!VZMu4f57N0GBKVcaJs1WNxNkA1JOmp4NcYiVDoDqIJM) 79 | - 上海交通大学的[戴文渊](https://mega.nz/#!UehghTCK!9KPD4FwWpHoZmYCmweF0y67Sft7KzTi8F_ZIUA15-QE) 80 | - 中科院计算所[赵中堂](https://mega.nz/#!cKowSJSD!NLPQ01oSBYXughH9F1toFqdFoYY7JsPQMZlIYtn2-LA) 81 | 82 | 其他的文章,请见[完整版](https://mega.nz/#F!YHIFxJAL!Ts413E2dbEc_2az4dhb_Jg)。 83 | 84 | - - - 85 | 86 | ### 6.Domain adaptation相关的文章 87 | 88 | Domain adaptation是迁移学习领域比较热的研究方向,在这里整理了一些经典的文章和说明:[Domain adaptation](https://github.com/jindongwang/transferlearning/blob/master/doc/domain_adaptation.md) 89 | 90 | #### 代表性的方法及文章 91 | 92 | - 迁移成分分析方法(Transfer component analysis, TCA) 93 | - [Domain adaptation via tranfer component analysis](https://mega.nz/#!JTwElLrL!j5-TanhHCMESsGBNvY6I_hX6uspsrTxyopw8bPQ2azU) 94 | - 发表在IEEE Trans. Neural Network期刊上(现改名为IEEE trans. Neural Network and Learning System),前作会议文章发在AAAI-09上 95 | - [我的解读](https://zhuanlan.zhihu.com/p/26764147?group_id=844611188275965952) 96 | 97 | - 联合分布适配方法(joint distribution adaptation,JDA) 98 | - [Transfer Feature Learning with Joint Distribution Adaptation](http://ise.thss.tsinghua.edu.cn/~mlong/doc/joint-distribution-adaptation-iccv13.pdf) 99 | - 发表在2013年的ICCV上 100 | - [我的解读](https://zhuanlan.zhihu.com/p/27336930) 101 | 102 | - 测地线流式核方法(Geodesic flow kernel, GFK) 103 | - [Geodesic flow kernel for unsupervised domain adaptation](https://mega.nz/#!tDY1lCSD!flMSgl-0uIswpSFL3sdZgKi6fOyFVLtcO8P6SE0OUPU) 104 | - 发表在CVPR-12上 105 | - [我的解读](https://zhuanlan.zhihu.com/p/27782708) 106 | - 领域不变性迁移核学习(Transfer Kernel Learning, TKL) 107 | - [Domain invariant transfer kernel learning](https://mega.nz/#!tOoCCRhB!YyoorOUcp6XIPPd6A0s7qglYnaSiRJFEQBphtZ2c58Q) 108 | - 发表在IEEE Trans. Knowledge and Data Engineering期刊上 109 | - 深度适配网络(Deep Adaptation Network, DAN) 110 | - 发表在ICML-15上:learning transferable features with deep adaptation networks 111 | - [我的解读](https://zhuanlan.zhihu.com/p/27657910) 112 | 113 | - [深度联合适配网络](http://proceedings.mlr.press/v70/long17a.html)(Joint Adaptation Network, JAN) 114 | - Deep Transfer Learning with Joint Adaptation Networks 115 | - 发表在ICML 2017上,作者也是龙明盛 116 | - 延续了之前的DAN工作,这次考虑联合适配 117 | _ _ _ 118 | 119 | ### [记与迁移学习大牛杨强教授的第二次会面](https://zhuanlan.zhihu.com/p/26260083) 120 | 121 | _ _ _ 122 | 123 | ### [迁移学习用于行为识别的文章总结](https://github.com/jindongwang/activityrecognition/blob/master/notes/%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0%E7%94%A8%E4%BA%8E%E8%A1%8C%E4%B8%BA%E8%AF%86%E5%88%AB.md) 124 | 125 | 我写的迁移学习应用于行为识别领域的文章小总结。目前不知道为什么markdown表格的格式错乱,未来会修正。 126 | 127 | _ _ _ 128 | 129 | ### 未来计划: 130 | 131 | 迁移学习、transfer learning、domain adaptation相关的我看过的一些论文: 132 | 133 | - 深度迁移学习 134 | 135 | 136 | - - - 137 | 138 | 139 | ### Contributing 140 | 141 | 如果你对本项目感兴趣,非常欢迎你加入! 142 | 143 | - 正常参与:请直接fork、pull都可以 144 | - 如果要上传文件:请**不要**直接上传到项目中,否则会造成git版本库过大。正确的方法是上传它的**超链接**。如果你要上传的文件本身就在网络中(如paper都会有链接),直接上传即可;如果是自己想分享的一些文件、数据等,鉴于国内网盘的情况,请按照如下方式上传: 145 | - 首先在[UPLOAD](https://my.pcloud.com/#page=puplink&code=4e9Z0Vwpmfzvx0y2OqTTTMzkrRUz8q9V) 直接上传(**不**需要注册账号) 146 | - 上传成功后,在[DOWNLOAD](https://my.pcloud.com/publink/show?code=kZWtboZbDDVguCHGV49QkmlLliNPJRMHrFX)里找到你刚上传的文件,共享链接即可。 147 | 148 | Welcome! 149 | 150 | > ***[文章版权声明]这篇文档是我开源到github上的,可以遵守相关的开源协议进行使用,如果使用时能加上我的名字就更好了。这个仓库中包含有很多研究者的论文、硕博士论文等,都来源于在网上的下载。我对其中一些文章都写了自己的浅见,希望能很好地帮助理解。这些文章的版权属于相应的出版社。如果作者或出版社有异议,请联系我进行删除(本来应该只放文章链接的,但是由于时间关系来不及)。一切都是为了更好地学术!*** 151 | -------------------------------------------------------------------------------- /doc/dataset.md: -------------------------------------------------------------------------------- 1 | ## Datasets for domain adaptation and transfer learning 2 | 3 | - *How many times have you been* ++struggling to find++ the useful datasets? 4 | - *How much time have you been wasting to* ++preprocess datasets++? 5 | - *How burdersome is it to compare with other methods*? Will you re-run their code? or there is no code? 6 | 7 | **Datasets are critical to machine learning**, but *You should focus on* **YOUR** work! So we want to save your time by: 8 | 9 | **JUST GIVE THEM TO YOU** so you can **DIRECTLY** use them! 10 | 11 | - - - 12 | 13 | **Some widely used datasets for domain adaptation and transfer learning are listed here. See [benchmark](#benchmark) of several classical algorithms.** 14 | 15 | *Only image datasets are listed, text datasets are to be added* 16 | 17 | | Dataset | Area | #Sample | #Feature | #Class | Subdomain | Reference | 18 | |:--------------:|:------------------:|:-------:|:-------------------:|:------:|:------------:|:--------:| 19 | | [Office+Caltech](#office+caltech) | Object recognition | 2533 | SURF:800 DeCAF:4096 | 10 | C, A, W, D | [1] | 20 | | [MNIST+USPS](#mnist+usps) | Digit recognition | 3800 | 256 | 10 | USPS, MNIST | [4] | 21 | | [COIL20](#coil20) | Object recognition | 1440 | 1024 | 20 | COIL1, COIL2 | [4] | 22 | | [PIE](#pie) | Face recognition | 11554 | 1024 | 68 | PIE1~PIE5 | [6] | 23 | | [VOC2007](#vlsc) | Object recognition | 3376 | DeCAF:4096 | 5 | V | [8] | 24 | | [LabelMe](#vlsc) | Object recognition | 2656 | DeCAF:4096 | 5 | L | [2] | 25 | | [SUN09](#vlsc) | Object recognition | 3282 | DeCAF:4096 | 5 | S | [9] | 26 | | [Caltech101](#vlsc) | Object recognition | 1415 | DeCAF:4096 | 5 | C | [3] | 27 | | [IMAGENET](#imagenet) | Object recognition | 7341 | DeCAF:4096 | 5 | I | [7] | 28 | | [AWA](#animals-with-attributes) | Animal recognition | 30475 | DeCAF:4096 SIFT/SURF:2000 | 50 | I | [5] | 29 | 30 | 31 | 32 | - - - 33 | 34 | 35 | ### Office+Caltech 36 | 37 | #### Area 38 | 39 | Visual object recognition 40 | 41 | #### Introduction 42 | 43 | Perhaps it is the **most popular** dataset for domain adaptation. Four domains are included: C(Caltech), A(Amazon), W(Webcam) and D(DSLR). In fact, this dataset is constructed from two datasets: Office-31 (which contains 31 classes of A, W and D) and Caltech-256 (which contains 256 classes of C). There are just 10 common classes in both, so the Office+Caltech dataset is formed. 44 | 45 | Even for the same category, the data distribution of different domains is exactly different. The following picture [1] indicates this fact by the monitor images from 4 domains. 46 | 47 | ![](https://raw.githubusercontent.com/jindongwang/transferlearning/master/png/domain%20_adaptation.png) 48 | 49 | #### Features 50 | 51 | There are ususlly two kinds of features: SURF and DeCAF6. They are with the same number of samples per domain, resulting 2533 samples in total: 52 | 53 | - C: 1123 54 | - A: 958 55 | - W: 295 56 | - D: 157 57 | 58 | And the dimension of features is: 59 | 60 | - For SURF: 800 61 | - For DeCAF6: 4096 62 | 63 | #### Copyright 64 | 65 | This dataset was first introduced by Gong et al. [1]. I got the SURF features from the website of [1], while DeCAF features from [10]. 66 | 67 | #### Download 68 | 69 | [Download Office+Caltech SURF dataset](https://mega.nz/#F!AaJTGIzD!XHM2XMsSd9V-ljVi0EtvFg) 70 | 71 | [Download Office+Caltech DeCAF dataset](https://mega.nz/#F!QDxBBC4J!LizxWbE1_JEwPSrA2mrrrw) 72 | 73 | 74 | - - - 75 | 76 | 77 | ### MNIST+USPS 78 | 79 | **Area** Handwritten digit recognition 80 | 81 | It is also popular. It contains randomly selected samples from MNIST and USPS. Then the source and target domains are constructed using each other. 82 | 83 | [Download MNIST+USPS SURF dataset](https://mega.nz/#F!oHJ2UCoK!r62nRoZ0gH8NXIcgmyWReA) 84 | 85 | 86 | - - - 87 | 88 | 89 | ### COIL20 90 | 91 | **Area** Object recognition 92 | 93 | It contains 20 classes. There are two datasets extracted: COIL1 and COIL2. 94 | 95 | [Download COIL20 SURF dataset](https://mega.nz/#F!xWxyTDaZ!MWamSH17Uu065XbDNYymkQ) 96 | 97 | 98 | - - - 99 | 100 | 101 | ### PIE 102 | 103 | **Area** Facial recognition 104 | 105 | It is a relatively large dataset with many classes. 106 | 107 | [Download PIE SURF dataset](https://mega.nz/#F!lPgmkZQB!z2QuBEmCzj2XR5AAQaIj7Q) 108 | 109 | 110 | - - - 111 | 112 | 113 | 114 | ### VLSC 115 | 116 | **Area** Image classification 117 | 118 | It contains four domains: V(VOC2007), L(LabelMe), S(SUN09) and C(Caltech). There are 5 classes: 'bird', 'car', 'chair', 'dog', 'person'. 119 | 120 | [Download the VLSC DeCAF dataset](https://mega.nz/#F!gTJxGTJK!w9UJjZVq3ClqGj4mBDmT4A) 121 | 122 | 123 | - - - 124 | 125 | 126 | 127 | ### IMAGENET 128 | 129 | It is selected from imagenet challange. 130 | 131 | [Download the IMAGENET DeCAF dataset](https://mega.nz/#!IeZ0yIQZ!spaZ0L3lbpsTykRJf5CNx6zk4kUk-p5MlqPAlGkPbu8) 132 | 133 | 134 | - - - 135 | 136 | 137 | ### Animals-with-Attributes 138 | 139 | [Download the SURF/SIFT/DeCAF features](https://mega.nz/#F!Na5jyLiC!LT29_gyoPsd_eEoym3CgMg) 140 | 141 | 142 | - - - 143 | 144 | 145 | ## Benchmark 146 | 147 | TOCOMPLETE 148 | 149 | ### Office+Caltech SURF 150 | 151 | | ID | Dim | Method | C->A | C->W | C->D | A->C | A->W | A->D | W->C | W->A | W->D | D->C | D->A | D->W | 152 | |----|-----|----------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------| 153 | | 1 | 100 | PCA+1NN | 36.95 | 32.54 | 38.22 | 34.73 | 35.59 | 27.39 | 26.36 | 31 | 77.07 | 29.65 | 32.05 | 75.93 | 154 | | 2 | 100 | GFK+1NN | 41.02 | 40.68 | 38.85 | 40.25 | 38.98 | 36.31 | 30.72 | 29.75 | 80.89 | 30.28 | 32.05 | 75.59 | 155 | | 3 | 100 | TCA+1NN | 38.2 | 38.64 | 41.4 | 37.76 | 37.63 | 33.12 | 29.3 | 30.06 | 87.26 | 31.7 | 32.15 | 86.1 | 156 | | 4 | 100 | TSL+1NN | 44.47 | 34.24 | 43.31 | 37.58 | 33.9 | 26.11 | 29.83 | 30.27 | 87.26 | 28.5 | 27.56 | 85.42 | 157 | | 5 | 100 | JDA+1NN | 44.78 | 41.69 | 45.22 | 39.36 | 37.97 | 39.49 | 31.17 | 32.78 | 89.17 | 31.52 | 33.09 | 89.49 | 158 | | 6 | 100 | UDA+1NN | 47.39 | 46.56 | 48.41 | 41.41 | 43.05 | 42.04 | 32.41 | 34.45 | 91.08 | 34.19 | 34.24 | 90.85 | 159 | | 7 | 30 | SA+1NN | 49.27 | 40 | 39.49 | 39.98 | 33.22 | 33.76 | 35.17 | 39.25 | 75.16 | 34.55 | 39.87 | 76.95 | 160 | | 8 | 30 | SDA+1NN | 49.69 | 38.98 | 40.13 | 39.54 | 30.85 | 33.76 | 34.73 | 39.25 | 75.8 | 35.89 | 38.73 | 76.95 | 161 | | 9 | 30 | GFK+1NN | 46.03 | 36.95 | 40.76 | 40.69 | 36.95 | 40.13 | 24.76 | 27.56 | 85.35 | 29.3 | 28.71 | 80.34 | 162 | | 10 | 30 | TCA+1NN | 45.82 | 31.19 | 34.39 | 42.39 | 36.27 | 33.76 | 29.39 | 28.91 | 89.17 | 30.72 | 31 | 86.1 | 163 | | 11 | 30 | JDA+1NN | 45.62 | 41.69 | 45.22 | 39.36 | 37.97 | 39.49 | 31.17 | 32.78 | 89.17 | 31.52 | 33.09 | 89.49 | 164 | | 12 | 30 | TJM+1NN | 46.76 | 38.98 | 44.59 | 39.45 | 42.03 | 45.22 | 30.19 | 29.96 | 89.17 | 31.43 | 32.78 | 85.42 | 165 | | 13 | 30 | SCA+1NN | 45.62 | 40 | 47.13 | 39.72 | 34.92 | 39.49 | 31.08 | 29.96 | 87.26 | 30.72 | 31.63 | 84.41 | 166 | | 14 | 30 | JGSAprimal+1NN | 51.46 | 45.42 | 45.86 | 41.5 | 45.76 | 47.13 | 33.21 | 39.87 | 90.45 | 29.92 | 38 | 91.86 | 167 | | 15 | 30 | JGSAlinear+1NN | 52.3 | 45.76 | 48.41 | 38.11 | 49.49 | 45.86 | 32.68 | 41.02 | 90.45 | 30.19 | 36.01 | 91.86 | 168 | | 16 | 30 | JGSArbf+1NN | 53.13 | 48.47 | 48.41 | 41.5 | 45.08 | 45.22 | 33.57 | 40.81 | 88.54 | 30.28 | 38.73 | 93.22 | 169 | | 17 | 20 | PCA+1NN | 36.95 | 32.54 | 38.22 | 34.73 | 35.59 | 27.39 | 26.36 | 29.35 | 77.07 | 29.65 | 32.05 | 75.93 | 170 | | 18 | 20 | FSSL+1NN | 35.88 | 32.32 | 37.53 | 33.91 | 34.35 | 26.37 | 25.85 | 29.53 | 76.79 | 27.89 | 30.61 | 74.99 | 171 | | 19 | 20 | TCA+1NN | 45.82 | 30.51 | 35.67 | 40.07 | 35.25 | 34.39 | 29.92 | 28.81 | 85.99 | 32.06 | 31.42 | 86.44 | 172 | | 20 | 20 | GFK+1NN | 41.02 | 40.68 | 38.85 | 40.25 | 38.98 | 36.31 | 30.72 | 29.75 | 80.89 | 30.28 | 32.05 | 75.59 | 173 | | 21 | 20 | TJM+1NN | 46.76 | 38.98 | 44.59 | 39.45 | 42.03 | 45.22 | 30.19 | 29.96 | 89.17 | 31.43 | 32.78 | 85.42 | 174 | | 22 | 20 | VDA+1NN | 46.14 | 46.1 | 51.59 | 42.21 | 51.19 | 48.41 | 27.6 | 26.1 | 89.18 | 31.26 | 37.68 | 90.85 | 175 | | 23 | no | 1NN | 23.7 | 25.76 | 25.48 | 26 | 29.83 | 25.48 | 19.86 | 22.96 | 59.24 | 26.27 | 28.5 | 63.39 | 176 | | 24 | no | SVM | 55.64 | 45.22 | 43.73 | 45.77 | 42.04 | 39.66 | 31.43 | 34.76 | 82.8 | 29.39 | 26.62 | 63.39 | 177 | | 25 | no | LapSVM | 56.27 | 45.8 | 43.73 | 44.23 | 42.74 | 39.79 | 31.99 | 34.77 | 83.43 | 29.49 | 27.37 | 64.31 | 178 | | 26 | no | TKL+SVM | 54.28 | 46.5 | 51.19 | 45.59 | 49.04 | 46.44 | 34.82 | 40.92 | 83.44 | 35.8 | 40.71 | 84.75 | 179 | | 27 | no | KMM+SVM | 48.32 | 45.78 | 53.53 | 42.21 | 42.38 | 42.72 | 29.01 | 31.94 | 71.98 | 31.61 | 32.2 | 72.88 | 180 | | 28 | no | DTMKL+SVM | 54.33 | 42.04 | 44.74 | 45.01 | 36.94 | 40.85 | 32.5 | 36.53 | 88.85 | 32.1 | 34.03 | 81.69 | 181 | | 29 | no | SKM+SVM | 53.97 | 43.31 | 43.05 | 44.7 | 37.58 | 42.37 | 31.34 | 35.07 | 89.81 | 30.37 | 30.27 | 81.02 | 182 | 183 | **Results are coming from:** 184 | 185 | - 1~5:[4] 186 | - 6~15: [11] 187 | - 16~21: [12] 188 | - 22~28: [13] 189 | 190 | - - - 191 | 192 | 193 | ### References 194 | 195 | [1] Gong B, Shi Y, Sha F, et al. Geodesic flow kernel for unsupervised domain adaptation[C]//Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on. IEEE, 2012: 2066-2073. 196 | 197 | [2] Russell B C, Torralba A, Murphy K P, et al. LabelMe: a database and web-based tool for image annotation[J]. International journal of computer vision, 2008, 77(1): 157-173. 198 | 199 | [3] Griffin G, Holub A, Perona P. Caltech-256 object category dataset[J]. 2007. 200 | 201 | [4] Long M, Wang J, Ding G, et al. Transfer feature learning with joint distribution adaptation[C]//Proceedings of the IEEE International Conference on Computer Vision. 2013: 2200-2207. 202 | 203 | [5] http://attributes.kyb.tuebingen.mpg.de/ 204 | 205 | [6] http://www.cs.cmu.edu/afs/cs/project/PIE/MultiPie/Multi-Pie/Home.html 206 | 207 | [7] http://www.cs.dartmouth.edu/~chenfang/proj_page/FXR_iccv13/ 208 | 209 | [8] M. Everingham, L. Van-Gool, C. K. Williams, J. Winn, and A. Zisserman, “The pascal visual object classes (VOC) challenge,” Int. J. Comput. Vis., vol. 88, no. 2, pp. 303–338, 2010. 210 | 211 | [9] M. J. Choi, J. J. Lim, A. Torralba, and A. S. Willsky, “Exploiting hierarchical context on a large database of object categories,” in Proc. IEEE Conf. Comput. Vis. Pattern Recogit., 2010, pp. 129–136 212 | 213 | [10] http://www.uow.edu.au/~jz960/ 214 | 215 | [11] Zhang J, Li W, Ogunbona P. Joint Geometrical and Statistical Alignment for Visual Domain Adaptation[C]. CVPR 2017. 216 | 217 | [12] Tahmoresnezhad J, Hashemi S. Visual domain adaptation via transfer feature learning[J]. Knowledge and Information Systems, 2017, 50(2): 585-605. 218 | 219 | [13] Long M, Wang J, Sun J, et al. Domain invariant transfer kernel learning[J]. IEEE Transactions on Knowledge and Data Engineering, 2015, 27(6): 1519-1532. -------------------------------------------------------------------------------- /code/MyARTL/lapgraph.m: -------------------------------------------------------------------------------- 1 | function [W, elapse] = lapgraph(fea,options) 2 | % Usage: 3 | % W = graph(fea,options) 4 | % 5 | % fea: Rows of vectors of data points. Each row is x_i 6 | % options: Struct value in Matlab. The fields in options that can be set: 7 | % Metric - Choices are: 8 | % 'Euclidean' - Will use the Euclidean distance of two data 9 | % points to evaluate the "closeness" between 10 | % them. [Default One] 11 | % 'Cosine' - Will use the cosine value of two vectors 12 | % to evaluate the "closeness" between them. 13 | % A popular similarity measure used in 14 | % Information Retrieval. 15 | % 16 | % NeighborMode - Indicates how to construct the graph. Choices 17 | % are: [Default 'KNN'] 18 | % 'KNN' - k = 0 19 | % Complete graph 20 | % k > 0 21 | % Put an edge between two nodes if and 22 | % only if they are among the k nearst 23 | % neighbors of each other. You are 24 | % required to provide the parameter k in 25 | % the options. Default k=5. 26 | % 'Supervised' - k = 0 27 | % Put an edge between two nodes if and 28 | % only if they belong to same class. 29 | % k > 0 30 | % Put an edge between two nodes if 31 | % they belong to same class and they 32 | % are among the k nearst neighbors of 33 | % each other. 34 | % Default: k=0 35 | % You are required to provide the label 36 | % information gnd in the options. 37 | % 38 | % WeightMode - Indicates how to assign weights for each edge 39 | % in the graph. Choices are: 40 | % 'Binary' - 0-1 weighting. Every edge receiveds weight 41 | % of 1. [Default One] 42 | % 'HeatKernel' - If nodes i and j are connected, put weight 43 | % W_ij = exp(-norm(x_i - x_j)/2t^2). This 44 | % weight mode can only be used under 45 | % 'Euclidean' metric and you are required to 46 | % provide the parameter t. 47 | % 'Cosine' - If nodes i and j are connected, put weight 48 | % cosine(x_i,x_j). Can only be used under 49 | % 'Cosine' metric. 50 | % 51 | % k - The parameter needed under 'KNN' NeighborMode. 52 | % Default will be 5. 53 | % gnd - The parameter needed under 'Supervised' 54 | % NeighborMode. Colunm vector of the label 55 | % information for each data point. 56 | % bLDA - 0 or 1. Only effective under 'Supervised' 57 | % NeighborMode. If 1, the graph will be constructed 58 | % to make LPP exactly same as LDA. Default will be 59 | % 0. 60 | % t - The parameter needed under 'HeatKernel' 61 | % WeightMode. Default will be 1 62 | % bNormalized - 0 or 1. Only effective under 'Cosine' metric. 63 | % Indicates whether the fea are already be 64 | % normalized to 1. Default will be 0 65 | % bSelfConnected - 0 or 1. Indicates whether W(i,i) == 1. Default 1 66 | % if 'Supervised' NeighborMode & bLDA == 1, 67 | % bSelfConnected will always be 1. Default 1. 68 | % 69 | % 70 | % Examples: 71 | % 72 | % fea = rand(50,15); 73 | % options = []; 74 | % options.Metric = 'Euclidean'; 75 | % options.NeighborMode = 'KNN'; 76 | % options.k = 5; 77 | % options.WeightMode = 'HeatKernel'; 78 | % options.t = 1; 79 | % W = constructW(fea,options); 80 | % 81 | % 82 | % fea = rand(50,15); 83 | % gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4]; 84 | % options = []; 85 | % options.Metric = 'Euclidean'; 86 | % options.NeighborMode = 'Supervised'; 87 | % options.gnd = gnd; 88 | % options.WeightMode = 'HeatKernel'; 89 | % options.t = 1; 90 | % W = constructW(fea,options); 91 | % 92 | % 93 | % fea = rand(50,15); 94 | % gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4]; 95 | % options = []; 96 | % options.Metric = 'Euclidean'; 97 | % options.NeighborMode = 'Supervised'; 98 | % options.gnd = gnd; 99 | % options.bLDA = 1; 100 | % W = constructW(fea,options); 101 | % 102 | % 103 | % For more details about the different ways to construct the W, please 104 | % refer: 105 | % Deng Cai, Xiaofei He and Jiawei Han, "Document Clustering Using 106 | % Locality Preserving Indexing" IEEE TKDE, Dec. 2005. 107 | % 108 | % 109 | % Written by Deng Cai (dengcai2 AT cs.uiuc.edu), April/2004, Feb/2006, 110 | % May/2007 111 | % 112 | 113 | if (~exist('options','var')) 114 | options = []; 115 | else 116 | if ~isstruct(options) 117 | error('parameter error!'); 118 | end 119 | end 120 | 121 | %================================================= 122 | if ~isfield(options,'Metric') 123 | options.Metric = 'Cosine'; 124 | end 125 | 126 | switch lower(options.Metric) 127 | case {lower('Euclidean')} 128 | case {lower('Cosine')} 129 | if ~isfield(options,'bNormalized') 130 | options.bNormalized = 0; 131 | end 132 | otherwise 133 | error('Metric does not exist!'); 134 | end 135 | 136 | %================================================= 137 | if ~isfield(options,'NeighborMode') 138 | options.NeighborMode = 'KNN'; 139 | end 140 | 141 | switch lower(options.NeighborMode) 142 | case {lower('KNN')} %For simplicity, we include the data point itself in the kNN 143 | if ~isfield(options,'k') 144 | options.k = 5; 145 | end 146 | case {lower('Supervised')} 147 | if ~isfield(options,'bLDA') 148 | options.bLDA = 0; 149 | end 150 | if options.bLDA 151 | options.bSelfConnected = 1; 152 | end 153 | if ~isfield(options,'k') 154 | options.k = 0; 155 | end 156 | if ~isfield(options,'gnd') 157 | error('Label(gnd) should be provided under ''Supervised'' NeighborMode!'); 158 | end 159 | if ~isempty(fea) && length(options.gnd) ~= size(fea,1) 160 | error('gnd doesn''t match with fea!'); 161 | end 162 | otherwise 163 | error('NeighborMode does not exist!'); 164 | end 165 | 166 | %================================================= 167 | 168 | if ~isfield(options,'WeightMode') 169 | options.WeightMode = 'Binary'; 170 | end 171 | 172 | bBinary = 0; 173 | switch lower(options.WeightMode) 174 | case {lower('Binary')} 175 | bBinary = 1; 176 | case {lower('HeatKernel')} 177 | if ~strcmpi(options.Metric,'Euclidean') 178 | warning('''HeatKernel'' WeightMode should be used under ''Euclidean'' Metric!'); 179 | options.Metric = 'Euclidean'; 180 | end 181 | if ~isfield(options,'t') 182 | options.t = 1; 183 | end 184 | case {lower('Cosine')} 185 | if ~strcmpi(options.Metric,'Cosine') 186 | warning('''Cosine'' WeightMode should be used under ''Cosine'' Metric!'); 187 | options.Metric = 'Cosine'; 188 | end 189 | if ~isfield(options,'bNormalized') 190 | options.bNormalized = 0; 191 | end 192 | otherwise 193 | error('WeightMode does not exist!'); 194 | end 195 | 196 | %================================================= 197 | 198 | if ~isfield(options,'bSelfConnected') 199 | options.bSelfConnected = 1; 200 | end 201 | 202 | %================================================= 203 | tmp_T = cputime; 204 | 205 | if isfield(options,'gnd') 206 | nSmp = length(options.gnd); 207 | else 208 | nSmp = size(fea,1); 209 | end 210 | maxM = 62500000; %500M 211 | BlockSize = floor(maxM/(nSmp*3)); 212 | 213 | 214 | if strcmpi(options.NeighborMode,'Supervised') 215 | Label = unique(options.gnd); 216 | nLabel = length(Label); 217 | if options.bLDA 218 | G = zeros(nSmp,nSmp); 219 | for idx=1:nLabel 220 | classIdx = options.gnd==Label(idx); 221 | G(classIdx,classIdx) = 1/sum(classIdx); 222 | end 223 | W = sparse(G); 224 | elapse = cputime - tmp_T; 225 | return; 226 | end 227 | 228 | switch lower(options.WeightMode) 229 | case {lower('Binary')} 230 | if options.k > 0 231 | G = zeros(nSmp*(options.k+1),3); 232 | idNow = 0; 233 | for i=1:nLabel 234 | classIdx = find(options.gnd==Label(i)); 235 | D = EuDist2(fea(classIdx,:),[],0); 236 | [dump idx] = sort(D,2); % sort each row 237 | clear D dump; 238 | idx = idx(:,1:options.k+1); 239 | 240 | nSmpClass = length(classIdx)*(options.k+1); 241 | G(idNow+1:nSmpClass+idNow,1) = repmat(classIdx,[options.k+1,1]); 242 | G(idNow+1:nSmpClass+idNow,2) = classIdx(idx(:)); 243 | G(idNow+1:nSmpClass+idNow,3) = 1; 244 | idNow = idNow+nSmpClass; 245 | clear idx 246 | end 247 | G = sparse(G(:,1),G(:,2),G(:,3),nSmp,nSmp); 248 | G = max(G,G'); 249 | else 250 | G = zeros(nSmp,nSmp); 251 | for i=1:nLabel 252 | classIdx = find(options.gnd==Label(i)); 253 | G(classIdx,classIdx) = 1; 254 | end 255 | end 256 | 257 | if ~options.bSelfConnected 258 | for i=1:size(G,1) 259 | G(i,i) = 0; 260 | end 261 | end 262 | 263 | W = sparse(G); 264 | case {lower('HeatKernel')} 265 | if options.k > 0 266 | G = zeros(nSmp*(options.k+1),3); 267 | idNow = 0; 268 | for i=1:nLabel 269 | classIdx = find(options.gnd==Label(i)); 270 | D = EuDist2(fea(classIdx,:),[],0); 271 | [dump idx] = sort(D,2); % sort each row 272 | clear D; 273 | idx = idx(:,1:options.k+1); 274 | dump = dump(:,1:options.k+1); 275 | dump = exp(-dump/(2*options.t^2)); 276 | 277 | nSmpClass = length(classIdx)*(options.k+1); 278 | G(idNow+1:nSmpClass+idNow,1) = repmat(classIdx,[options.k+1,1]); 279 | G(idNow+1:nSmpClass+idNow,2) = classIdx(idx(:)); 280 | G(idNow+1:nSmpClass+idNow,3) = dump(:); 281 | idNow = idNow+nSmpClass; 282 | clear dump idx 283 | end 284 | G = sparse(G(:,1),G(:,2),G(:,3),nSmp,nSmp); 285 | else 286 | G = zeros(nSmp,nSmp); 287 | for i=1:nLabel 288 | classIdx = find(options.gnd==Label(i)); 289 | D = EuDist2(fea(classIdx,:),[],0); 290 | D = exp(-D/(2*options.t^2)); 291 | G(classIdx,classIdx) = D; 292 | end 293 | end 294 | 295 | if ~options.bSelfConnected 296 | for i=1:size(G,1) 297 | G(i,i) = 0; 298 | end 299 | end 300 | 301 | W = sparse(max(G,G')); 302 | case {lower('Cosine')} 303 | if ~options.bNormalized 304 | [nSmp, nFea] = size(fea); 305 | if issparse(fea) 306 | fea2 = fea'; 307 | feaNorm = sum(fea2.^2,1).^.5; 308 | for i = 1:nSmp 309 | fea2(:,i) = fea2(:,i) ./ max(1e-10,feaNorm(i)); 310 | end 311 | fea = fea2'; 312 | clear fea2; 313 | else 314 | feaNorm = sum(fea.^2,2).^.5; 315 | for i = 1:nSmp 316 | fea(i,:) = fea(i,:) ./ max(1e-12,feaNorm(i)); 317 | end 318 | end 319 | 320 | end 321 | 322 | if options.k > 0 323 | G = zeros(nSmp*(options.k+1),3); 324 | idNow = 0; 325 | for i=1:nLabel 326 | classIdx = find(options.gnd==Label(i)); 327 | D = fea(classIdx,:)*fea(classIdx,:)'; 328 | [dump idx] = sort(-D,2); % sort each row 329 | clear D; 330 | idx = idx(:,1:options.k+1); 331 | dump = -dump(:,1:options.k+1); 332 | 333 | nSmpClass = length(classIdx)*(options.k+1); 334 | G(idNow+1:nSmpClass+idNow,1) = repmat(classIdx,[options.k+1,1]); 335 | G(idNow+1:nSmpClass+idNow,2) = classIdx(idx(:)); 336 | G(idNow+1:nSmpClass+idNow,3) = dump(:); 337 | idNow = idNow+nSmpClass; 338 | clear dump idx 339 | end 340 | G = sparse(G(:,1),G(:,2),G(:,3),nSmp,nSmp); 341 | else 342 | G = zeros(nSmp,nSmp); 343 | for i=1:nLabel 344 | classIdx = find(options.gnd==Label(i)); 345 | G(classIdx,classIdx) = fea(classIdx,:)*fea(classIdx,:)'; 346 | end 347 | end 348 | 349 | if ~options.bSelfConnected 350 | for i=1:size(G,1) 351 | G(i,i) = 0; 352 | end 353 | end 354 | 355 | W = sparse(max(G,G')); 356 | otherwise 357 | error('WeightMode does not exist!'); 358 | end 359 | elapse = cputime - tmp_T; 360 | return; 361 | end 362 | 363 | 364 | if strcmpi(options.NeighborMode,'KNN') && (options.k > 0) 365 | if strcmpi(options.Metric,'Euclidean') 366 | G = zeros(nSmp*(options.k+1),3); 367 | for i = 1:ceil(nSmp/BlockSize) 368 | if i == ceil(nSmp/BlockSize) 369 | smpIdx = (i-1)*BlockSize+1:nSmp; 370 | dist = EuDist2(fea(smpIdx,:),fea,0); 371 | dist = full(dist); 372 | [dump idx] = sort(dist,2); % sort each row 373 | idx = idx(:,1:options.k+1); 374 | dump = dump(:,1:options.k+1); 375 | if ~bBinary 376 | dump = exp(-dump/(2*options.t^2)); 377 | end 378 | 379 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),1) = repmat(smpIdx',[options.k+1,1]); 380 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),2) = idx(:); 381 | if ~bBinary 382 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),3) = dump(:); 383 | else 384 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),3) = 1; 385 | end 386 | else 387 | smpIdx = (i-1)*BlockSize+1:i*BlockSize; 388 | dist = EuDist2(fea(smpIdx,:),fea,0); 389 | dist = full(dist); 390 | [dump idx] = sort(dist,2); % sort each row 391 | idx = idx(:,1:options.k+1); 392 | dump = dump(:,1:options.k+1); 393 | if ~bBinary 394 | dump = exp(-dump/(2*options.t^2)); 395 | end 396 | 397 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),1) = repmat(smpIdx',[options.k+1,1]); 398 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),2) = idx(:); 399 | if ~bBinary 400 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),3) = dump(:); 401 | else 402 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),3) = 1; 403 | end 404 | end 405 | end 406 | 407 | W = sparse(G(:,1),G(:,2),G(:,3),nSmp,nSmp); 408 | else 409 | if ~options.bNormalized 410 | [nSmp, nFea] = size(fea); 411 | if issparse(fea) 412 | fea2 = fea'; 413 | clear fea; 414 | for i = 1:nSmp 415 | fea2(:,i) = fea2(:,i) ./ max(1e-10,sum(fea2(:,i).^2,1).^.5); 416 | end 417 | fea = fea2'; 418 | clear fea2; 419 | else 420 | feaNorm = sum(fea.^2,2).^.5; 421 | for i = 1:nSmp 422 | fea(i,:) = fea(i,:) ./ max(1e-12,feaNorm(i)); 423 | end 424 | end 425 | end 426 | 427 | G = zeros(nSmp*(options.k+1),3); 428 | for i = 1:ceil(nSmp/BlockSize) 429 | if i == ceil(nSmp/BlockSize) 430 | smpIdx = (i-1)*BlockSize+1:nSmp; 431 | dist = fea(smpIdx,:)*fea'; 432 | dist = full(dist); 433 | [dump idx] = sort(-dist,2); % sort each row 434 | idx = idx(:,1:options.k+1); 435 | dump = -dump(:,1:options.k+1); 436 | 437 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),1) = repmat(smpIdx',[options.k+1,1]); 438 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),2) = idx(:); 439 | G((i-1)*BlockSize*(options.k+1)+1:nSmp*(options.k+1),3) = dump(:); 440 | else 441 | smpIdx = (i-1)*BlockSize+1:i*BlockSize; 442 | dist = fea(smpIdx,:)*fea'; 443 | dist = full(dist); 444 | [dump idx] = sort(-dist,2); % sort each row 445 | idx = idx(:,1:options.k+1); 446 | dump = -dump(:,1:options.k+1); 447 | 448 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),1) = repmat(smpIdx',[options.k+1,1]); 449 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),2) = idx(:); 450 | G((i-1)*BlockSize*(options.k+1)+1:i*BlockSize*(options.k+1),3) = dump(:); 451 | end 452 | end 453 | 454 | W = sparse(G(:,1),G(:,2),G(:,3),nSmp,nSmp); 455 | end 456 | 457 | if strcmpi(options.WeightMode,'Binary') 458 | W(find(W)) = 1; 459 | end 460 | 461 | if isfield(options,'bSemiSupervised') && options.bSemiSupervised 462 | tmpgnd = options.gnd(options.semiSplit); 463 | 464 | Label = unique(tmpgnd); 465 | nLabel = length(Label); 466 | G = zeros(sum(options.semiSplit),sum(options.semiSplit)); 467 | for idx=1:nLabel 468 | classIdx = tmpgnd==Label(idx); 469 | G(classIdx,classIdx) = 1; 470 | end 471 | Wsup = sparse(G); 472 | if ~isfield(options,'SameCategoryWeight') 473 | options.SameCategoryWeight = 1; 474 | end 475 | W(options.semiSplit,options.semiSplit) = (Wsup>0)*options.SameCategoryWeight; 476 | end 477 | 478 | if ~options.bSelfConnected 479 | for i=1:size(W,1) 480 | W(i,i) = 0; 481 | end 482 | end 483 | 484 | W = max(W,W'); 485 | 486 | elapse = cputime - tmp_T; 487 | return; 488 | end 489 | 490 | 491 | % strcmpi(options.NeighborMode,'KNN') & (options.k == 0) 492 | % Complete Graph 493 | 494 | if strcmpi(options.Metric,'Euclidean') 495 | W = EuDist2(fea,[],0); 496 | W = exp(-W/(2*options.t^2)); 497 | else 498 | if ~options.bNormalized 499 | % feaNorm = sum(fea.^2,2).^.5; 500 | % fea = fea ./ repmat(max(1e-10,feaNorm),1,size(fea,2)); 501 | [nSmp, nFea] = size(fea); 502 | if issparse(fea) 503 | fea2 = fea'; 504 | feaNorm = sum(fea2.^2,1).^.5; 505 | for i = 1:nSmp 506 | fea2(:,i) = fea2(:,i) ./ max(1e-10,feaNorm(i)); 507 | end 508 | fea = fea2'; 509 | clear fea2; 510 | else 511 | feaNorm = sum(fea.^2,2).^.5; 512 | for i = 1:nSmp 513 | fea(i,:) = fea(i,:) ./ max(1e-12,feaNorm(i)); 514 | end 515 | end 516 | end 517 | 518 | % W = full(fea*fea'); 519 | W = fea*fea'; 520 | end 521 | 522 | if ~options.bSelfConnected 523 | for i=1:size(W,1) 524 | W(i,i) = 0; 525 | end 526 | end 527 | 528 | W = max(W,W'); 529 | 530 | 531 | 532 | elapse = cputime - tmp_T; 533 | 534 | 535 | function D = EuDist2(fea_a,fea_b,bSqrt) 536 | % Euclidean Distance matrix 537 | % D = EuDist(fea_a,fea_b) 538 | % fea_a: nSample_a * nFeature 539 | % fea_b: nSample_b * nFeature 540 | % D: nSample_a * nSample_a 541 | % or nSample_a * nSample_b 542 | 543 | 544 | if ~exist('bSqrt','var') 545 | bSqrt = 1; 546 | end 547 | 548 | 549 | if (~exist('fea_b','var')) | isempty(fea_b) 550 | [nSmp, nFea] = size(fea_a); 551 | 552 | aa = sum(fea_a.*fea_a,2); 553 | ab = fea_a*fea_a'; 554 | 555 | aa = full(aa); 556 | ab = full(ab); 557 | 558 | if bSqrt 559 | D = sqrt(repmat(aa, 1, nSmp) + repmat(aa', nSmp, 1) - 2*ab); 560 | D = real(D); 561 | else 562 | D = repmat(aa, 1, nSmp) + repmat(aa', nSmp, 1) - 2*ab; 563 | end 564 | 565 | D = max(D,D'); 566 | D = D - diag(diag(D)); 567 | D = abs(D); 568 | else 569 | [nSmp_a, nFea] = size(fea_a); 570 | [nSmp_b, nFea] = size(fea_b); 571 | 572 | aa = sum(fea_a.*fea_a,2); 573 | bb = sum(fea_b.*fea_b,2); 574 | ab = fea_a*fea_b'; 575 | 576 | aa = full(aa); 577 | bb = full(bb); 578 | ab = full(ab); 579 | 580 | if bSqrt 581 | D = sqrt(repmat(aa, 1, nSmp_b) + repmat(bb', nSmp_a, 1) - 2*ab); 582 | D = real(D); 583 | else 584 | D = repmat(aa, 1, nSmp_b) + repmat(bb', nSmp_a, 1) - 2*ab; 585 | end 586 | 587 | D = abs(D); 588 | end 589 | 590 | --------------------------------------------------------------------------------