先上图(输入图):
SRGAN-tensorflow-master生成的图(目标图):
从上一篇中最后说过,从后向前调试,把tf 的中间层数据输入到某一层,再和目标图比较,相同则通过,否则继续找原因
这个输入图暂时只是提供图像尺寸用
后处理:
def deprocess(image):
with tf.name_scope("deprocess"):
# [-1, 1] => [0, 1]
return (image + 1) / 2
这个[-1, 1] => [0, 1] 是不对称的,输入部分不作相反处理,也就是说是这样的:
0,255 --> 0,1-->网络(-1,1) --> 0,1 --> 0,255
数据 0,1在网络中最后已经变成 -1,1 了
这一点比较新鲜,估计和Prelu激励有关吧
而后 BGR 转换到RGB:
void RGB2BGR(卷积层 & di) //R B 通道互换
{
int wh=di.width * di.height;
float * tmp =new float[wh];
memcpy(tmp, di.data+wh*2, wh*sizeof(float)); //3->tmp 暂存
memcpy(di.data+wh*2, di.data, wh*sizeof(float)); //1->3 r->b
memcpy(di.data, tmp, wh*sizeof(float)); //3(tmp)->1 b->r
delete []tmp; tmp=NULL;
}
据说tf内部是BGR格式(已忘记从哪看来的了),这时输出层已经可以输出一样的图了
然后是亚素数卷积层(pixelShuffler),这个包含一个卷积(64通道扩维到256)和一个像数组合(降维回64,图像放大2倍)
void 放大排列256_64(卷积层*si,卷积层*di)
//Pixelshuffler (亚像素卷积层)像素混组
{
//bottom
const int bn = 1;//图像数
const int bc = si->depth;
const int bh = si->height;
const int bw = si->width;
//top
//const int tn = top_shape[0];
const int tc = di->depth;
const int th = di->height;
const int tw = di->width;
int test_r1 = bc/tc;//缩放比值的平方 通道比值
const int r = th / bh;//缩放比值 2
//int test_r2 = r * r;
//CHECK_EQ( test_r1, test_r2) << "Pixelshuffler output is illegal";
const float* bottom_data = si->data;//bottom[0]->cpu_data();
float* top_data = di->data;//top[0]->mutable_cpu_data();
int top_index = 0;
int bottom_index = 0;
int new_c = 0;
int new_h = 0;
int new_w = 0;
for(int n = 0; n < bn; n++){
for(int c = 0; c < bc; c++){
for(int h = 0; h < bh; h++){
for(int w = 0; w < bw; w++){
new_c = static_cast<int>(floor((float)c/(r*r)));
new_h = h*r + (static_cast<int>(floor((float)c/r)))%r;
new_w = w*r+ (c%(r*r))%r;
top_index =n*(tc*th*tw)+ new_c*(th*tw)+ new_h*tw+ new_w;
top_data[top_index] = bottom_data[bottom_index];
bottom_index++;
}
}
}
}
}
这个是从caffe_srgan-master中抄来的,我把它改名为'放大排列256_64'只是便于理解,实际上它也可以用于其它地方,
比如espcn的3倍放大(9通道合成1通道)和2倍放大(4通道合成1通道)
这部分也可以了。
最后提供一个下载:
我从ESPCN-TensorFlow-master中改编过来的32位espcn超分辨重建(2倍)
其中一个用了OpenBLAS加速,加速后飞快(按照他们自己的说法,矩阵乘法可以加快10倍)
地址(百度网盘):