jindongwang / transferlearning

Transfer learning / domain adaptation / domain generalization / multi-task learning etc. Papers, codes, datasets, applications, tutorials.-迁移学习
http://transferlearning.xyz/
MIT License
13.45k stars 3.81k forks source link

有关DAAN复现的一点问题 #228

Closed JoheyHan closed 3 years ago

JoheyHan commented 3 years ago

王老师您好,我在改写您的DAAN网络并用在自己的数据过程中出现了一些问题,域鉴别器损失不收敛,不知道域鉴别器(全局和每个类别的域鉴别器的loss都围绕在0.69(0-1对半开)算不算是鞍点。。。),并且对代码中的一些参数有些不太理解,对照您的论文后也没怎么弄清楚,希望能请教您一下: 1. transferlearning/code/deep/DAAN/train.py / line125

local loss

    loss_s = 0.0
    loss_t = 0.0
    tmpd_c = 0
    for i in range(args.num_class):
        loss_si = F.nll_loss(F.log_softmax(s_out[i], dim=1), sdomain_label)
        loss_ti = F.nll_loss(F.log_softmax(t_out[i], dim=1), tdomain_label)
        loss_s += loss_si
        loss_t += loss_ti
        tmpd_c += 2 * (1 - 2 * (loss_si + loss_ti))
    tmpd_c /= args.num_class

    d_c = d_c + tmpd_c.cpu().item()

    global_loss = 0.05*(err_s_domain + err_t_domain)
    local_loss = 0.01*(loss_s + loss_t)

这里的全局loss中:我认为(loss_si+loss_ti)/2才是论文中的域判决损失,所以应该是tmpd_c+= 2 (1 - 2 (loss_si + loss_ti)/2) 对吗? 同理global_loss 和local_loss也要除以2?并且我也不太清楚global_loss 和 local_loss前的系数是如何设定的,如果是权衡参数lambda的话系数又不是一样的,这里我一直不太清楚。这个系数的选择是和类别个数有关系吗? 2. line 104

for batch_idx, (source_data, source_label) in tqdm.tqdm(enumerate(source_loader), total=len_dataloader, desc='Train epoch = {}'.format(epoch), ncols=80, leave=False): p = float(batch_idx+1 + epoch len_dataloader) / args.epochs / len_dataloader alpha = 2. / (1. + np.exp(-10 p)) - 1 optimizer.zero_grad() source_data, source_label = source_data.to(DEVICE), source_label.to(DEVICE) for target_data, target_label in target_loader: target_data, target_label = target_data.to(DEVICE), target_label.to(DEVICE) break out = model(source_data, target_data, source_label, DEV, alpha) s_output, s_domain_output, t_domain_output = out[0],out[1],out[2] s_out = out[3] t_out = out[4] 这里的alpha我理解的是梯度反传的大小,我看MADA和您的论文中并没有对它进行太多的说明,因此我一直认为是1,不知道是不是我哪的认识有问题。 3. 域判别器中间维大小1024是必须的吗,感觉类别与判别器太多了,1024的中间维导致内存占用太大,最后我跑不动了。。。但是域判别器小了是不是就会不收敛,对域的鉴别能力有限

希望得到您的回答,谢谢您

jindongwang commented 3 years ago

@Richardych

houwenxin commented 3 years ago
  1. 这样的设定是因为作者在实验的过程中发现不用除以2效果也比较好,但是在我们最新的实现里为了严谨统一都是除以2之后做的,并且实验发现是否除以2的影响没有那么大。
  2. 这个alpha是动态变化的,随着训练的进度由0变为1,可以参考DANN的论文[1]。
  3. 这个当然不是一定的,域判别器中间维大小本身是一个参数,可以通过搜索得到最优的。

最后,DAAN的代码已经集成入DeepDA库了,欢迎参考我们重新实现的版本:https://github.com/jindongwang/transferlearning/tree/master/code/DeepDA

[1] Ganin Y, Lempitsky V. Unsupervised domain adaptation by backpropagation. ICML 2015.

JoheyHan commented 3 years ago

好的明白了,非常感谢您的回答