C++实现超分辨率 RCAN

RCAN(由很深的通道注意力的残差网络实现的图像超分辨率)

在RCAN-master 中有模型(百度网盘),现在我们来实现其中的4倍模型 :RCAN_BIX4.pt

由 Pytorch 中导出后有156M大。

流程图:

 定义数据池:

1。残差缩放块

struct 残差缩放块 //自适应调整残差(训练得缩放比)
{

	层数据 * conv1;//64-->64	块尾层
	//relu
	层数据 * conv2;//64-->64	块尾层 (x)

	//自动缩放残差
	//自适应池化(1)	在这里就是求通道平均值 w x h --> 1
	层数据 * conv3;//64-->4	
	层数据 * conv4;//4-->64	            
	//sigmoid  生成 1 个缩放值(y)(0-1间的数)(每通道)
	//x=y*x
};

2。残差组

struct 残差组 
{

	//int 残差缩放块数量;// 20
	残差缩放块 * 伸缩块;//64-->64
	层数据 * conv;//64-->64	块尾层
	//res += x

};

3。模型

struct RCAN模型
{
		
	层数据 * 减均值;//3->3


    //头部----------------------
	//浅层特征提取
	层数据 * conv1;//3->64

	//主体----------------------
	int 残差组数量;//10块
	残差组 * 块;

	//主体尾层
	层数据 * conv2; //64-->64

	//全局残差相加

	//尾部----------------------
	//放大
	层数据 * up1;//64->256 
	//亚像素卷积 256->64 放大2倍
	层数据 * up2;//64->256 
	//亚像素卷积 256->64 放大2倍
	
	//输出
	层数据 * out;//64->3 

	层数据 * 加均值;//3->3

	//构造函数
	RCAN模型();

};

初始化:

RCAN模型::RCAN模型()
{

	int size;
	层数据 * 层;


	/*名称,输入维度,输出维度,核宽*/
		初始化层(减均值,3,3,1);
		初始化层(加均值,3,3,1);

		初始化层(conv1,3,64,3);

		残差组数量=10;
		size = sizeof(残差组)*残差组数量;
		块=(残差组*)malloc(size);
		残差组 * 残差组0=块;
		for (int k0 = 0;k0<残差组数量;k0++)
		{
			//残差组0->残差缩放块数量=20;
			size = sizeof(残差缩放块)*20;
			残差组0->伸缩块=(残差缩放块*)malloc(size);
			残差缩放块 * 残差缩放块0=残差组0->伸缩块;
			for (int k = 0;k<20;k++)
			{
				初始化层(残差缩放块0->conv1,64,64,3);
				初始化层(残差缩放块0->conv2,64,64,3);
				初始化层(残差缩放块0->conv3,64,4,1);
				初始化层(残差缩放块0->conv4,4,64,1);

				残差缩放块0++;
			}
			初始化层(残差组0->conv,64,64,3);

			残差组0++;
		}

		初始化层(conv2,64,64,3);

		初始化层(up1,64,256,3);
		初始化层(up2,64,256,3);

		初始化层(out,64,3,3);

}

先来看一下效果图:

小图

RCAN 4倍图

ESRGAN 4倍图

D-DBPN 4倍图

EDSR 4倍图

由这个体量是只能和ESRGAN、DBPN 比的,速度上和ESRGAN相近,DBPN最慢

EDSR飞快,并且效果相差不大。

---------------------------------------------------------分隔线----------------------------------------------------------------------

看这个图:RCAN 好象完全碾压 EDSR,实际上,是不可能相差这么大,因为哪个数据只相差一点点嘛 。

我们来实现RCAN的一个亮点(可训练通道残差缩放比的残差块):

static void 残差缩放块前传(残差缩放块 & b,卷积层 * 源,卷积层 * 目标/*,bool load*/)//从源 传入并返回,不从目标返回(只为方便用于宏)
{

	层数据 * 层;
	int pad;

	int wid=源->width;
	int hei=源->height;
	int wh= wid*hei;
	int whd=wh*源->depth;

	卷积层	输入备份(wid,hei,64);
	输入备份.data=new float[whd];//	
		
	卷积层复制(源,&输入备份);


	卷积层	备份(wid,hei,64);
	备份.data=new float[whd];//		

	卷积层 均值(1,1,64);
	均值.data=new float[64];

	卷积前传(b.conv1);
	卷积前传无RELU(b.conv2);
			//if(load) //调试对比时用
			//	load_mat2卷积层("me/conv_du_x.txt",源);
	卷积层复制(源,&备份);

	通道求均值(*源,均值.data);
			//if(load)
			//	//load_mat2卷积层("me/avg_pool.txt",源);
			//	save_卷积层2txt(&均值,"avg_pool.txt");
	Resize卷积层(*源,1,1,64);
	卷积层复制(&均值,源);


	均值卷积前传(b.conv3);
	均值卷积前传无RELU(b.conv4);

	vl_sigmoid(源);//标准化的均值

			//if(load)
				load_mat2卷积层("me/conv_du.txt",源);
			//				save_卷积层2txt(源,"conv_du.txt");


	/* //第1种方法
	卷积层复制(源,&均值);-----------------------

	Resize卷积层(*源,wid,hei,64);
	卷积层复制(&备份,源);

	卷积层乘以(*源,均值.data);//残差缩放

	卷积层相加(&输入备份,源);//输入加残差
	*/

	//* //第2种方法
	卷积层乘以(备份,源->data);//残差缩放
		
	Resize卷积层(*源,wid,hei,64);
	卷积层复制(&备份,源);//从源返回
	卷积层相加(&输入备份,源);//输入加残差

	//*/


}

该文作者能想出这个亮点已经非常了不起了,一般人真的想不出来,虽然EDSR抛弃了残差缩小比:

可以看出:RCAN 是用200个残差块来碾压 EDSR 的16个残差块的。

由于一张图,说了一些废话。

结束。

下载:

win32超分辩重建RCAN程序

win超分辨率重建 RCAN(4倍)的win32程序,由RCAN-master中的模型改编而来

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值