我是靠谱客的博主 甜美小天鹅,最近开发中收集的这篇文章主要介绍步长为2的卷积 VS 步长为1的卷积 + 间隔删除(美颜BeautyGAN),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

用以前的代码并不能实现 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<di.depth;i++)
			for(int j=0;j<di.height;j++)
			{
				s+=si.width;//<---------先跳过一行
				for(int k=0;k<di.width;k++)
				{
					s++;//<---------先跳过一格
					*d++ = *s++;
					//s++;//<-------后跳过一格
				}
				//s+=si.width;//<-------后跳过一行
			}

	}
	else
		cout<<"隔行列删 出错了!";
}

这样就和《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"<<w<<endl;

	int w边=(wid-w)/2;
	//可能有的1像数
	//int x0=wid-w-w边*2;

	int h边=(hei-h)/2;
	//可能有的1像数
	int y0=hei-h-h边*2;

	卷积层 t(w,h,di.depth);
	t.data=new float[w*h*di.depth]; 

	int wc=di.width;

	//复制内容
	float *s=di.data;
	float *d=t.data;
	for(int j=0;j<di.depth;j++)
	{
		s +=wc*h边;//跳过上边

		for(int i=0;i<h;i++)
		{
			
				cblas_scopy(w,s+w边 , 1, d, 1);
				//下一位置
				s+=wc;
				d+=w;

		}
					
		s +=wc*(h边+y0);//跳过下边

	}
	//删除原来的,设置新的
	delete []di.data;  di.data=NULL;  
	di.data=t.data;
	di.width=w;di.height=h;


}

输入图:

输出的8个图:

下载:

人脸美颜程序

win32人脸图像美容处理程序,由《BeautyGAN-matser》模型权重转换而来

https://download.csdn.net/download/juebai123/11777059

最后

以上就是甜美小天鹅为你收集整理的步长为2的卷积 VS 步长为1的卷积 + 间隔删除(美颜BeautyGAN)的全部内容,希望文章能够帮你解决步长为2的卷积 VS 步长为1的卷积 + 间隔删除(美颜BeautyGAN)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部