Conv2D 在 tflite 图中的奇怪输出

Strange output of Conv2D in tflite graph

我有一个 tflite 图形片段,其描述在所附图片中

我需要调试它的行为,但在第一步我就得到了非常令人费解的结果。 当我在第一个 Conv2D 之后输入零张量作为输入时,我希望得到一个仅由 Conv2D 的偏差值组成的张量(因为所有内核元素都乘以零),但我得到了一个由一些随机数据组成的张量,这里是代码片段:

def test_graph(path=PATH_DEFAULT):
    interp = tf.lite.Interpreter(path)
    interp.allocate_tensors()

    input_details = interp.get_input_details()
    in_idx = input_details[0]['index']

    zeros = np.zeros(shape=(1, 256, 256, 3), dtype=np.float32)
    interp.set_tensor(in_idx, zeros)
    interp.invoke()

    # index of output of first conv2d operator is 3 (see netron pic)
    after_conv_2d = interp.get_tensor(3)

    # shape of bias is just [count of output channels]
    n, h, w, c = after_conv_2d.shape

    # if we feed zeros as input, we can expect that the only values we get are the values of bias
    # since all kernel elems in that case are multiplied by zeros

    uniq_vals_cnt = len(np.unique(after_conv_2d))
    assert uniq_vals_cnt <= c, f"There are {uniq_vals_cnt} in output, should be <= than {c}"

输出:

AssertionError: There are 287928 in output, should be <= than 24

谁能帮我解开我的误解?

我认为我可以从解释器获得任何中间张量的假设似乎是错误的,我们只能对输出这样做,即使解释器不会引发错误,甚至为与非输出相关的索引给出正确形状的张量强度。

调试此类图的一种方法是生成所有张量输出,但似乎最简单的方法是使用 tocotflite 文件转换为 pb,然后将 pb 转换回 tflite 并指定新的输出。这种方式并不理想,因为 tocotflite -> pb 转换的支持在 1.9 之后被删除,并且使用之前的版本可能会在某些图表上中断(在我的情况下它会中断)。

更多内容在这里: