我有一个在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)
答案 0 :(得分:0)
很抱歉,我对tensorflow并不熟悉,所以我无法提供代码,但是也许我对caffe模型进行量化的经验很有意义。
如果我对您的理解正确,则您有一个tensorflow模型(float32),您想将其量化为int8并将其保存在numpy.array
中。
首先,您应该读取每一层的所有权重,这可能是python列表或numpy.array
或其他东西,没关系。
然后,量化算法将极大地影响精度,您必须为模型选择最佳算法。但是,这些算法具有相同的核心-规模。您需要做的就是将所有权重缩放到-127到127(int8),就像没有scale
的{{1}}层一样,并记录比例因子。
平均值,如果要在FPGA上实现,则数据也应量化。这是一个新问题-int8 * int8的结果是int16,这显然是溢出。
为解决此问题,我们创建了一个新参数-shift-将int16结果移回int8。注意,bias
参数不是常数8,假设我们有0 * 0 = 0,我们根本不需要移动结果。
我们应该考虑的最后一个问题是,如果网络太深,则由于某些不合理的shift
参数,层结果可能会溢出,因此我们无法直接对每个单独的层进行量化而不考虑其他层。
在FPGA上完成所有网络之后,如果要将int8反量化为float32,只需使用(最终结果的)最后一个scale参数进行mul / div(取决于您定义scale
的方式)。
这是基本的量化算法,其他类似scale
的算法可能具有更高的准确性。现在我们有了量化模型,您可以将其保存到所需的任何内容中,这不是一件容易的事。
P.S。为什么会麻木? bin文件最适合FPGA,不是吗?
而且,您对在FPGA上实现softmax有什么想法?我对此感到困惑...