如何在 Tensorflow 2 中获取 Conv2D 内核值

Posted

技术标签:

【中文标题】如何在 Tensorflow 2 中获取 Conv2D 内核值【英文标题】:How to get Conv2D kernel values in Tensorflow 2 【发布时间】:2022-01-21 14:28:18 【问题描述】:

问题

我有一个Conv2D 层:

l0 = tf.keras.layers.Conv2D(1, 3, activation=None, input_shape=(36,36,3))

我想找出所用过滤器/内核矩阵中的确切值(不仅仅是它们的数量)。 如何访问内核矩阵值?


解决方案尝试

import tensorflow as tf
import numpy as np

我创建了一个 numpy 数组:

x_core = np.array([[1,0,0,1],
                   [0,0,0,0],
                   [0,0,0,0],
                   [1,0,0,1]],dtype=float)

将其转换为(1,4,4,1)张量的形状:

x = tf.expand_dims(tf.expand_dims(tf.convert_to_tensor(x_core),axis=0),axis=3)

使用strides=(2,2) 对其应用Conv2D 层。这意味着输出将是一个 2 × 2 矩阵,其中左上角的值将等于内核矩阵中的左上角值,结果的右上角将等于内核矩阵的右上角,以此类推在。 (x_core 中的特殊零和一实现了这一点。)

y = tf.keras.layers.Conv2D(1, 2, strides=(2,2), activation=None, input_shape=x.shape[1:])(x)

但是,如果我重新运行代码,y 会发生变化,即过滤器不是恒定的,这表明内核矩阵是从分布中提取的。


类似问题

类似但不同的问题:How to get CNN kernel values in Tensorflow - 此方法仅适用于 Tensorflow 1。存在问题:

gr = tf.get_default_graph()AttributeError: module 'tensorflow' has no attribute 'get_default_graph'

如果我用Graph 替换get_default_graph(因为我相信这是较新的等价物),请将name="conv1" 放入我的层定义:conv_layer_1 = tf.keras.layers.Conv2D(1, 2, strides=(2,2), activation=None, input_shape=x.shape[1:],name="conv1"),然后按照建议运行conv1_kernel_val = tf.Graph().get_tensor_by_name('conv1/kernel:0').eval(),我得到:

KeyError: "名称 'conv1/kernel:0' 指的是一个不 存在。图中不存在“conv1/kernel”操作。”

【问题讨论】:

这可能会有所帮助How to correctly get layer weights from Conv2D in keras? 【参考方案1】:
import tensorflow as tf

input_shape = (4, 28, 28, 3)
x = tf.random.normal(input_shape)
model = tf.keras.layers.Conv2D(2, 3, activation='relu', input_shape=input_shape[1:])
y = model(x)
print(model.kernel)

【讨论】:

谢谢。如果我省略了 y = model(x) 行,你知道为什么这不起作用吗? 模型第一次调用就建好了

以上是关于如何在 Tensorflow 2 中获取 Conv2D 内核值的主要内容,如果未能解决你的问题,请参考以下文章

比较 Conv2D 与 Tensorflow 和 PyTorch 之间的填充

在 Tensorflow 中重用层权重

pytorch 与 tensorflow 2.0 的视图等效性是啥?

tf.nn.conv2d 在 tensorflow 中做了啥?

TensorFlow 中 conv2d 的确切含义

tensorflow中踩过的坑