Skip to content

Commit 17e8b65

Browse files
committed
upd: contents
1 parent 9c79048 commit 17e8b65

5 files changed

Lines changed: 227 additions & 20 deletions

File tree

src/chaps/ch00_prefix.tex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ \section*{说明}
7676

7777
第6章到第8章,介绍了领域自适应的3大类基本的方法,分别是:数据分布自适应法、特征选择法、子空间学习法。
7878

79-
第9章重点介绍了目前持续最火的深度迁移学习方法
79+
第9章重点介绍了目前主流的深度迁移学习方法
8080

8181
第10章提供了简单的上手实践教程。
8282

@@ -90,6 +90,8 @@ \section*{说明}
9090

9191
\textbf{手册的相关资源:}
9292

93+
我们在Github上持续维护了迁移学习的资源仓库,包括论文、代码、文档、比赛等,请读者持续关注:\url{https://github.com/jindongwang/transferlearning},配合本手册更香哦!
94+
9395
网站(内含勘误表):\url{http://t.cn/RmasEFe}
9496

9597
开发维护地址: \url{http://github.com/jindongwang/transferlearning-tutorial}

src/chaps/ch10_practice.tex

Lines changed: 202 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ \section{上手实践}
4949

5050
在众多的非深度迁移学习方法中,我们选择最经典的迁移方法之一、发表于IEEE TNN 2011的TCA(Transfer Component Analysis)~\cite{pan2011domain}方法进行实践。为了便于学习,我们同时用Matlab和Python实现了此代码。代码的链接为\url{https://github.com/jindongwang/transferlearning/tree/master/code/traditional/TCA}。下面我们对代码进行简单讲解。
5151

52+
\subsection{TCA方法代码实现}
53+
5254
\subsubsection{Matlab}
5355

5456
\textbf{1. 数据获取}
@@ -254,7 +256,7 @@ \subsubsection{Python}
254256

255257
与Matlab代码类似,我们也可以用Python对TCA进行实现,其主要依赖于Numpy和Scipy两个强大的科学计算库。Python版本的TCA代码如下:
256258

257-
\begin{lstlisting}[title=TCA方法的Matlab实现, frame=shadowbox]
259+
\begin{lstlisting}[title=TCA方法的Python实现, frame=shadowbox]
258260

259261
import numpy as np
260262
import scipy.io
@@ -355,8 +357,205 @@ \subsubsection{Python}
355357

356358
通过以上过程,我们分别使用Matlab代码和Python代码对经典的TCA方法进行了实验,完成了一个迁移学习任务。其他的非深度迁移学习方法,均可以参考上面的过程。值得庆幸的是,许多论文的作者都公布了他们的文章代码,以方便我们进行接下来的研究。读者可以从Github~\footnote{\url{https://github.com/jindongwang/transferlearning/tree/master/code}}或者相关作者的网站上获取其他许多方法的代码。
357359

358-
%\subsection{深度网络的finetune}
360+
\subsection{深度网络的finetune代码实现}
361+
362+
本小节我们用Pytorch实现一个深度网络的finetune。Pytorch是一个较为流行的深度学习工具包,由Facebook进行开发,在Github~\footnote{\url{https://github.com/pytorch/pytorch}}上也进行了开源。
363+
364+
Finetune指的是训练好的深度网络,拿来在新的目标域上进行微调。因此,我们假定读者具有基本的Pytorch知识,直接给出finetune的代码。完整的代码可以在这里~\footnote{\url{https://github.com/jindongwang/transferlearning/tree/master/code/deep/finetune_AlexNet_ResNet}}找到。
365+
366+
我们定义一个叫做finetune的函数,它接受输入的一个已有模型,从目标数据中进行微调,输出最好的模型其结果。其代码如下:
367+
368+
\begin{lstlisting}[title=深度网络的finetune代码实现, frame=shadowbox]
369+
370+
def finetune(model, dataloaders, optimizer):
371+
since = time.time()
372+
best_acc = 0.0
373+
acc_hist = []
374+
criterion = nn.CrossEntropyLoss()
375+
for epoch in range(1, N_EPOCH + 1):
376+
# lr_schedule(optimizer, epoch)
377+
print('Learning rate: {:.8f}'.format(optimizer.param_groups[0]['lr']))
378+
print('Learning rate: {:.8f}'.format(optimizer.param_groups[-1]['lr']))
379+
for phase in ['src', 'val', 'tar']:
380+
if phase == 'src':
381+
model.train()
382+
else:
383+
model.eval()
384+
total_loss, correct = 0, 0
385+
for inputs, labels in dataloaders[phase]:
386+
inputs, labels = inputs.to(DEVICE), labels.to(DEVICE)
387+
optimizer.zero_grad()
388+
with torch.set_grad_enabled(phase == 'src'):
389+
outputs = model(inputs)
390+
loss = criterion(outputs, labels)
391+
preds = torch.max(outputs, 1)[1]
392+
if phase == 'src':
393+
loss.backward()
394+
optimizer.step()
395+
total_loss += loss.item() * inputs.size(0)
396+
correct += torch.sum(preds == labels.data)
397+
epoch_loss = total_loss / len(dataloaders[phase].dataset)
398+
epoch_acc = correct.double() / len(dataloaders[phase].dataset)
399+
acc_hist.append([epoch_loss, epoch_acc])
400+
print('Epoch: [{:02d}/{:02d}]---{}, loss: {:.6f}, acc: {:.4f}'.format(epoch, N_EPOCH, phase, epoch_loss,
401+
epoch_acc))
402+
if phase == 'tar' and epoch_acc > best_acc:
403+
best_acc = epoch_acc
404+
print()
405+
fname = 'finetune_result' + model_name + \
406+
str(LEARNING_RATE) + str(args.source) + \
407+
'-' + str(args.target) + '.csv'
408+
np.savetxt(fname, np.asarray(a=acc_hist, dtype=float), delimiter=',',
409+
fmt='%.4f')
410+
time_pass = time.time() - since
411+
print('Training complete in {:.0f}m {:.0f}s'.format(
412+
time_pass // 60, time_pass % 60))
413+
414+
return model, best_acc, acc_hist
415+
416+
\end{lstlisting}
417+
418+
其中,model可以是由任意深度网络训练好的模型,如Alexnet、Resnet等。
419+
420+
另外,有很多任务也需要用到深度网络来提取深度特征以便进一步处理。我们也进行了实现,代码在\url{https://github.com/jindongwang/transferlearning/blob/master/code/feature_extractor}中。
421+
359422
%
360-
%\subsection{深度网络自适应}
423+
\subsection{深度网络自适应代码}
424+
425+
我们仍然以Pytorch为例,实现深度网络的自适应。具体地说,实现经典的DDC (Deep Domain Confusion)~\cite{tzeng2014deep}方法和与其类似的DCORAL (Deep CORAL)~\cite{sun2016deep}方法。
426+
427+
此网络实现的核心是:如何正确计算DDC中的MMD损失、以及DCORAL中的CORAL损失,并且与神经网络进行集成。此部分对于初学者难免有一些困惑。如何输入源域和目标域、如何进行判断?因此,我们认为此部分应该是深度迁移学习的基础代码,读者应该努力地进行学习和理解。
428+
429+
\textbf{网络结构}
430+
431+
首先我们要定义好网络的架构,其应该是来自于已有的网络结构,如Alexnet和Resnet。但不同的是,由于要进行深度迁移适配,因此,输出层要和finetune一样,和目标的类别数相同。其二,由于要进行距离的计算,我们需要加一个叫做bottleneck的层,用来将最高维的特征进行降维,然后进行距离计算。当然,bottleneck层不加尚可。
432+
433+
我们的网络结构如下所示:
434+
435+
\begin{lstlisting}[title=深度迁移网络代码实现, frame=shadowbox]
436+
import torch.nn as nn
437+
import torchvision
438+
from Coral import CORAL
439+
import mmd
440+
import backbone
441+
442+
443+
class Transfer_Net(nn.Module):
444+
def __init__(self, num_class, base_net='resnet50', transfer_loss='mmd', use_bottleneck=True, bottleneck_width=256, width=1024):
445+
super(Transfer_Net, self).__init__()
446+
self.base_network = backbone.network_dict[base_net]()
447+
self.use_bottleneck = use_bottleneck
448+
self.transfer_loss = transfer_loss
449+
bottleneck_list = [nn.Linear(self.base_network.output_num(
450+
), bottleneck_width), nn.BatchNorm1d(bottleneck_width), nn.ReLU(), nn.Dropout(0.5)]
451+
self.bottleneck_layer = nn.Sequential(*bottleneck_list)
452+
classifier_layer_list = [nn.Linear(self.base_network.output_num(), width), nn.ReLU(), nn.Dropout(0.5),
453+
nn.Linear(width, num_class)]
454+
self.classifier_layer = nn.Sequential(*classifier_layer_list)
455+
456+
self.bottleneck_layer[0].weight.data.normal_(0, 0.005)
457+
self.bottleneck_layer[0].bias.data.fill_(0.1)
458+
for i in range(2):
459+
self.classifier_layer[i * 3].weight.data.normal_(0, 0.01)
460+
self.classifier_layer[i * 3].bias.data.fill_(0.0)
461+
462+
def forward(self, source, target):
463+
source = self.base_network(source)
464+
target = self.base_network(target)
465+
source_clf = self.classifier_layer(source)
466+
if self.use_bottleneck:
467+
source = self.bottleneck_layer(source)
468+
target = self.bottleneck_layer(target)
469+
transfer_loss = self.adapt_loss(source, target, self.transfer_loss)
470+
return source_clf, transfer_loss
471+
472+
def predict(self, x):
473+
features = self.base_network(x)
474+
clf = self.classifier_layer(features)
475+
return clf
476+
477+
\end{lstlisting}
478+
479+
其中Transfer Net是整个网络的模型定义。它接受参数有:
480+
481+
\begin{itemize}
482+
\item num class: 目标域类别数
483+
\item base net: 主干网络,例如Resnet等,也可以是自己定义的网络结构
484+
\item Transfer loss: 迁移的损失,比如MMD和CORAL,也可以是自己定义的损失
485+
\item use bottleneck: 是否使用bottleneck
486+
\item bottleneck width: bottleneck的宽度
487+
\item width: 分类器层的width
488+
\end{itemize}
489+
490+
\textbf{迁移损失定义}
491+
492+
迁移损失是核心。其定义如下:
493+
494+
\begin{lstlisting}[title=深度迁移网络代码实现, frame=shadowbox]
495+
496+
def adapt_loss(self, X, Y, adapt_loss):
497+
"""Compute adaptation loss, currently we support mmd and coral
498+
Arguments:
499+
X {tensor} -- source matrix
500+
Y {tensor} -- target matrix
501+
adapt_loss {string} -- loss type, 'mmd' or 'coral'. You can add your own loss
502+
Returns:
503+
[tensor] -- adaptation loss tensor
504+
"""
505+
if adapt_loss == 'mmd':
506+
mmd_loss = mmd.MMD_loss()
507+
loss = mmd_loss(X, Y)
508+
elif adapt_loss == 'coral':
509+
loss = CORAL(X, Y)
510+
else:
511+
loss = 0
512+
return loss
513+
\end{lstlisting}
514+
515+
其中的MMD和CORAL是自己实现的两个loss,MMD对应DDC方法,CORAL对应DCORAL方法。其代码在上述github中可以找到,我们不再赘述。
516+
517+
\textbf{训练}
518+
519+
训练时,我们一次输入一个batch的源域和目标域数据。为了方便,我们使用pytorch自带的dataloader。
520+
521+
\begin{lstlisting}[title=深度迁移网络代码实现, frame=shadowbox]
522+
def train(source_loader, target_train_loader, target_test_loader, model, optimizer, CFG):
523+
len_source_loader = len(source_loader)
524+
len_target_loader = len(target_train_loader)
525+
train_loss_clf = utils.AverageMeter()
526+
train_loss_transfer = utils.AverageMeter()
527+
train_loss_total = utils.AverageMeter()
528+
for e in range(CFG['epoch']):
529+
model.train()
530+
iter_source, iter_target = iter(
531+
source_loader), iter(target_train_loader)
532+
n_batch = min(len_source_loader, len_target_loader)
533+
criterion = torch.nn.CrossEntropyLoss()
534+
for i in range(n_batch):
535+
data_source, label_source = iter_source.next()
536+
data_target, _ = iter_target.next()
537+
data_source, label_source = data_source.to(
538+
DEVICE), label_source.to(DEVICE)
539+
data_target = data_target.to(DEVICE)
540+
541+
optimizer.zero_grad()
542+
label_source_pred, transfer_loss = model(data_source, data_target)
543+
clf_loss = criterion(label_source_pred, label_source)
544+
loss = clf_loss + CFG['lambda'] * transfer_loss
545+
loss.backward()
546+
optimizer.step()
547+
train_loss_clf.update(clf_loss.item())
548+
train_loss_transfer.update(transfer_loss.item())
549+
train_loss_total.update(loss.item())
550+
if i % CFG['log_interval'] == 0:
551+
print('Train Epoch: [{}/{} ({:02d}%)], cls_Loss: {:.6f}, transfer_loss: {:.6f}, total_Loss: {:.6f}'.format(
552+
e + 1,
553+
CFG['epoch'],
554+
int(100. * i / n_batch), train_loss_clf.avg, train_loss_transfer.avg, train_loss_total.avg))
555+
556+
# Test
557+
test(model, target_test_loader)
558+
\end{lstlisting}
559+
361560
%
362561
%\subsection{深度对抗网络迁移}

src/chaps/ch13_appendix.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ \subsection{迁移学习相关的期刊和会议}
3838
9 & ECCV & European Conference on Computer Vision & 计算机视觉 \\ \hline
3939
10 & WWW & International World Wide Web Conferences & 文本、互联网 \\ \hline
4040
11 & CIKM & International Conference on Information and Knowledge Management & 文本分析 \\ \hline
41+
12 & ACMMM & ACM International Conference on Multimedia & 多媒体 \\ \hline
4142
\end{tabular}
4243
}
4344
\end{table}

src/main.tex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@
4747
\renewcommand{\today}{\number\year\number\month\number\day 日}
4848

4949

50-
\title{{\Huge 迁移学习简明手册{\large\linebreak\\}}{\Large 一点心得体会\\版本号:v1.0\linebreak\linebreak
50+
\title{{\Huge 迁移学习简明手册{\large\linebreak\\}}{\Large 一点心得体会\\版本号:v1.1\linebreak\linebreak
5151
}}
5252
\author{\\
5353
王晋东\\中国科学院计算技术研究所\\\href{http://tutorial.transferlearning.xyz}{tutorial.transferlearning.xyz}}
54-
\date{2018年4月}
54+
\date{2018年4月初稿\\
55+
2019年10月最新修改}
5556
\maketitle
5657
\thispagestyle{empty}
5758

src/main.toc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,21 @@
6969
\contentsline {subsubsection}{\numberline {9.4.2}核心方法}{52}{subsubsection.9.4.2}%
7070
\contentsline {subsubsection}{\numberline {9.4.3}小结}{55}{subsubsection.9.4.3}%
7171
\contentsline {section}{\numberline {10}上手实践}{56}{section.10}%
72-
\contentsline {subsubsection}{\numberline {10.0.1}Matlab}{56}{subsubsection.10.0.1}%
73-
\contentsline {section}{\numberline {11}迁移学习前沿}{61}{section.11}%
74-
\contentsline {subsection}{\numberline {11.1}机器智能与人类经验结合迁移}{61}{subsection.11.1}%
75-
\contentsline {subsection}{\numberline {11.2}传递式迁移学习}{61}{subsection.11.2}%
76-
\contentsline {subsection}{\numberline {11.3}终身迁移学习}{62}{subsection.11.3}%
77-
\contentsline {subsection}{\numberline {11.4}在线迁移学习}{63}{subsection.11.4}%
78-
\contentsline {subsection}{\numberline {11.5}迁移强化学习}{64}{subsection.11.5}%
79-
\contentsline {subsection}{\numberline {11.6}迁移学习的可解释性}{64}{subsection.11.6}%
80-
\contentsline {section}{\numberline {12}总结语}{65}{section.12}%
81-
\contentsline {section}{\numberline {13}附录}{66}{section.13}%
82-
\contentsline {subsection}{\numberline {13.1}迁移学习相关的期刊和会议}{66}{subsection.13.1}%
83-
\contentsline {subsection}{\numberline {13.2}迁移学习研究学者}{66}{subsection.13.2}%
84-
\contentsline {subsection}{\numberline {13.3}迁移学习资源汇总}{69}{subsection.13.3}%
85-
\contentsline {subsection}{\numberline {13.4}迁移学习常用算法及数据资源}{70}{subsection.13.4}%
72+
\contentsline {subsection}{\numberline {10.1}TCA方法代码实现}{56}{subsection.10.1}%
73+
\contentsline {subsubsection}{\numberline {10.1.1}Matlab}{56}{subsubsection.10.1.1}%
74+
\contentsline {subsubsection}{\numberline {10.1.2}Python}{60}{subsubsection.10.1.2}%
75+
\contentsline {subsection}{\numberline {10.2}深度网络的finetune代码实现}{62}{subsection.10.2}%
76+
\contentsline {subsection}{\numberline {10.3}深度网络自适应代码}{63}{subsection.10.3}%
77+
\contentsline {section}{\numberline {11}迁移学习前沿}{66}{section.11}%
78+
\contentsline {subsection}{\numberline {11.1}机器智能与人类经验结合迁移}{66}{subsection.11.1}%
79+
\contentsline {subsection}{\numberline {11.2}传递式迁移学习}{66}{subsection.11.2}%
80+
\contentsline {subsection}{\numberline {11.3}终身迁移学习}{67}{subsection.11.3}%
81+
\contentsline {subsection}{\numberline {11.4}在线迁移学习}{68}{subsection.11.4}%
82+
\contentsline {subsection}{\numberline {11.5}迁移强化学习}{69}{subsection.11.5}%
83+
\contentsline {subsection}{\numberline {11.6}迁移学习的可解释性}{69}{subsection.11.6}%
84+
\contentsline {section}{\numberline {12}总结语}{70}{section.12}%
85+
\contentsline {section}{\numberline {13}附录}{71}{section.13}%
86+
\contentsline {subsection}{\numberline {13.1}迁移学习相关的期刊和会议}{71}{subsection.13.1}%
87+
\contentsline {subsection}{\numberline {13.2}迁移学习研究学者}{71}{subsection.13.2}%
88+
\contentsline {subsection}{\numberline {13.3}迁移学习资源汇总}{74}{subsection.13.3}%
89+
\contentsline {subsection}{\numberline {13.4}迁移学习常用算法及数据资源}{75}{subsection.13.4}%

0 commit comments

Comments
 (0)