首页 > 解决方案 > 使用 NumPy 验证 Keras Conv2D 卷积返回不同层输出

问题描述

我正在尝试使用标准 Keras 验证我的网络构建的第一层的输出。第一层的名称是 conv2d。

我构建了一个新模型只是为了获得第一层的输出,使用以下代码:

inter_layer = None
weights = None
biases = None

for layer in qmodel.layers:
    if layer.name == "conv2d":
        print("Found layer: " + layer.name)
        inter_layer = layer
        weights = layer.get_weights()[0]
        biases = layer.get_weights()[1]

inter_model = Model(qmodel.input,inter_layer.output)

inter_model.compile()

然后,我做了以下事情(img_test 是 cifar10 图像之一):

first_layer_output = inter_model.predict(img_test)

# Get the 3x3 pixel upper left patch of the 3 channels of the input image
img_test_slice = img_test[0,:3,:3,:]
# Get only the first filter of the layer
weigths_slice = weights[:,:,:,0]
# Get the bias of the first filter of the layer
bias_slice = biases[0]
# Get the 3x3 pixel upper left patch of the first channel of the output of the layer
output_slice = first_layer_output[0,:3,:3,0]

我打印了每个切片的形状,并得到了正确的形状:

据我了解,如果我这样做:

partial_sum = np.multiply(img_test_slice,weigths_slice)
output_pixel = partial_sum.sum() + bias_slice

output_pixel 应该是 output_slice 的值之一(实际上是索引 [1,1] 中的值,因为该层具有 padding = 'SAME')。

但是......它不是。

也许我遗漏了一些关于卷积计算如何工作的非常简单的东西,但据我所知,进行元素乘法然后对所有值求和加上偏差应该是该层的输出像素之一。

也许层的输出数据的排列方式与层的输入不同?

标签: pythonnumpytensorflowkerasconvolution

解决方案


问题是使用 get_weights 方法。

我的模型使用的是 QKeras 层,当你使用这个层时,你不应该使用 get_weights 来获取层权重,而是 insted 做一些类似的事情:

for quantizer, weight in zip(layer.get_quantizers(), layer.get_weights()):
    if quantizer:
        weight = tf.constant(weight)
        weight = tf.keras.backend.eval(quantizer(weight))

如果你使用这个 for 循环提取权重,你会得到真正的量化权重,所以现在计算是正确的。


推荐阅读