[读论文]DECOR-GAN

21 篇文章 2 订阅
14 篇文章 2 订阅

前排提示:个人笔记,不太详细,仅供参考

任务:粗略体素几何体的精细化

输入:粗略( 6 4 3 64^3 643)体素几何体content作为content,精细体素( 25 6 3 256^3 2563)几何体作为style
输出:content的精细化的体素几何体(( 6 4 3 64^3 643)),风格上类似给定的style。
在这里插入图片描述

方法概述

一个粗略( 6 4 3 64^3 643)体素几何体content,最近邻上采样得到generator mask。分辨率是256.

generator输入这个content和一个latent code, 输出256的精细几何体。

精细几何体经过generator mask,滤掉一些部分。

过滤的精细几何体,经过discrininator,得到一个不知道是什么的东西。

这个东西施加discrininator mask得到不知道是什么2.

不知道是什么2直接计算Ld

  1. reconstruction loss 结果像style: 希望如果拿style降采样后的结果通过网络,可以生成style自己。
  2. Ld (discrininator的loss, discriminatior mask): 希望生成的结果中,原来有内容的体素,现在还是有内容。 用一个discrininator类似于把generator的结果处理了一番。然后判断(降采样后为空的体素,希望在content中也为空)。 (啊这?为啥不直接降采样啊????为啥要discrininator啊????)
  3. generator mask: 希望原来空白的地方,最后还是空白:不是loss,就是用个mask,在generate之后把空的地方筛掉。
    在这里插入图片描述

discrininator

目的是惩罚lack of voxels,希望生成的结果中,原来有内容的体素,现在还是有内容。
可能他输出的就是,这个位置对不对,

这是作者的supplement文件提供的网络结构图:
输入:体素[X,Y,Z,1] (xyz是长宽高,均为256)
输出:[X/2-8,Y/2-8,Z/2-8,1] (120?,不知道是啥)
在这里插入图片描述

这是代码:(modelAE_GD.py)

class discriminator(nn.Module):
    def __init__(self, d_dim, z_dim):
        super(discriminator, self).__init__()
        self.d_dim = d_dim
        self.z_dim = z_dim

        self.conv_1 = nn.Conv3d(1,             self.d_dim,    4, stride=1, padding=0, bias=True) #in_channel, out_channel, kernal size
        self.conv_2 = nn.Conv3d(self.d_dim,    self.d_dim*2,  3, stride=2, padding=0, bias=True)
        self.conv_3 = nn.Conv3d(self.d_dim*2,  self.d_dim*4,  3, stride=1, padding=0, bias=True)
        self.conv_4 = nn.Conv3d(self.d_dim*4,  self.d_dim*8,  3, stride=1, padding=0, bias=True)
        self.conv_5 = nn.Conv3d(self.d_dim*8,  self.d_dim*16, 3, stride=1, padding=0, bias=True)
        self.conv_6 = nn.Conv3d(self.d_dim*16, self.z_dim,    1, stride=1, padding=0, bias=True)

    def forward(self, voxels, is_training=False):
        out = voxels

        out = self.conv_1(out)
        out = F.leaky_relu(out, negative_slope=0.02, inplace=True)

        out = self.conv_2(out)
        out = F.leaky_relu(out, negative_slope=0.02, inplace=True)

        out = self.conv_3(out)
        out = F.leaky_relu(out, negative_slope=0.02, inplace=True)

        out = self.conv_4(out)
        out = F.leaky_relu(out, negative_slope=0.02, inplace=True)

        out = self.conv_5(out)
        out = F.leaky_relu(out, negative_slope=0.02, inplace=True)

        out = self.conv_6(out)
        out = torch.sigmoid(out)

        return out

可以看到,输入的是长宽高为x,y,z, 通道数为1的体素;输出是长宽高分别/2-8, 通道数变为N+1(代码中的z_dim即为N+1)的体素。N是detailed shapes的数量,也就是style的数量。

结合论文和代码,XYZ均为256,所以discrininator输出的长宽高为120,通道数是N+1??N是类别。

说的是这个小区域对不对。

