在FPGA上运行量化的TensorFlow模型 / 纯Python

3

我有一个在Keras上训练的模型,它是在MNIST数据集上训练的简单模型。

我想要做的是将这个模型重写并运行在FPGA设备上。为了做到这一点,我想要完全理解量化模型的工作原理。

首先,我使用后训练量化将此模型转换为.tflite格式和UINT8精度(https://www.tensorflow.org/lite/performance/post_training_quantization)。

因此,我有了量化模型,准确率约为90%。

现在,我尝试从量化模型中获取权重,并在纯Python中实现它。我使用这个工具来可视化并获取模型权重:https://github.com/lutzroeder/netron

虽然简单的Python代码(矩阵乘法、加偏置和relu)可以正常工作,但具有量化权重的代码却不能正常工作。

因此,我的问题是如何使用numpy编写前馈?

我的Keras模型如下:

model = Sequential()
model.add(Dense(512, input_shape=input_shape))
model.add(Activation(tf.nn.relu))
model.add(Dense(100))
model.add(Activation(tf.nn.relu))
model.add(Dense(num_classes))
model.add(Activation(tf.nn.softmax))
model.compile(
    optimizer=Adam(),
    loss='categorical_crossentropy',
    metrics=['accuracy'],
)

我使用TocoConverter进行了转换,并在tensorflow中运行成功。接下来,我尝试用纯Python编写前馈。
for img, label in zip(x_test, y_test):
    img = img.astype('uint8')
    total_seen += 1
    label = tf.keras.utils.to_categorical(label, num_classes=num_classes)
    X = img.reshape(1, 784)
    z1 = np.dot(X, W0.T) + b0
    a1 = relu(z1)
    z2 = np.dot(a1, W1.T) + b1
    a2 = relu(z2)
    z3 = np.dot(a2, W2.T) + b2
    prediction = np.argmax(z3)
    label = np.argmax(label)
    if prediction == label:
        num_correct += 1

但是这个模型的准确度只有约10%,所以出了些问题。如何纠正这个模型?
提前感谢您的帮助。
编辑: 我已经阅读了有关TensorFlow量化的论文: http://openaccess.thecvf.com/content_cvpr_2018/papers/Jacob_Quantization_and_Training_CVPR_2018_paper.pdf 我几乎知道所有事情,我知道激活和内核的S和Z值是什么。但是在矩阵乘法之后,它应该乘以因子:M:= S1 * S2 / S3。 我不知道S3比例是什么以及如何获得它。因为我在netron图中看不到任何相关内容。有什么建议吗?

请添加您正在尝试的代码示例,最好添加一些简单的示例以便人们可以看到问题所在。同时请注意代码注释以提高可读性。 - E.Coms
你成功在FPGA上实现了模型吗?我也在尝试同样的事情,但是无法找出正确的计算流程。 - Nazar
1个回答

0

你需要完成两个步骤:

  1. 将输入、权重和偏置反量化为完整精度(或整数等效)

    (w-w_offset)*w_scale

  2. 在 Relu 之后,将激活值重新量化为整数

    a/a_scale+a_offset

    你可以跳过第二步,即将激活值量化-反量化,但这样可能会略微增加与 TFlite 模型不同的风险。这是因为 Relu 没有上限,但 TFlite 会将其饱和到最大值。

你可以查看我的 TFlite 教程我的 Github,其中我介绍了概念和训练,并即将撰写推理内容。


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