在神经网络中进行量化后,是否需要按权重比例的反比例来缩放输出

时间:2019-02-16 17:20:37

标签: tensorflow machine-learning keras artificial-intelligence

我目前正在编写脚本,以将Keras模型量化至8位。我通过对权重和偏差进行正态分布,然后对均值的2个标准偏差内的所有值插值到[-128,127]范围,对权重进行基本的线性缩放。 所有这些都有效,我通过推理来运行模型,但是我的图像非常糟糕。我知道性能会受到很小的影响,但性能下降约10倍。 我的问题是,在对权重进行缩放之后,是否需要对输出进行逆缩放操作?我读过的所有论文似乎都没有提到这一点,但是我不确定为什么我的结果会这么差。

该网络用于图像去马赛克。它可以获取RAW图像,并且可以输出噪声非常低且没有去马赛克效果的图像。我的全精度模型非常好,图像PSNR约为40-43dB,但是经过量化后,我得到4-8dB的图像,而且图像质量令人难以置信。

想要阅读的人的代码

for i in layer_index:
    count = count+1
    layer = model.get_layer(index = i);
    weights = layer.get_weights();
    weights_act = weights[0];

    bias_act = weights[1];

    std = np.std(weights_act)
    if (std > max_std):
        max_std = std

    mean = np.mean(weights_act)
    mean_of_mean = mean_of_mean + mean


   mean_of_mean = mean_of_mean / count

max_bound = mean_of_mean + 2*max_std
min_bound = mean_of_mean - 2*max_std

print(max_bound, min_bound)


for i in layer_index:
    layer = model.get_layer(index = i);
    weights = layer.get_weights();
    weights_act = weights[0];
    bias_act = weights[1];
    weights_shape = weights_act.shape;
    bias_shape = bias_act.shape;
    new_weights = np.empty(weights_shape, dtype = np.int8)
    print(new_weights.dtype)
    new_biass = np.empty(bias_shape, dtype = np.int8)

    for a in range(weights_shape[0]):
        for b in range(weights_shape[1]):
            for c in range(weights_shape[2]):
                for d in range(weights_shape[3]):
                    new_weight = (((weights_act[a,b,c,d] - min_bound) * (127 - (-128)) / (max_bound - min_bound)) + (-128))
                    new_weights[a,b,c,d] = np.int8(new_weight)
                    #print(new_weights[a,b,c,d], weights_act[a,b,c,d])

    for e in range(bias_shape[0]):
        new_bias = (((bias_act[e] - min_bound) * (127 - (-128)) / (max_bound - min_bound)) + (-128))
        new_biass[e] = np.int8(new_bias)

    new_weight_layer = (new_weights, new_biass)
   layer.set_weights(new_weight_layer)

1 个答案:

答案 0 :(得分:0)

您不会按照自己的意愿去做,我会解释。 如果您希望采用预先训练的模型并对其进行量化,则必须在涉及权重的每个操作之后添加比例,例如以卷积操作为例。 如我们所知,在我的身体中,卷积运算是线性的,为简单起见,我将忽略偏差(添加他相对容易),假设X是我们的输入Y是我们的输出,W是权重,那么卷积可以写成:

Y=W*X

其中'*'代表卷积运算,您基本上要做的是将权重乘以某个标量(称其为'a')并将其乘以其他标量(称其为'b')。因此在模型中,您使用W',其中:W'= Wa+b

因此,如果我们返回卷积运算,则可以在您的量化网络中得到基本的下一个运算:Y' = W'*X = (Wa+b)*X

因为卷积是线性的,我们得到:Y' = a(W*X) + b*X' 不要忘记,在您的网络中,您想在卷积的输出端收到Y而不是Y',因此您必须进行shift +重新缩放以获得正确答案。

因此,在做出了这样的解释(我希望已经很清楚了)之后,我希望您能够理解网络中存在的问题,您可以进行此规模测量并转移到所有的权重上,而您永远无法弥补,我认为您的困惑是因为您读过的论文从一开始就以量化模式对模型进行了训练,而没有采用预先训练的模型对其进行了量化。

对于您的问题,我认为tensorflow图转换工具可能会有所帮助,请看一下: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/graph_transforms/README.md

如果您想了解有关量化预训练模型的更多信息,可以在中找到更多信息(有关更多学术信息,请访问Scholar.google.com: https://www.tensorflow.org/lite/performance/post_training_quantization