loss在modelAE.py 第455行:

 D_out = self.discriminator(voxel_style,is_training=True)
                    loss_d_real = (torch.sum((D_out[:,z_vector_style_idx:z_vector_style_idx+1]-1)**2 * Dmask_style) + torch.sum((D_out[:,-1:]-1)**2 * Dmask_style))/torch.sum(Dmask_style)
                    loss_d_real.backward()

                    D_out = self.discriminator(voxel_fake,is_training=True)
                    loss_d_fake = (torch.sum((D_out[:,z_vector_style_idx:z_vector_style_idx+1])**2 * Dmask_fake) + torch.sum((D_out[:,-1:])**2 * Dmask_fake))/torch.sum(Dmask_fake)
                    loss_d_fake.backward()

                    self.optimizer_d.step()

generator

输入:vosel数据[X,Y,Z,1],latent code[8] (XYZ相当于长宽高)
输出:[4X,4Y,4Z,1]
还挺清楚的,但没看到mask在哪里
在这里插入图片描述

loss: 注意,都是二范数

符号定义

C: M coase content shapes
S: N detailed style shapes
z s z_s zs: 某个detailed shape s的latent code
M D M^D MD: binary discrinimator masks
M G M^G MG: binary generator masks
D g D_g Dg: discrininator, 输入的是generator (fake)
D s D_s Ds: discrininator, 输入的是detailed style shapes (real)

Ld: discrininator loss

分为global(fake)和real(style)两支,她俩的区别只有Dg和Ds的区别。(这个在Preventing mode collapse里面解释)

在这里插入图片描述
其实有点看不懂,因为感觉S应该只进入Ds ,而c应该只进入Dg。

但总之是说,经过了mask之后,我们希望对每个s输出结果是1(判定为real),而对每个generator的结果输出是0(判定为fake).

loss_d_real = (torch.sum((D_out[:,z_vector_style_idx:z_vector_style_idx+1]-1)**2 * Dmask_style) + torch.sum((D_out[:,-1:]-1)**2 * Dmask_style))/torch.sum(Dmask_style)

LGAN

在这里插入图片描述
在这里插入图片描述

也是氛围global和style。也是一个Dg一个Ds,其他都一样。
他说的是,我希望经过generator生成的结果,经过mask以后,会被discrininator判定为1 (real).

Lr: reconstruction loss

希望generator 根据 降采样的s生成的s,和真实s完全一样。
在这里插入图片描述

代码

看论文看不懂,看代码吧:
modelAE.py第455行:

D_out = self.discriminator(voxel_style,is_training=True)
loss_d_real = (torch.sum((D_out[:,z_vector_style_idx:z_vector_style_idx+1]-1)**2 * Dmask_style) + torch.sum((D_out[:,-1:]-1)**2 * Dmask_style))/torch.sum(Dmask_style)
loss_d_real.backward()

D_out = self.discriminator(voxel_fake,is_training=True)
loss_d_fake = (torch.sum((D_out[:,z_vector_style_idx:z_vector_style_idx+1])**2 * Dmask_fake) + torch.sum((D_out[:,-1:])**2 * Dmask_fake))/torch.sum(Dmask_fake)
loss_d_fake.backward()

self.optimizer_d.step()

preventing mode collapse

在输出层分成了N+1个branches (从补充材料看到,是N+1个通道。)
N是detailed shapes的数量,1是global branch。
训练时用weighted global loss和对应的stype-specific branch loss.

每个style的latent code是怎么求的

总结,最先开始是自己的style编号,然后让网络跟着一起优化一下。

首先这个z得是generator的forward的第2个参数z.
在modelAE.py里面可以看到,给他的是z_tensor_g.
是z_tensor和self.generator.style_codes的矩阵相乘。

而 z_tensor 看上面,是其他style是rand,自己的style是1的一个东西。
那么显然我们也可以这样弄。

self.generator.style_codes:
modelAE_GD:
style_codes = torch.zeros((self.prob_dim, self.z_dim))
self.style_codes = nn.Parameter(style_codes)
nn.init.constant_(self.style_codes, 0.0)
注意nn.Parameters意思是把它作为一个可训练的参数。
所以每次都会参与训练。
初始化为0.

Network overview说,we use an embedding module to learn an 8D latent style code for each given detailed shape.

generator/discrininator mask 怎么得到

是用coarse content shape 做最近邻上采样得到的。

对于generator mask,本文用的是256的分辨率。
对于 discirninator mask,用128的分辨率。

