【论文阅读21】DSN——域分离网络

DSN全称Domain Separation Network,是我看的第二篇域迁移的文章,这篇文章在DANN之后,思想上的一大亮点是对特征进行了分离,这样潜在地扩大了域迁移的范围~

补充一点,具体实现上的一大亮点是loss的选择,实验表明scale-invariant的MSE损失的效果确实很棒~

写在前面

读这篇文章的时候觉得自己的写作水平有了变化,但是说不清楚是好是坏。因为DSN这篇文章相比DANN有了理论上的改进,但是在写作DANN的时候却漏掉了一些关键的总结,比如这样的模型优缺点分析。

虽然DANN的博客似乎有了点味儿,但是还是要把关键的地方点出来啊💪

为什么读

  • 同DANN一样,IID-CSS上听来的,而且时间在DANN之后,似乎(的确)有了更多(一些)改进的地方
  • 人家虽然不是JMLR,但却是2016年NIPS上的一篇poster啊🙈
  • 在阅读的时候觉得其中可能有个地方有些问题,所以把感受记录下来

这次的文献及相关参考链接似乎有点多,在这里列出几个主要的,其它放在文末。

  1. DSN文献原文:DSN
  2. DSN种一个重要损失项——scale-invariant的MSE损失 的来源:Depth Map Prediction from a Single Image using a Multi-Scale Deep Network
  3. 知乎用户笨笨的文章迁移学习:Domain Separation Networks,在我看来这个讲得很干净,内容也都讲到了
  4. CSDN用户hjimce的文章深度学习(二十八)基于多尺度深度网络的单幅图像深度估计,该文种的代码让我走出迷雾,弄懂了部分loss的具体实现方式

对文章的整体理解

其实上面所述参考链接中的知乎文章已经够用了。现在大致重新总结一下,让我们从DANN的一个缺点过渡到本文的思路。

DANN在做域迁移的时候,直接将源域和目标域的样本转化到某一特征空间中并混淆它们,达到迁移的效果。

但是这样做,其实有一些问题,即域迁移本身是难以做到全部特征迁移的,因为不同的域对应的特征、特征分布的确是不同的。那么新的思路就来了,不同的域之间有联系性,也有差异性,那么联系性可以简单描述为特征空间中有一些维度是不同域共享的,称为共有(common)特征;反之差异性可以简单描述为特征空间中有另一些维度不是共享的,是域本身的特征,所以称为私有(private)特征

因此,基于这个新思路,我们希望基于DANN的结构,把共有的特征和私有的特征分离开来,期望能够更好地描述不同域之间的关系,达到更好的效果。到这里,文章标题Domain Separation Network的思路就完全确定了,下面就是怎么去实现了。

DSN模型结构

👴话不多说,直接暴力上结构!

结构还是比较清晰的,咱们直接点明该结构是在哪一(几)块完成公、私有特征分离的操作的。就是除了右下角分类外的全部结构,但是别慌,别看框框多,其实都是高度对称的结构。类比DANN,输入从全部样本 $x$ 分离为有标记的两域样本 $x_s$ 和 $x_t$,下标自然是源域source和目标域target了;同时输出也从全部特征空间的 $f$ 转化为了公有特征 $h_c$ 和私有特征 $h_p$。

成功分离的保证是暹罗网络。啥?暹罗网络?想到了吧哈哈,哥我曾经看过一篇语音生成的文章MelGAN-VC,现在看看这个特征分离的操作和这篇文章不是有点像,而是完全一致!都是利用Siamese Network,中文译为暹罗网络或者孪生网络,使用的是特征分离对抗➕样本恢复的形式。具体懒得说了,反正我早学过了🤭,这里就列一篇介绍暹罗网络的博客吧Siamese Network:孪生网络 简单理解

好了,上面把文章的核心对抗方法直接跳过了,那么模型的结构其实就讲完了😄

Loss组成

讲到这里,忘了说,文章的两大亮点,一是利用暹罗网络分离了公私有特征;二是loss的具体形式了,先点明,就是scale-invariant的MSE损失的使用。loss的具体组成请参阅参考链接中的知乎文章迁移学习:Domain Separation Networks,这里不再赘述。但是其中很多细节还需要研究研究。

