没错,我就是那个为了勋章不择手段的屑(手动狗头)。快乐的假期结束了哭哭...
DANN 对抗迁移学习
域适应Domain Adaption-迁移学习;把具有不同分布的源域(Source Domain)和目标域(Target Domain)中的数据,映射到同一个特征空间。
GAN:生成对抗网络,包含生成器和判别器,有点类似博弈论的做法。
GAN+迁移学习:生成器不再是生成样本,而是进行特征提取工作。目标:从源域和目标域中提取特征,使得判别器无法区别提取的特征是来自哪个域。
好的可迁移特征:1-Domain-invariance,2.Discriminativeness
损失loss:训练损失和域判别损失

这里有一个疑惑,就是梯度反转层gradient reversal layer的作用?论文原文称之为GRL。
部分源码
下面对DANN的一个pytorch实现代码进行简要的分析。仅对网络的搭建代码进行说明。
1-梯度反转层的构建(GRL)
from torch.autograd import Functionclass ReverseLayerF(Function):@staticmethoddef forward(ctx, x, alpha):ctx.alpha = alphareturn x.view_as(x)@staticmethoddef backward(ctx, grad_output):output = grad_output.neg() * ctx.alphareturn output, None
2-整体模型的搭建
这一版的写法很像keras,完成了结构图中的模型搭建,各个网络的意义如论文中的那个图一样。
import torch.nn as nn
from functions import ReverseLayerFclass CNNModel(nn.Module):def __init__(self):super(CNNModel, self).__init__()self.feature = nn.Sequential()self.feature.add_module('f_conv1', nn.Conv2d(3, 64, kernel_size=5))self.feature.add_module('f_bn1', nn.BatchNorm2d(64))self.feature.add_module('f_pool1', nn.MaxPool2d(2))self.feature.add_module('f_relu1', nn.ReLU(True))self.feature.add_module('f_conv2', nn.Conv2d(64, 50, kernel_size=5))self.feature.add_module('f_bn2', nn.BatchNorm2d(50))self.feature.add_module('f_drop1', nn.Dropout2d())self.feature.add_module('f_pool2', nn.MaxPool2d(2))self.feature.add_module('f_relu2', nn.ReLU(True))self.class_classifier = nn.Sequential()self.class_classifier.add_module('c_fc1', nn.Linear(50 * 4 * 4, 100))self.class_classifier.add_module('c_bn1', nn.BatchNorm1d(100))self.class_classifier.add_module('c_relu1', nn.ReLU(True))self.class_classifier.add_module('c_drop1', nn.Dropout())self.class_classifier.add_module('c_fc2', nn.Linear(100, 100))self.class_classifier.add_module('c_bn2', nn.BatchNorm1d(100))self.class_classifier.add_module('c_relu2', nn.ReLU(True))self.class_classifier.add_module('c_fc3', nn.Linear(100, 10))self.class_classifier.add_module('c_softmax', nn.LogSoftmax(dim=1))self.domain_classifier = nn.Sequential()self.domain_classifier.add_module('d_fc1', nn.Linear(50 * 4 * 4, 100))self.domain_classifier.add_module('d_bn1', nn.BatchNorm1d(100))self.domain_classifier.add_module('d_relu1', nn.ReLU(True))self.domain_classifier.add_module('d_fc2', nn.Linear(100, 2))self.domain_classifier.add_module('d_softmax', nn.LogSoftmax(dim=1))def forward(self, input_data, alpha):input_data = input_data.expand(input_data.data.shape[0], 3, 28, 28)feature = self.feature(input_data)feature = feature.view(-1, 50 * 4 * 4)reverse_feature = ReverseLayerF.apply(feature, alpha)class_output = self.class_classifier(feature)domain_output = self.domain_classifier(reverse_feature)return class_output, domain_output
本文分析的源码是github上源文件的一个子集,欢迎各位一起来交流学习。GitHub - fungtion/DANN_py3: python 3 pytorch implementation of DANN
原文的链接贴在这里,方便各位朋友细看。