对generator:
可以直接上采样:strict
或者将原来的shape按一个voxe扩大之后,再上采样:loose。本文用的是loose

显存优化技术

crop, emm,就是按bounding box裁了一下。

modelAE.py
crop_voxel函数。
emm,而且好像只在test里面调用了?

只生成一半,因为假设是对称的。

0,1不好训练的问题,使用高斯filter。见4.4
那我们去代码里面看一下他的crop?

GPU与训练时间

Nvidia Telsa V100 GPU,each model takes 6 to 24 housrs depending on the category.
batch size 是1.

感觉还是,emm,有点凉。

tricks

binary不好训练,给voxel 高斯模糊一下。

代码

train

dxb = batch_index_list[idx]
mask_fake =  torch.from_numpy(self.mask_content[dxb]).to(self.device).unsqueeze(0).unsqueeze(0).float()
Dmask_fake = torch.from_numpy(self.Dmask_content[dxb]).to(self.device).unsqueeze(0).unsqueeze(0).float()
input_fake = torch.from_numpy(self.input_content[dxb]).to(self.device).unsqueeze(0).unsqueeze(0).float()
z_tensor_g = torch.matmul(z_tensor, self.generator.style_codes).view([1,-1,1,1,1])
voxel_fake = self.generator(input_fake,z_tensor_g,mask_fake,is_training=False)
voxel_fake = voxel_fake.detach()

generator的输入是
input_fake,z_tensor_g,mask_fak

都是float类型,32位的。
那,确实,没有怎么,emm,节省的亚子。
算一下吧。

latent space

八维的style code,可以每一维都在上面连续的explore一下。
在这里插入图片描述

消融实验

masks

其中Conditional的意思是,generator和discrininator masks都不要了,在discrininator中用conditional GAN, 把coarse voxels作为condition。那个数字就是他的感受野。
在这里插入图片描述
在这里插入图片描述

高斯模糊

模糊得越厉害,越像style,但会过于模糊了。
作者说,如果渐进式训练,先用较大的模糊值,然后再用较小的σ,也许会更好。
在这里插入图片描述

奇异的截断线性函数模拟sigmoid:

在modelAE_GD.py里面第128行左右,用这个代替了sigmoid:
在这里插入图片描述

out = torch.max(torch.min(out, out0.002+0.998), out0.002)。

该函数是,
在0-1之间 为 y = x (斜率为1)
在其他位置斜率为0.002.
在0和1两点可以接上。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]: 这个方法是处理来自client的参数,确保特定类型的窗口不能获取焦点。其中包括TYPE_SYSTEM_OVERLAY、TYPE_SECURE_SYSTEM_OVERLAY和TYPE_TOAST。\[1\] 引用\[2\]: 每个Display都有一个displayId,对应着一个DisplayContent。每个DisplayContent会创建一个DisplayPolicy,用于确保WindowState的唯一性。此方法还会检查添加相关类型的窗口所需要的权限,并在每个display中禁止重复添加特殊类型的窗口,如TYPE_STATUS_BAR和TYPE_NOTIFICATION_SHADE。\[2\] 引用\[3\]: 这个方法主要处理窗口的显示状态。成员mAppOpVisibility默认为true,而成员mAppOp是在WindowState的构造方法中赋值的,它是在创建WindowState时传入的appOp\[0\]。而这个appOp\[0\]是在PhoneWindowManager#checkAddPermission方法中初始化的,它有几种取值,包括AppOpsManager.OP_NONE、AppOpsManager.OP_TOAST_WINDOW和AppOpsManager.OP_SYSTEM_ALERT_WINDOW,分别针对不同类型的窗口。\[3\] 问题: PRIVATE_FLAG_IS_SCREEN_DECOR是什么意思? 回答: PRIVATE_FLAG_IS_SCREEN_DECOR是一个用于标记窗口是否为屏幕装饰的私有标志位。当窗口被设置为屏幕装饰时,它将具有这个标志位,表示它是用于装饰屏幕而不是显示内容的窗口。这个标志位可以在WindowManager.LayoutParams中找到,并且可以通过设置或检查该标志位来确定窗口是否为屏幕装饰。 #### 引用[.reference_title] - *1* *2* *3* [Android R WindowManagerService 添加window过程分析 (二)](https://blog.csdn.net/qq_28261343/article/details/116060579)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值