Keras模型评估与量化权重后训练

5
我有一个在Keras中训练的模型,保存为.h5文件。该模型使用TensorFlow后端进行单精度浮点值训练。现在我想实现一个硬件加速器,在Xilinx FPGA上执行卷积操作。但是,在决定在FPGA上使用的定点位宽之前,我需要通过将权重量化为8或16位数字来评估模型准确性。我看到了tensorflow quantise,但不确定如何处理每个层的权重、量化并存储在numpy数组列表中。在所有层都被量化后,我想将模型的权重设置为新形成的量化权重。请问是否能帮助我完成这个过程?
以下是我尝试将精度从float32降至float16的方法,请告知是否正确。
for i in range(len(w_orginal)):
temp_shape = w_orginal[i].shape
print('Shape of index: '+ str(i)+ 'array is :')
print(temp_shape)
temp_array = w_orginal[i]
temp_array_flat = w_orginal[i].flatten()
for j in range(len(temp_array)):
    temp_array_flat[j] = temp_array_flat[j].astype(np.float16)

temp_array_flat = temp_array_flat.reshape(temp_shape)
w_fp_16_test.append(temp_array_flat)
1个回答

0

很抱歉我不熟悉tensorflow,所以无法提供代码,但是我的量化caffe模型的经验或许有帮助。

如果我理解正确,您有一个tensorflow模型(float32),想将其量化为int8并保存在numpy.array中。

首先,您应该读取每个层的所有权重,这可能是python列表或numpy.array或其他什么东西,都没有关系。

然后,量化算法将显着影响准确性,您必须为您的模型选择最佳算法。然而,这些算法具有相同的核心--比例尺。您需要做的就是将所有权重缩放到-127至127(int8),就像没有biasscale层一样,并记录比例因子。

同时,如果要在FPGA上实现它,则数据也应进行量化。这里我们有一个新问题--int8 * int8的结果是int16,这显然会溢出。

为了解决这个问题,我们创建了一个新的参数--shift--将int16结果转换回int8。需要注意的是,shift 参数不会恒定为8,例如当0 * 0 = 0时,我们根本不需要移位结果。
我们需要考虑的最后一个问题是,如果网络太深,在某些不合理的scale参数下,层结果可能会溢出,因此我们不能直接量化每个单独的层而不考虑其他层。
在FPGA上完成所有网络操作后,如果您想将int8反量化为float32,只需使用最后一个尺度参数(即最终结果)进行一些乘除(取决于如何定义scale)。
这是一个基本的量化算法,类似于tf.quantization的其他算法可能具有更高的精度。现在我们已经有了量化模型,你可以保存到任何你喜欢的地方,这不难。
附:为什么使用Numpy?.bin文件不是FPGA上的最佳选择吗?
另外,你有关于在FPGA上实现Softmax的想法吗?我对此感到困惑...

是的...这就是我想做的...但很抱歉,我不明白如何将float32数值缩放到范围为-127至127的int8中...这对我来说有些困惑。接下来是处理溢出的问题...如果结果大于127或小于-127...我只需将其向上取整到最大可能值...这就是我想做的...但keras内部仍然将这些值视为float32。 - frisco_1989
量化就像是一个反向过程,你可以尝试将结果缩放到int8,然后你就会知道缩放输入数据的范围,而输入数据是前一层的结果... - ID.W
抱歉,我不知道如何从Keras中获取float32数字...但我认为这是Keras应该具备的基本功能。尝试在用户指南中查找? - ID.W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接