pixel2style2pixel(pSp)实现解读【一】 -- 理论层面

在这里插入图片描述

前言

pixel2stylepixel是人脸编辑中比较重要的encoder方法,这里针对理论部分作简要记录。
代码解读部分见here
论文
Code

介绍

stylegan可以随机生成图片(人脸、动漫、汽车等),通过MLP实现了一个从离散的潜空间到人脸图像的可控、可编辑的人脸生成器。但是当我们想对真实世界的人脸图像进行人脸编辑时,需要首先把图像投射到latent space里生成latent code,然后再通过stylegan进行重建,但多数情况下,重建的结果很差、同时耗时很大。

同时,许多方法选择将图像编码到w空间生成latent code(512*1),然后再利用stylegan来生成,但事实证明将真实图像反转为512维的向量w∈W并不能导致准确的重建。

基于以上背景,psp应运而生:

  • 将真实图像投射到extented latent space w+ (18 * 512 * 1)[18个不同的512维度w向量]
  • 基于特征金字塔网络结构,从不同的金字塔尺度中提取风格向量,并根据其空间尺度直接insert into fixed 、pretrained Stylegan generator中
  • 可以直接将图像重建,避免耗时的优化过程

创新点

  • 一个能直接编码真实图像到latent space w+的的styleGAN编码器

  • 一个通用的解决image2image的端到端框架

    之前的方法都是直接拿了残差模块后输出的特征来塞到styleGAN里,这造成了很大的定位偏差(locality bias)。我们的方案是直接把styles送到styleGAN里去而不加入其他的spatial输入。这个方法尤其在人脸正面化方面取得了较大的优势,可以完全以无监督的方式来进行。其次是对中间style表征的支持使得我们可以用于许多人脸相关的任务,比如超分、分割图人脸生成等。

psp结构

请添加图片描述
传统而直接的方案是直接使用encoder最后一层的512维向量直接repeat18次 【这会导致编码生成地很随意,表征不够丰富,生成缺乏细节】。

stylegan中提出了在sythesis网络中不同level的latent code实际代表了不同层次的特征,大致可以分为三组coarse、medium和fine。借鉴了该思路,psp在模型结构中使用FPN(特征金字塔网络结构)来实现encoder,生成了三种不同level的特征,然后利用全连接层来生成latent code。

作者也尝试使用了其他的思路,比如直接从最大的特征图里生成所有的style编码可以取得相似的效果,但是会影响模型大小。另一个极端是从最小的特征图生成所有的编码,在保证维度足够的情况下
也能保证性能稳定。

Loss Functions

encoder使用了几个目标的加权组合来训练:

利用了像素级别的L2损失函数,其中psp(x)就是最后网络的输出(encoder+stylegan后)
L 2 ( x ) = ∣ x − p S p ( x ) ∣ 2 \mathcal{L}_{2}(\mathbf{x})=|\mathbf{x}-p S p(\mathbf{x})|_{2} L2(x)=xpSp(x)2
为了保证感知相似度,使用了LPIPS损失
L LPIPS  ( x ) = ∣ F ( x ) − F ( p S p ( x ) ) ∣ 2 \mathcal{L}_{\text {LPIPS }}(\mathbf{x})=|F(\mathbf{x})-F(p S p(\mathbf{x}))|_{2} LLPIPS (x)=F(x)F(pSp(x))2
为了保证输入输出尽可能是人脸,引入了一个人脸识别相关的损失
$$

\left.\mathcal{L}_{\mathrm{ID}}(\mathbf{x})=1-\langle R(\mathbf{x}), R(p S p(\mathbf{x})))\right\rangle

$$
在这里采用了ArcFace作为人脸编码网络,输入会被crop和resize到112 * 112输入

最终,损失函数为:
L ( x ) = λ 1 L 2 ( x ) + λ 2 L L P I P S ( x ) + λ 3 L I D ( x ) + λ 4 L r e g ( x ) L(x) = λ1L2(x) + λ2LLPIPS(x) + λ3LID(x) + λ4Lreg(x) L(x)=λ1L2(x)+λ2LLPIPS(x)+λ3LID(x)+λ4Lreg(x)

The Benifits of the StyleGAN Domain

在这里插入图片描述

前人的工作就有指出,styleGAN学习到的针对语义物体的分离是通过分层地表征来实现的,这就引入了第二个我们想要的东西:多模态数据生成

