1.领域
领域是学习的主体,由数据和生成这些数据的概率分布构成。一个领域可以如下表示:
D={X, Y, P(x,y)}
X:数据所处特征空间
Y:数据对应标签空间
P:概率分布
2.迁移学习形式化定义
给定一个源域Ds和目标域Dt,迁移学习目标如下:
(1)特征空间不同,Xs != Xt
(2)标签空间不同,Ys != Yt
(3)特征和类别空间相同、概率分布不同,Ps != Pt
至少有一种成立时,利用源域数据去学习一个目标域上的预测函数。
3.领域自适应
给定一个源域Ds和目标域Dt,领域自适应的目标是当特征空间和类别空间均相同,但联合概率分布不同时,利用源域数据去学习一个目标域上的预测函数。
4.迁移学习的三个基本问题
何时迁移、何处迁移、如何迁移
5.负迁移
用R(A(Ds,Dt))表示源域Ds和目标域Dt使用迁移学习算法后产生的误差。当满足以下情况时,发生了负迁移:
R(A(Ds,Dt)) > R(A'(Ds,Dt))
A’(Ds,Dt)表示不经过迁移学习的误差。
6.迁移学习过程:
数据->问题定义与迁移性分析->迁移过程->模型选择->应用与部署
7.迁移学习的核心
找到源域和目标域的相似性。度量两个领域的相似性,定性定量地给出相似程度;以度量为准则,通过采用的手段,增大两个领域之间的相似性。
8. 迁移学习的分布度量
(1)边缘分布自适应
针对源域和目标域的边缘概率分布不同,并假设二者的条件概率分布相同,用源域和目标域之间的边缘分布距离来近似二者之间的联合概率分布距离
D(Ps(x,y),Pt(x,y)) ~= D(Ps(x),Pt(x))
(2)条件分布自适应
针对源域和目标域的边缘概率分布相同,而条件概率分布不同,用源域和目标域之间的条件分布距离来近似二者之间的联合概率分布距离
D(Ps(x,y),Pt(x,y)) ~= D(Ps(y|x),Pt(y|x))
(3)联合分布自适应
用源域和目标域之间的边缘分布距离和条件分布距离来近似二者之间的联合概率分布距离
D(Ps(x,y),Pt(x,y)) ~= D(Ps(y|x),Pt(y|x)) + D(Ps(x),Pt(x))
(4)动态分布自适应
边缘分布自适应和条件分布自适应不是同等重要,利用平衡因子u来调整两个分布之间的距离。
D(Ds,Dt) ~= u*D(Ps(y|x),Pt(y|x)) + (1-u)*D(Ps(x),Pt(x))
9.分布自适应因子的计算
A-distance定义为建立一个二分类器进行两个不同领域的分类得出的误差,s(h)定义为线性分类器h的分类误差
dA(Ds, Dt) = 2*(1-2*s(h))
分别计算边缘分布和条件分布的A-distance,并用dM和dC来表示
u = 1 - dM / (dM + ∑dc)
c=1~C
10.迁移学习统一表征
迁移学习统一表征为以下形式:
由此派生出三个迁移学习方法:
样本权重迁移法:学习源域样本的权重,用于源域和目标域的相似度高情况下
特征变换迁移法:学习一个特征变换T来减少正则化项,用于两者概率分布差异较大,变换有统计特征变换和几何特征变换
模型预训练迁移法:将源域判别函数fs对目标域数据进行正则化和微调,预训练-微调模型
11.在office31数据集上实践
from scipy import io
import os
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
def load_data(floder, domain):
data = io.loadmat(os.path.join(floder, domain + '_fc6.mat'))
# io.loadmat 加载 MATLAB 文件
# 返回:以变量名作为键的字典,并将加载的矩阵作为值。
# print(data)
return data['fts'], data['labels']
def knn_classify(Xs,Ys,Xt,Yt, k=1):
model = KNeighborsClassifier(n_neighbors=k)
Ys = Ys.ravel()
# Ys.ravel() 将数组多维度拉成一维数组。
Yt = Yt.ravel()
model.fit(Xs, Ys)
Yt_pred = model.predict(Xt)
acc = accuracy_score(Yt, Yt_pred)
print('Accuracy using KNN: {:.2f}%'.format(acc * 100))
if __name__ == "__main__":
folder = './office31-decaf'
src_domain = 'amazon'
tar_domain = 'dslr'
Xs, Ys = load_data(folder, src_domain)
Xt, Yt = load_data(folder, tar_domain)
print('Source:', src_domain, Xs.shape, Ys.shape)
print('Target:', tar_domain, Xt.shape, Yt.shape)
knn_classify(Xs, Ys, Xt, Yt)