python - 使用 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]
我打印了每个切片的形状,并得到了正确的形状:
- img_test_slice: (3,3,3)
- 重量切片:(3,3,3)
- 输出切片:(3,3)
据我了解,如果我这样做:
partial_sum = np.multiply(img_test_slice,weigths_slice)
output_pixel = partial_sum.sum() + bias_slice
output_pixel 应该是 output_slice 的值之一(实际上是索引 [1,1] 中的值,因为该层具有 padding = 'SAME')。
但是......它不是。
也许我遗漏了一些关于卷积计算如何工作的非常简单的东西,但据我所知,进行元素乘法然后对所有值求和加上偏差应该是该层的输出像素之一。
也许层的输出数据的排列方式与层的输入不同?
解决方案
问题是使用 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 循环提取权重,你会得到真正的量化权重,所以现在计算是正确的。
推荐阅读
- r - 如何在我的 Arima 预测图的 xaxis 上获取日期而不仅仅是数字
- javascript - 为什么我的 onClick 在渲染时会激活?
- sql - Oracle 11g DB 链接使用情况
- python-3.x - 通过 package_data 将非 python 文件复制到 Scripts 目录
- chef-infra - 如何从执行资源命令输出中设置节点属性值
- c++ - 有人可以为此提供伪代码吗?
- sql - 将两列与 SQL Server 2008 中其他表中的列连接并比较?
- c# - ChromelyResponse.Status 被忽略
- r - 为什么这个线性模型的拟合值不连续?
- c# - 带有 Access 数据库的 ASP.NET 中的插入子句问题