其实在阅读这部分的时候,我遇到了很多障碍,这里我主要对scale-invariant的MSE损失有以下疑问,该loss似乎在全局图像恢复上的效果比一般的MSE好,效果好的理由是文章中的实验验证:

  1. 但为什么是这种形式呢?(下文解答)

  2. 对于图像恢复的颜色和色彩强度没有要求,为什么?(待求证!

  3. 这个loss的定义很奇怪,原文中的形式是 $(4)$ 式,前一项记为MSE,后一项记为SIMSE。而我在 https://github.com/fungtion/DSN 找到的代码中看别人复现的loss用的是此MSE+SIMSE而不是减?(下文解答)

  4. 此loss中前者MSE的计算并不是什么矩阵 $A^TA$ 特征值绝对值最大值(参考 https://www.zhihu.com/question/50557667 )而是普通的矩阵元素差值平方和?那这里矩阵的 $L_2$ 范数究竟是什么?

针对问题 $1、3、4$,我先后查阅了这种scale-invariant的MSE损失的原文,2014NIPS的Depth Map Prediction from a Single Image using a Multi-Scale Deep Network,以及CSDN博客深度学习(二十八)基于多尺度深度网络的单幅图像深度估计,和G站上他人的代码 https://github.com/fungtion/DSN 。从这三处,我将给出我的分析过程。

首先,G站上的代码是本文的PyTorch实现,loss函数的定义在 https://github.com/fungtion/DSN/blob/master/functions.py ,训练的过程在 https://github.com/fungtion/DSN/blob/master/train.py ,由于把源域和目标域损失都分开算了,所以目标域上没标签,就没有分类损失,源域上则有。其中的MSE项和SIMSE项分别是(引用他人代码啦注明出处应该可以…)

1
2
3
4
5
6
7
8
9
10
class MSE(nn.Module):
def __init__(self):
super(MSE, self).__init__()

def forward(self, pred, real):
diffs = torch.add(real, -pred)
n = torch.numel(diffs.data)
mse = torch.sum(diffs.pow(2)) / n

return mse
1
2
3
4
5
6
7
8
9
10
11
class SIMSE(nn.Module):

def __init__(self):
super(SIMSE, self).__init__()

def forward(self, pred, real):
diffs = torch.add(real, - pred)
n = torch.numel(diffs.data)
simse = torch.sum(diffs).pow(2) / (n ** 2)

return simse

这些就是代码实现中的具体loss计算方式,而我觉得原文的 $(4)$ 式右边第一项写成矩阵的 $L_2$ 范数是不合适的。毕竟 mse = torch.sum(diffs.pow(2)) / n​ 说明了这不是正规的矩阵 $L_2$ 范数。这样问题 $4$ 就解决了

其次,在CSDN博客中,作者有一段该loss的代码,不过是TF,我不太熟悉,但是写得很棒。关键是代码的注释里有一句

文献中公式4,参数$\lambda$取值为0.5。公式采用的是简化为(n×sum(d^2)-λ*(sum(d))^2)/(n^2)

这提示,是不是代码实现简化了特征根的计算,用代码中的形式来代替计算呢?确实看了Depth Map Prediction from a Single Image using a Multi-Scale Deep Network $(4)$ 式,形式上是一致的。那么是不是替代品呢?是的,原文是在log空间计算的,所以度量其实是 $\displaystyle \alpha(x, \hat{x}) = \dfrac{1}{n}\sum_i \left(\log x_i - \log \hat{x}_i\right)$ ,所以现在本文用正常的原空间有 $\displaystyle \alpha(x, \hat{x}) = \dfrac{1}{n}\sum_i \left(x_i - \hat{x}_i\right)$,所以带入参考文献Depth Map Prediction from a Single Image using a Multi-Scale Deep Network的 $(1)$ 式有

这的确就是代码实现中的具体计算方式,这进一步说明代码种的形式确实是SIMSE的形式,说明原文的 $(4)$ 式右边第一项写成矩阵的 $L_2$ 范数是不合适的。这样问题 $1$ 就被推导出来了

最后,针对问题 $3$,我觉得这位兄弟的代码不小心写错了,好了问题 $3$ 也解决了~


综上,这篇文章我基本上都看完了,还剩一些小问题藏在加粗字中,待办了~

其它小细节

  • 学到一个新函数:torch.numel,输入是tensor,输出是全部元素的个数,感觉就是张量的size

  • MMD损失是什么我看不懂,需要再去具体学习!

  • 文章的其它部分,尤其是对比实验、其它loss都可以参考迁移学习:Domain Separation Networks,讲得挺好

  • 文章原文中说代码在这https://github.com/tensorflow/models/domain_adaptation,但👴没找着

  • difference loss用矩阵乘积的形式超过了DANN loss的效果!说明这种分离公共、私有特征的度量是有效的!

  • 上面反复说的知乎文章下面有个评论:

    您好,请问在输入公有特征提取器的时候,是把两个域的样本整体用两个矩阵输入进去,还是从每次从目标域和源域各选取一个成为一对输入进去呢

    从文章原文 $(3)$ 式的loss看应该是全部数据喂进去了,从代码看也是这样,不过多了点细节,是分源域样本和目标域样本分别通通喂进去的

参考文献

文章主要的4篇参考文献在为什么读章节中已经给出。

[5] 黑猫紧张. PN-35: Domain Separation Networks (NIPS 2016)[EB/OL]. https://zhuanlan.zhihu.com/p/82403668, 2019-09-13.

[6] gdtop818. Domain Separation Networks[EB/OL]. https://blog.csdn.net/weixin_37993251/article/details/91472097, 2019-06-11.

[7] PoemK. Domain Separation Networks (NIPS 2016)[EB/OL]. https://blog.csdn.net/yskyskyer123/article/details/95664755, 2019-07-12.

[8] 究竟灰. 论文阅读:Depth Map Prediction from a Single Image using a Multi-Scale Deep Network[EB/OL]. https://zhuanlan.zhihu.com/p/29312227, 2019-09-18.

[9] Xuefeng_BUPT. Depth Map Prediction from a Single Image using a Multi-Scale Deep Network(NIPS2014)论文阅读[EB/OL]. https://blog.csdn.net/chishuideyu/article/details/83573174, 2018-10-31.