用以前的代码并不能实现 python、Tensorflow 同样的效果。
MatConvNet 和 Tensorflow 中的卷积,在步长为2时,并且图像长宽是偶数时,并不完全相同
比如步长为1的一个卷积结果是这样的:
[[ 2. 0. 2. 4.]
[ 1. 4. 4. 3.]
[ 4. 3. 5. 9.]
[ 3. 4. 6. 2.]]
步长为2的一个卷积结果可以是:
[[ 2. . 2. .]
[ . . . .]
[ 4. . 5. .]
[ . . . .]]
由于跳步的位置不同也可以是:
[[ . . . .]
[ . 4. . 3.]
[ . . . .]
[ . 4. . 2.]]
这两个结果显然是不同的。
由于我的卷积代码是从 MatConvNet 中抄来的,所以这里用
<步长为1的卷积 + 间隔删除> 来代替 <步长为2的卷积>
2步长卷积:
/*2步长卷积*/
wid=wid/2;hei=hei/2;
if(ConvX->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)
Resize卷积层(*目标,wid,hei,ConvX->输出维度);
pad=ConvX->核宽/2;
vl_nnconv(源,目标,ConvX ,2,2,pad,pad,pad,pad);
1步长卷积+间隔删除:
/* 步长为1的卷积+隔行删除 代替 步长为2的卷积 */
if(ConvX->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)
Resize卷积层(*目标,wid,hei,ConvX->输出维度);
pad=ConvX->核宽/2;
vl_nnconv(源,目标,ConvX ,1,1,pad,pad,pad,pad);
std::swap (源,目标);
wid=wid/2;hei=hei/2;
Resize卷积层(*目标,wid,hei,ConvX->输出维度);
隔行列删(*源,*目标);
间隔删行列:
void 隔行列删(卷积层 & si,卷积层 & di)
{
float *s=si.data;
float *d=di.data;
if(si.width==di.width*2 && si.height==di.height*2 && si.depth==di.depth)
{
for(int i=0;i
这样就和《BeautyGAN-master》的效果相同了。
效果图:
上方都是统一把图像缩放到256x256,为了可以处理更大的图像,并且可以是长方形的,这里先把图像剪裁一下:
//取中心区域(4的倍数)
void 剪裁成正方形(卷积层 & di)
{
int wid=di.width;
int hei=di.height;
int w=min(wid,hei);
//取4的倍数
w-=w % 4;
int h=w;//同宽
cout<<"图像剪裁成:"<< w<<"x"<
输入图:
输出的8个图:
下载:
win32人脸图像美容处理程序,由《BeautyGAN-matser》模型权重转换而来
https://download.csdn.net/download/juebai123/11777059