将图片通过encoder生成latent code (18 * 512 * 1),然后在style mixing网络内1~7层使用利用图片生成的latent code,剩下层里面送入随机latent code。

可以通过加入参数来控制两者的融合,在psp中是通过在coarse和medium层面上使用了encoder输出的styles,剩下的fine层面的特征使用了随机变量,保证我们输出的人是一个人,但是在细节上存在一些变化。

讨论

该方法被限制在由StyleGan生成的图像上,假如想要投射的真实世界图像在训练的Stylegan模型中并不存在案例,那么在通过psp encoder + stylegan生成便十分困难

由于psp考虑的是全局的一致性,对于细节的关注不足,所以存在一定程度上重建失败的例子

在这里插入图片描述

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
參考了一下NeHe 的教程, 在 cocos2d-x 2.0 上可以做點小手腳在 Windows 上全屏顯示! 參考了一下NeHe 的教程, 在 cocos2d-x 2.0 上可以做點小手腳在 Windows 上全屏顯示! 主要修改兩個檔案: CCEGLView.h CCEGLView.cpp 它們在工程里的位置是 libcocos2d->platform->win32 先打開 CCEGLView.h 在 public: 底下加上一個新功能: void setFullScreen(bool flag); 另外在 private: 里加上一個新變數: bool m_bFullScreen; 接下來是 CCEGLView.cpp: 在 Constructor 加上 m_bFullScreen 的初始值: CCEGLView::CCEGLView() : m_bCaptured(false) , m_hWnd(NULL) , m_hDC(NULL) , m_hRC(NULL) , m_lpfnAccelerometerKeyHook(NULL) , m_bFullScreen(false) 再加上我們的 setFullScreen(): void CCEGLView::setFullScreen(bool flag) { m_bFullScreen = flag; } 然後在 Create() 里, 把CreateWindowEx() 那段改成下邊這樣: /////////////// FULLSCREEN HACK - BEGIN DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style DWORD dwStyle = WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX; // Window Style if (m_bFullScreen) { DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings;,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = w; // Selected Screen Width dmScreenSettings.dmPelsHeight = h; // Selected Screen Height dmScreenSettings.dmBitsPerPel = 32; // Selected Bits Per Pixel dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. if (ChangeDisplaySettings(&dmScreenSettings;,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { // If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode. if (MessageBox(NULL, L"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?",L"cocos2d-x",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { setFullScreen(false); // back to windowed mode } else { // Pop Up A Message Box Letting User Know The Program Is Closing. MessageBox(NULL,L"Program Will Now Close.",L"ERROR",MB_OK|MB_ICONSTOP); return FALSE; // Return FALSE } } else // yeah! we are in fullscreen { dwExStyle = WS_EX_APPWINDOW; dwStyle=WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; //ShowCursor(FALSE); RECT rect; rect.left=(long)0; // Set Left Value To 0 rect.right=(long)w; // Set Right Value To Requested Width rect.top=(long)0; // Set Top Value To 0 rect.bottom=(long)h; // Set Bottom Value To Requested Height AdjustWindowRectEx(▭, dwStyle, FALSE, dwExStyle); // Adjust To True Requested Size } } /////////////// FULLSCREEN HACK - END // create window m_hWnd = CreateWindowEx( dwExStyle, // Extended Style For The Window kWindowClassName, // Class Name wszBuf, // Window Title dwStyle, // Defined Window Style 0, 0, // Window Position 0, // Window Width 0, // Window Height NULL, // No Parent Window NULL, // No Menu hInstance, // Instance NULL ); CC_BREAK_IF(! m_hWnd); 基本上這樣已搞定. 最後在我們自己項目的 main.cpp 里選擇全屏即可: AppDelegate app; CCEGLView& eglView = CCEGLView::sharedOpenGLView(); eglView.setFullScreen(true); eglView.setViewName("Hello Tests"); eglView.setFrameSize(1920, 1080); 要注意事項: - eglView.setFullScreen(true) 一定要在 eglView.setViewName("xxx") 前面. - eglView.setFrameSize(1920, 1080) 設定的大小, 一定要是顯卡可以支持的. - 不能再用CCDirector::sharedDirector()->enableRetinaDisplay(true)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值