在前面的“超分辨重建”部分有个批归一化(BatchNorm),和这个差不多,那个是训练时计算的,我们只是拿来用,这里是实时计算。
y=(x-均值)/sqrt(方差+微小值)
对每个通道分别处理:
void vl_Norm(卷积层 * out)
{
float epsilon = 10E-9 ;//10E-4 ;
float u, std;// 均值 方差
float * s=out->data, *s0;
float p;
int WH = out->height * out->width;
for (int c=0; c<out->depth; ++c)//对每个通道分别计算和处理
{
//先求均值
u=0;
std=0;
s0=s;
for (int i=0; i<WH; ++i)
{
p = *s0++;
u += p;//和
std += p*p;//平方
}
u /= WH; //均值
//cout<<"u:"<<u<<endl;
//
std=sqrt(std/WH-u*u+epsilon);//方差
//cout<<"std:"<<std<<endl;
// 输入归一化
s0=s;
for (int i=0; i<WH; ++i)
{
p = *s0;//
*s0++ = (p-u)/std;//均值 方差
}
s+=WH;//下一通道
}
}
另外原文中的relu 中有个“将nan转换为零”的动作,这里则不用了(只将权重中的nan替换成零),可能会对结果有影响吧。
原relu:
def relu(input):
relu = tf.nn.relu(input)
# 将nan转换为零 (nan != nan)
nan_to_zero = tf.where(tf.equal(relu, relu), relu, tf.zeros_like(relu))
return nan_to_zero
主要是我还不知道在c++中要怎样处理nan。
这章结束