2018 ECCV Deforming Autoencoders: UnsupervisedDisentangling of Shape and Appearance

作者美国纽约州立大学石溪分校 Zhixin Shu

Paperhttps://openaccess.thecvf.com/content_ECCV_2018/papers/Zhixin_Shu_Deforming_Autoencoders_Unsupervised_ECCV_2018_paper.pdf

Code: https://github.com/zhixinshu/DeformingAutoencoders-pytorch

关键词:Unsupervised groupwise image alignment 无监督分组图像对齐, disentangle shape and appearance, latent representation

 

根据代码:https://github.com/zhixinshu/DeformingAutoencoders-pytorch/blob/master/train_DAE_CelebA.py理解该方法:

输入图像到编码器,编码器输出该图像的latent representation(代码中编码器输出的特征的维度 batch_size * channels * 1 * 1,经过维度调整view,得到batch_size * channels),接着 latent represnetation 分别输入到两个全联连接层,得到两个特征通道数量不同的latent representation,这里根据解码器的输出,本人分别称这两个latent representation为 texture/apperance latent representation (shape : 10 * 16), 另一个是shape latent representation (shape: 10 * 128),可以调整参数变换两个latent representation的特征通道数量。 

shape LR, texture LR 分别输入到两个解码器,分别得到deformation field,合成appearance。

deformation field 输入到 spatial integration layer 生成网格,网格包含x,y方向的坐标;接着,网格输入到 Hardtanh()激活函数中,坐标取值范围归一化到[-1,1]。最后,grid_sample函数利用坐标,以及合成图像,重新插值生成输出图像。

编码器输出:

# encoders of DAE, using DenseNet architecture
class Dense_Encoders(nn.Module):
    def __init__(self, opt):
        super(Dense_Encoders, self).__init__()
        self.ngpu = opt.ngpu
        self.encoder = waspDenseEncoder(opt, ngpu=1, nc=opt.nc, ndf = opt.ndf, ndim = opt.zdim)
        self.zImixer = waspMixer(opt, ngpu=1, nin = opt.zdim, nout = opt.idim)
        self.zWmixer = waspMixer(opt, ngpu=1, nin = opt.zdim, nout = opt.wdim)

    def forward(self, input):
        self.z     = self.encoder(input) # shape 10 * 128
        self.zImg  = self.zImixer(self.z)# shape 10 * 16
        self.zWarp = self.zWmixer(self.z)# shape 10 * 128
        return self.z, self.zImg, self.zWarp

self.z, self.zImg (texture LR), slef.zWarp (shape LR)。

解码器输出:

class Dense_DecodersIntegralWarper2(nn.Module):
    def __init__(self, opt):
        super(Dense_DecodersIntegralWarper2, self).__init__()
        self.imagedimension = opt.imgSize
        self.ngpu = opt.ngpu
        self.idim = opt.idim
        self.wdim = opt.wdim
        self.decoderI = waspDenseDecoder(opt, ngpu=self.ngpu, nz=opt.idim, nc=opt.nc, ngf=opt.ngf, lb=0, ub=1)#
        self.decoderW = waspDenseDecoder(opt, ngpu=self.ngpu, nz=opt.wdim, nc=2, ngf=opt.ngf, lb=0, ub=1, activation=nn.Tanh, args=[], f_activation=nn.Sigmoid, f_args=[])
        self.warper   = waspWarper(opt)
        self.integrator = waspGridSpatialIntegral(opt)
        self.cutter = nn.Hardtanh(-1,1)
    def forward(self, zI, zW, basegrid):
        self.img = self.decoderI(zI.view(-1,self.idim,1,1))
        self.diffentialWarping = self.decoderW(zW.view(-1,self.wdim,1,1))*(5.0/self.imagedimension) # (5.0/self.imagedimension) 对应
        self.warping = self.integrator(self.diffentialWarping)-1.2 # 为什么要减去 1.2,为了将取之范围移动到-1~1 附近,而1.2 通过torch.median()估算得到的。
        self.warping = self.cutter(self.warping)# 再通过nn.Hardtanh()将self.warping 截断至[-1, 1]内。
        self.resWarping = self.warping-basegrid
        self.output  = self.warper(self.img, self.warping) # 模型重建结果
        return self.img, self.resWarping, self.output, self.warping

self.img,self.resWarping, self.output, self.warping

 损失函数:

在代码中,作者使用的是L1损失计算重建损失,并不是论文中所述的L2损失。

 

 

 

等式(6)中的Sa 与 So之间的L2损失在代码中也没有实现。在Github的Issues也有人提出相同的问题,但是作者没有反馈。

 具体的公式解释,见论文。简单地来说,使用了损失函数3,5,6来约束模型。文章中作者还提到了对抗损失,但是在代码中没有体现出来。:

测试代码与问题

预训练模型参数加载问题:

使用https://github.com/zhixinshu/DeformingAutoencoders-pytorch/blob/master/train_DAE_CelebA.py代码,以及模型的参数加载预训练模型参数,出现模型参数不匹配问题,将代码中import DAENet_InstanceNorm as DAENet 替换成import DAENet。

使用该模型训练腹部MRI数据集 ,https://chaos.grand-challenge.org/Data/

问题1:模型损失函数不熟练,重建图像显示一团黑。

思考:是不是归一化方法不一样?我自己写了数据扩充,以及归一化:

 与作者的对比,发现作者没有使用数据扩充,且输入数据归一化到[0,1],我的输入数据归一化到[-1,1]:

def parseSampledDataPoint(dp0_img, nc):
    dp0_img  = dp0_img.float()/255 # convert to float and rerange to [0,1]
    if nc==1:
        dp0_img  = dp0_img.unsqueeze(3)
    dp0_img  = dp0_img.permute(0,3,1,2).contiguous()  # reshape to [batch_size, 3, img_H, img_W]
    return dp0_img

问题2: 修改归一化后,部分损失能够在模型训练开始阶段逐渐下降,但是随着训练次数的增加,模型的BiasReduce损失值又上升,而且重建图像和生成Texture 几乎一样,不像论文的人脸重建的效果,重建图像与Texture有区别。

思考:

(1)代码BiasReduce损失没有实现 Sa 与 So之间的L2损失 引起的?

(2)batch_size(原代码:100,https://github.com/zhixinshu/DeformingAutoencoders-pytorch/blob/master/train_DAE_CelebA.py)或者\delta 取值(源代码中\delta = 0.078125 = 5/64超参数影响 ?

分析 推论(2):为了保持\delta不变,将5改成20,进行一次实验。通过对比BiasReduce损失的收敛情况,可以得出\delta取值对BiasReduce损失收敛影响比较重要。但是重建图像和生成Texture 几乎一样,没有改善。

继续分析:

(3)重建损失函数是L1损失,不是L2损失引起 生成的Texture 与 Reconstruction Imags一致?

(4)会不会是保存的时候出现问题?

(5)不更改源代码,将MR图像直接缩放到64输入到模型中,且放弃数据扩充,看看有什么效果?

答:经过两种实验的分析,第一种:将图像缩放到64,有数据扩充,模型输出的Texture,重建图像如下所示:

 

 通过可视化分析,Texture  与重建图像没有显著的差异。但是分析第二种:将图像缩放到64,无数据扩充,生成结果如下所示,发现生成的结果有所改善。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值