读论文TP_GAN与代码解析

资源准备:论文下载, 代码下载(tensorflow实现)

预备知识:tf.reduce_函数

TP GAN ;全名 TWO pathway Geanerator Network,,,在此文作用为侧脸->正脸,与普通GAN区别开的是它用两条pathway分别处理局部部位与整体,最后合成结果,整体架构如下图所示,图中省略了部分路线,resblock与部分convolution处理

 

官方给定的代码中TP_GAN-Mar6FS.py函数有:

build_model

用于构造网络,构造loss

processor

注释:输入3通道图片,输出3通道,3*4的梯度图(gradient map);步骤是对输入图进行一个conv后将原图与结果concat

用于g_loss中,至于g_loss是什么,(todo)

FeaturePredict

partRotator

如图,输入侧面的眼或嘴或鼻,输出正面的眼或嘴或鼻

四个卷积的尺度2倍的递增,图中每层卷积间省略了resblock和Leaky Relu,中间卷积到反卷积间省略了两个resblock,比起变分自动编码器,PartRotator还多出一个跨层的输入,通过与原输入tf.concat的方式 跨层输入;代码中输出是两个,一个是原结果,另一个是结果再1*1conv,tanh处理

generator,decoder

(这是Global pathway的)两个一起讲,代码里输入输出有点乱,挺多个输入输出。此图中简化了:第1个deconv的结果作为第3个的输入,第2->第4,第3->第5 ; havles maximum是将vector切半,输出较大的一半,img跨层输入不是简单的输入,除了resize,resblock,conv以外还有其他的操作,略过; 图中 省略了每层的resblock和Leaky Relu,右下角箭头的输入是PartCombiner后的结果,

decoder函数的返回值:每一个deconv后再加一个1*1的conv,有5个deconv,所以共5个返回值(代码中有多的重复的返回值,忽略)

 

partCombiner

如图,输入眼嘴鼻,将眼嘴鼻放到设定好的位置,其余用tf.pad来补全,如文中所说:Specifically, we put each feature tensor at a “template landmark location”,重合的地方用tf.maximum处理,总体被文中称为Position Aggregation操作

loadDeepFace

文中没提怎么面部定位,代码中是直接提取脸部的各个部位的坐标用于裁剪,此函数作用是用pickle读取这些坐标文件

DiscriminatorLocal

conv尺度两倍递增,倒数第二层conv与倒数第三层conv的filter尺度一样,图中省略每层间的leaky relu和第四层和第五层后的resblock

FeatureExtractDeepFace

一个深层次的FeatureExtrarter,其中有res的结构,引用了_conv_layer,get_conv_filter函数; 代码注释:processing from color to gray; 函数在build_model中被调用,作用:提取特征,用于构造dv_loss,  dv_loss代码中是global decoder产生的图与groundtruth的Loss, 对应到文章是Pixel-wise Loss。Pixel-wise Loss如图

继续说代码中的dv_loss是怎么实现的:decoder函数->生成图片G,并引入groundtruth图片->FeatureExtractDeepFace函数->tf.reduce_sum和其他reduce_函数->loss

evaluate,train,get_conv_filter, get_bias, get_fc_weight, save, load

Loss

保证对称性的symetric loss,作用:加速拟合,产生更真实的图。还可以补全遮挡部位

Adversarial Loss
Identity Perserving Loss

Pixel-Wise Loss,见上面函数featureExtractDeepFace,是通过feature内的L1距离,让一些突出特征在变化过程中保留下来

tv Loss(total variation regularization loss),如名

Discriminator

就看到一个discriminatorLocal函数,文中说这个网络的Discriminator特别之处是产生的结果是一个probability map

 

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
修改这个函数,要实现防止连续点按 while (1) { tp_dev.scan(0); if (tp_dev.sta & TP_PRES_DOWN) { //触摸屏被按下 if (tp_dev.x[0] > 0 && tp_dev.x[0] < 130 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 0 && tp_dev.x[0] < 130 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i < 5) { password[i++] = '1'; } } else if (tp_dev.x[0] > 130 && tp_dev.x[0] < 260 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 130 && tp_dev.x[0] < 260 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i < 5) { password[i++] = '2'; } } else if (tp_dev.x[0] > 260 && tp_dev.x[0] < 390 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 260 && tp_dev.x[0] < 390 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i < 5) { password[i++] ='3'; } } else if (tp_dev.x[0] > 390 && tp_dev.x[0] < 520 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 390 && tp_dev.x[0] < 520 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i < 5) { password[i++] = '4'; } } else if (tp_dev.x[0] > 520 && tp_dev.x[0] < 650 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 520 && tp_dev.x[0] < 650 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i > 0) { password[--i] = '\0'; } } else if (tp_dev.x[0] > 650 && tp_dev.x[0] < 800 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { while(tp_dev.x[0] > 650 && tp_dev.x[0] < 800 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480){ tp_dev.scan(0); } if (i == 4) { break; //退出密码输入循环 } else { Show_Hz16(300,250,"提示信息:用户名或密码错误",RED,WHITE); } } //显示部分 LCD_ShowString(400,150,400,24,24,password); } }
05-22
while (1) { tp_dev.scan(0); if (tp_dev.sta & TP_PRES_DOWN) { //触摸屏被按下 if (tp_dev.x[0] > 0 && tp_dev.x[0] < 130 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i < 5) { password[i++] = '1'; } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } else if (tp_dev.x[0] > 130 && tp_dev.x[0] < 260 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i < 5) { password[i++] = '2'; } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } else if (tp_dev.x[0] > 260 && tp_dev.x[0] < 390 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i < 5) { password[i++] = '3'; } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } else if (tp_dev.x[0] > 390 && tp_dev.x[0] < 520 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i < 5) { password[i++] = '4'; } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } else if (tp_dev.x[0] > 520 && tp_dev.x[0] < 650 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i > 0) { password[--i] = '\0'; } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } else if (tp_dev.x[0] > 650 && tp_dev.x[0] < 800 && tp_dev.y[0] > 380 && tp_dev.y[0] < 480) { if (i == 4) { break; //退出密码输入循环 } else { Show_Hz16(300,250,"提示信息:用户名或密码错误",RED,WHITE); } while(tp_dev.sta & TP_PRES_DOWN) { //等待触摸屏释放 tp_dev.scan(0); } } //显示部分 LCD_ShowString(400,150,400,24,24,password); } } 在每个按键输入后,加入一个 while 循环等待触摸屏释放。这样可以防止连续点按导致密码输入错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值