前面已经准备好网络参数数据,这里正式开始。
这里只针对 FALSR-C.pb 模型,流程图:
定 义4残差块:
struct 残差块
{
//残差块-------------------------------->
//3x3
层数据 * cell2_bx_0;//48->96
层数据 * cell2_bx_d;//96->96 深度卷积
层数据 * cell2_bx_1;//96->48
//残差块--------------------------------<
};
定义模型数据池(有大概流程说明):
struct FALSR模型
{
//特征提取 3x3
层数据 * conv1;//1->32
//备份9 -->32
//部分0 1x1
层数据 * convg2_0;//组卷积(2分)//32(16)->32
//备份23 -->32
//连接 备份9 ,当前:32+32->64(短跳线)
//部分1 1x1(4个)
层数据 * cell1_0;//64->64
层数据 * cell1_1;//64->64
层数据 * cell1_2;//64->64
层数据 * cell1_3;//64->64
//备份53 -->64
//部分2 1x1
层数据 * cell2_s;//64->48
int 残差块数量;//(4个) 3x3
残差块 * 块;//48->96->48
//<---
//层数据 * cell2_bx_0;//48->96 普通卷积(每个通道用96个核 共48x96个) Conv2D
//层数据 * cell2_bx_d;//96->96 深度卷积 (每个通道用 1个核 共 96个) DepthwiseConv2dNative
//层数据 * cell2_bx_1;//96->48 普通卷积(每个通道用48个核 共96x48个)
//--->
//连接 备份23 ,当前:32+48->80(短跳线)
//部分3 1x1
层数据 * convg2_1;//组卷积(2分)//80(40)->32
//部分4 1x1
层数据 * convg4_2;//组卷积(4分)//32(16)->32
//连接 备份9 ,当前:32+32->64 (短跳线)
//部分5 1x1
层数据 * cell5_0;//64->48
层数据 * cell5_1;//48->48
层数据 * cell5_2;//48->48
层数据 * cell5_3;//48->48
//备份+0 -->48
//连接 备份23 ,当前:32+48->80(短跳线)
//部分6 3x3
层数据 * conv2;//80->16
//连接 备份9 ,备份53,备份+0,当前:32+64+48+16->160 (长、短跳线)
//合成 3x3
层数据 * conv3;//160->32
//备份9 + 当前 -->32 (总残差 长跳线)
//放大2倍
//(像素混组:DepthToSpace)32->8
//还原亮度通道 3x3
层数据 * conv4;//8->1
//构造函数
FALSR模型();
};
主函数:
void FALSR(char * savefilename,FALSR模型 & sr)
{
//
int wid=bmp.width;
int hei=bmp.height;
cout<<"输入图像宽度:"<<wid<<endl;
cout<<" 高度:"<<hei<<endl;
//
卷积层 Y(wid,hei);//亮度
Y.data=new float[wid * hei ];
//*
//--------------------------YUV---------------------1。开始
卷积层 U(wid,hei);//亮度
U.data=new float[wid * hei ];
卷积层 V(wid,hei);//亮度
V.data=new float[wid * hei ];
bmp2YUV(&Y,&U,&V);
//--------------------------YUV---------------------1。结束
//*/
/*
//-----------------------RGB-------------------------1。开始
卷积层 rgb(wid,hei,3);//亮度
rgb.data=new float[wid * hei * 3 ];
//jpg转换为RGB卷积层
bmp2RGB(rgb);
rgb2ypbpr(rgb);
{
卷积层 t(wid,hei);
t.data=rgb.data;
卷积层复制(&t,&Y);
}
//-------------------------RGB-----------------------1。结束
//*/
层数据 * 层;
//两个卷积层 交替前传(源,目标)
//用这个传回
卷积层 * di=(卷积层 *)malloc(sizeof(卷积层));
di->width=1;
di->height=1;
di->depth=1;
di->data=new float[1 ];
卷积层 *源,*目标;
源 = &Y;
目标 = di;
int pad;
cout<<"输入层..."<<endl;
卷积前传(sr.conv1);
//load_mat2卷积层("me/conv1.txt",源);
//conv1备份 <9>
卷积层 备份9(源->width,源->height,源->depth);
备份9.data=new float[源->width*源->height*源->depth ];
//备份
卷积层复制(源,&备份9);
//cell0--------------------------------------------------
cout<<"部分0..."<<endl;
//卷积前传(sr.convg2_0);
组卷积X分( *源,*目标,sr.convg2_0,2 );//2分组卷积
std::swap (源,目标);
//<23> 源
卷积层 备份23(源->width,源->height,源->depth);
备份23.data=new float[源->width*源->height*源->depth ];
卷积层复制(源,&备份23);
//<25> =<9><23>
//卷积层 * 连接0 = 卷积层连接(conv1备份,*源);
卷积层连接(备份9,备份23,*源);
//cell1--------------------------------------------------
cout<<"部分1..."<<endl;
卷积前传(sr.cell1_0);
卷积前传(sr.cell1_1);
卷积前传(sr.cell1_2);
卷积前传(sr.cell1_3);
//load_mat2卷积层("me/cell1_3.txt",源);
卷积层 备份53(源->width,源->height,源->depth);
备份53.data=new float[源->width*源->height*源->depth ];
卷积层复制(源,&备份53);
//cell2
cout<<"部分2..."<<endl;
卷积前传无RELU(sr.cell2_s);
//load_mat2卷积层("me/cell2-s.txt",源);//
残差块总成(sr,源);//从源传回
卷积层连接(备份23,*源,*目标);
std::swap (源,目标);
//load_mat2卷积层("me/concat_layer_1.txt",源);
//cell3
//cout<<"convg2_1.in:"<<源->depth<<endl;
cout<<"部分3..."<<endl;
//cout<<*(sr.convg2_1->偏移_数据)<<endl;
//cout<<*(sr.convg2_1->权重_数据)<<endl;
组卷积X分( *源,*目标,sr.convg2_1,2 );//2分组卷积
std::swap (源,目标);
//cout<<"convg2_1:"<<源->depth<<endl;
卷积层连接(备份9,*源,*目标);
std::swap (源,目标);
//load_mat2卷积层("me/concat_layer_2.txt",源);
//cell4
cout<<"部分4..."<<endl;
组卷积4分( *源,*目标,sr.convg4_2 );//4分组卷积
std::swap (源,目标);
卷积层连接(备份9,*源,*目标);
std::swap (源,目标);
//load_mat2卷积层("me/concat_layer_3.txt",源);
//cell5
cout<<"部分5..."<<endl;
卷积前传(sr.cell5_0);
卷积前传(sr.cell5_1);
卷积前传(sr.cell5_2);
卷积前传(sr.cell5_3);
//load_mat2卷积层("me/cell5_3.txt",源);
卷积层 备份a0(源->width,源->height,源->depth);
备份a0.data=new float[源->width*源->height*源->depth ];
卷积层复制(源,&备份a0);
卷积层连接(备份23,备份a0,*源);
//load_mat2卷积层("me/concat_layer_4.txt",源);
//cell6
cout<<"部分6..."<<endl;
卷积前传(sr.conv2);
//load_mat2卷积层("me/conv2.txt",源);
{
卷积层 *tmp1=卷积层连接(备份9,备份53);
卷积层 *tmp2=卷积层连接(*tmp1,备份a0);
卷积层连接(*tmp2,*源,*目标);
std::swap (源,目标);
del卷积层(*tmp1);
del卷积层(*tmp2);
}
//load_mat2卷积层("me/concat_layer_5.txt",源);
//合成降维
卷积前传(sr.conv3);
卷积层相加(&备份9,源);
//load_mat2卷积层("me/elementwise_layer_4.txt",源);
//删除备份
del卷积层(备份9);del卷积层(备份23);del卷积层(备份53);del卷积层(备份a0);
//放大
cout<<"放大2倍... "<<endl;
wid *= 2;hei *= 2;
Resize卷积层(*目标,wid,hei,sr.conv4->输入维度);
//像素混组(源,目标);
像数混组32_8(*源,*目标);//模拟tf的depth_to_space, 块大小:2 放大2倍
std::swap (源,目标);
//load_mat2卷积层("me/DepthToSpace.txt",源);
//loadk("t/conv4.txt",sr.conv4);
卷积前传无RELU(sr.conv4);
//load_mat2卷积层("me/out.txt",源);
//cout<<*(sr.conv4->偏移_数据)<<endl;
//cout<<*(sr.conv4->权重_数据)<<endl;
//原图放大2倍
ResizeGrayscaleImage(2.0);
//bicubic_resize(4.0);
wid=bmp.width;
hei=bmp.height;
//*
//--------------------YUV----------------------2。开始
卷积层 uY(wid,hei);//亮度
uY.data=new float[wid * hei ];
卷积层 uU(wid,hei);//亮度
uU.data=new float[wid * hei ];
卷积层 uV(wid,hei);//亮度
uV.data=new float[wid * hei ];
bmp2YUV(&uY,&uU,&uV);
//输入加上残差
卷积层复制(源,&uY);
// //save_卷积层2jpg(&uY,"uY");
YUV2bmp(&uY,&uU,&uV);
//--------------------YUV----------------------2。结束
//*/
/*
//---------------------RGB----------------------2。开始
Resize卷积层(rgb,wid,hei,3);
//jpg转换为RGB卷积层
bmp2RGB(rgb);
//
rgb2ypbpr(rgb);
{
卷积层 t(wid,hei);
t.data=rgb.data;
卷积层复制(源,&t);
卷积层 de(wid,hei,2);
de.data=rgb.data+wid*hei;
//load_mat2卷积层2("me/pbpr.txt",&de);
}
ypbpr2rgb(rgb);
//load_mat2卷积层2("me/rgb.txt",&rgb);
RGB2bmp(rgb);
//----------------------------RGB-----------------2。结束
//*/
del卷积层(*源);
del卷积层(*目标);
cout<<"图像转换成jpg格式... "<<endl;
savejpg(savefilename);
cout<<"转换文件已经保存为: "<<savefilename<<endl;
}
效果图:
小图
2倍图
结束。