音乐播放器
Ericam_blog
 
文章 标签
11

Powered by Gridea | Theme: Fog
载入天数...
载入时分秒...

stylegan的实验小记录

简单记录一下本周stylegan实验经历
做了很多...又仿佛什么都没做
hhhhhhh

stylegan3 encoder的设计实现

想尝试来实现一个简单的encoder,实现图片到latent code的投影,但理想很好、现实很惨。

image ===> latent

在此阶段主要尝试了两种方法:

1.将图片送入resnet50网络(不经过最后fc层),最终输出tensor的shape为2048 * 8 * 8 (当最初图片的size为256 * 256时),然后送入卷积层,最后经过两次全连接层,生成 16*512 向量,直接送入生成网络(相当于不经过mapping network)

self.resnet = list(resnet50(pretrained=True).children())[:-2]
self.resnet = torch.nn.Sequential(*self.resnet)
self.conv2d = torch.nn.Conv2d(2048,256,kernel_size=1)
self.flatten = torch.nn.Flatten()
self.dense1 = torch.nn.Linear(16384,256)
self.dense2 = torch.nn.Linear(256,(16*512))

感觉这个方法可能存在的问题:

  • resnet50网络学习能力是否足够?是否更大深度的网络学习效果更好?
  • 全连接层只是单纯经过两次线性变换,那如此其实可以合并的。是否加入了激活函数能够更好凸出分布呢?
  • 在卷积层深度跳跃是否过快。

(当然以上是借鉴了image2encoder的结构,但最终结果显示它并适合stylegan3)

2.利用随机种子生成一个与mapping network输入维度相同的tensor z(1 * 512),然后送入mapping network生成w (1 * 512),将这个w复制扩展维度(16 * 512 ),然后送入生成网络。

Latent Optim Model

​ 这一块算是最主要的地方,因为生成图像完全取决于输入的tensor ws (16*512),但如何对其进行优化,使它向着期待的方向收敛,挺关键。

最开始是先将图像进行一个预处理:

class PostSynthesisProcessing(torch.nn.Module):
    def __init__(self):
        super().__init__()

        self.min_value = -1
        self.max_value = 1
    
    def forward(self,synthesized_image):
        synthesized_image = (synthesized_image - self.min_value) * torch.tensor(255).float() / (self.max_value - self.min_value)
        synthesized_image = torch.clamp(synthesized_image+0.5,min=0,max=255)
        return synthesized_image

class VGGProcessing(torch.nn.Module):
    def __init__(self):
        super().__init__()

        self.image_size = 256
        self.mean = torch.tensor([0.485, 0.456, 0.406], device="cuda").view(-1, 1, 1)
        self.std = torch.tensor([0.229, 0.224, 0.225], device="cuda").view(-1, 1, 1)

    def forward(self, image):
        image = image / torch.tensor(255).float()
        image = F.adaptive_avg_pool2d(image, self.image_size)

        image = (image - self.mean) / self.std

        return image

但是在实验过程中,发现加入预处理后,后续产生的loss值过大,梯度爆炸了,于是便取消了该操作。

w_opt = torch.tensor(w_avg, dtype=torch.float32, device=device, requires_grad=True)
optimizer = torch.optim.Adam([w_opt], betas=(0.9, 0.999), lr=initial_learning_rate)
......      
synth_features = vgg16(synth_images)
dist = (target_features - synth_features).square().sum()
loss = dist

由于在stylegan3中取消了noise机制,所以不清楚如何添加来提高loss、促进梯度下降。所以最终模型学习效果很差。

stylegan2 开源 encoder 测试

原图:

stylegan2 - projector 投射出来的人脸:

e4e 投射出来的人脸:

相较而言,e4e的投影效果更好一点,对于毛发生成的控制更为精确。

目前尚存在的问题为:原图生成器为利用stylegan2关于网红数据集finetune得到(来源于网络,基于ffhq),但是该图利用ffhq预训练模型可以实现良好投影(如上图所示),而我根据ffhq模型finetune得到的生成器生成的图像,却无法通过ffhq预训练模型得到良好投影。

stylegan2 人脸编辑实验

基于年龄进行人脸编辑。

利用开源的参数文件进行测试:

可以看到虽然确实能产生age方面的变化,例如增加了皱纹等,但是生成图像略像欧美人(瞳孔颜色、五官等),原因是因为参数文件是利用ffhq数据集训练,因此在针对图像面部编辑时可能会产生意外情况。