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