如何从keras中的Conv2D正确获取图层权重?
How to correctly get layer weights from Conv2D in keras?
我将 Conv2D 层定义为:
Conv2D(96, kernel_size=(5, 5),
activation='relu',
input_shape=(image_rows, image_cols, 1),
kernel_initializer=initializers.glorot_normal(seed),
bias_initializer=initializers.glorot_uniform(seed),
padding='same',
name='conv_1')
这是我网络中的第一层。
输入尺寸为 64 x 160,图像为 1 个通道。
我正在尝试从这个卷积层可视化权重,但不确定如何获得它们。
这是我现在的做法:
1.Call
layer.get_weights()[0]
这将返回一个形状为 (5, 5, 1, 96) 的数组。 1 是因为图像是 1 通道的。
2.Take 5 x 5 过滤器
layer.get_weights()[0][:,:,:,j][:,:,0]
非常难看,但我不确定如何简化它,非常感谢您提出任何意见。
我不确定这 5 x 5 个方格。它们实际上是过滤器吗?
如果没有,谁能告诉我如何正确地从模型中获取过滤器?
我试着只显示前 25 个权重。我和你有同样的问题,是过滤器还是其他问题。它似乎与源自深度信念网络或堆叠 RBM 的过滤器不同。
这是未经训练的可视化权重:
这是经过训练的权重:
奇怪的是训练后没有任何变化!如果你比较它们,它们是相同的。
然后 DBN RBM 在顶部过滤第 1 层,在底部过滤第 2 层:
如果我设置 kernel_intialization="ones" 那么我得到的过滤器看起来不错,但净损失永远不会减少,尽管经过多次试验和错误更改:
这是显示 2D Conv 权重/过滤器的代码。
ann = Sequential()
x = Conv2D(filters=64,kernel_size=(5,5),input_shape=(32,32,3))
ann.add(x)
ann.add(Activation("relu"))
...
x1w = x.get_weights()[0][:,:,0,:]
for i in range(1,26):
plt.subplot(5,5,i)
plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
plt.show()
ann.fit(Xtrain, ytrain_indicator, epochs=5, batch_size=32)
x1w = x.get_weights()[0][:,:,0,:]
for i in range(1,26):
plt.subplot(5,5,i)
plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
plt.show()
------------------------更新---------------- ------
所以我再次尝试使用 0.01 的学习率而不是 1e-6,并通过将图像除以 255.0 使用在 0 和 1 之间而不是 0 和 255 之间归一化的图像。现在卷积滤波器发生变化,第一个卷积滤波器的输出如下所示:
您会注意到经过训练的过滤器发生了变化(变化不大)且学习率合理:
这是CIFAR-10测试集的图七:
这是第一个卷积层的输出:
如果我采用最后一个卷积层(中间没有密集层)并将其提供给未经训练的分类器,它类似于在准确性方面对原始图像进行分类,但如果我训练卷积层,最后一个卷积层输出提高分类器(随机森林)的准确性。
所以我会得出结论,卷积层确实是过滤器和权重。
在layer.get_weights()[0][:,:,:,:]中,[:,:,:,:]中的维度是权重的x位置,权重的y位置,第 n 个输入到相应的 conv 层(来自上一层,请注意,如果您尝试获取第一个 conv 层的权重,那么这个数字是 1,因为只有一个输入被驱动到第一个 conv 层)和第 k 个分别对应层中的过滤器或内核。因此,layer.get_weights()[0] 返回的数组形状可以解释为只有一个输入被驱动到该层,并生成 96 个 5x5 大小的过滤器。如果你想访问其中一个过滤器,你可以输入,比如说第 6 个过滤器
打印(layer.get_weights()[0][:,:,:,6].squeeze())。
但是,如果您需要第二个转换层的过滤器(参见下面的模型图像 link),请注意 32 个输入图像或矩阵中的每一个都有 64 个过滤器。如果你想获得其中任何一个的权重,例如为第 8 个输入图像生成的第 4 个过滤器的权重,那么你应该输入
打印(layer.get_weights()[0][:,:,8,4].squeeze())。
enter image description here
我将 Conv2D 层定义为:
Conv2D(96, kernel_size=(5, 5),
activation='relu',
input_shape=(image_rows, image_cols, 1),
kernel_initializer=initializers.glorot_normal(seed),
bias_initializer=initializers.glorot_uniform(seed),
padding='same',
name='conv_1')
这是我网络中的第一层。
输入尺寸为 64 x 160,图像为 1 个通道。
我正在尝试从这个卷积层可视化权重,但不确定如何获得它们。
这是我现在的做法:
1.Call
layer.get_weights()[0]
这将返回一个形状为 (5, 5, 1, 96) 的数组。 1 是因为图像是 1 通道的。
2.Take 5 x 5 过滤器
layer.get_weights()[0][:,:,:,j][:,:,0]
非常难看,但我不确定如何简化它,非常感谢您提出任何意见。
我不确定这 5 x 5 个方格。它们实际上是过滤器吗?
如果没有,谁能告诉我如何正确地从模型中获取过滤器?
我试着只显示前 25 个权重。我和你有同样的问题,是过滤器还是其他问题。它似乎与源自深度信念网络或堆叠 RBM 的过滤器不同。
这是未经训练的可视化权重:
这是经过训练的权重:
奇怪的是训练后没有任何变化!如果你比较它们,它们是相同的。
然后 DBN RBM 在顶部过滤第 1 层,在底部过滤第 2 层:
如果我设置 kernel_intialization="ones" 那么我得到的过滤器看起来不错,但净损失永远不会减少,尽管经过多次试验和错误更改:
这是显示 2D Conv 权重/过滤器的代码。
ann = Sequential()
x = Conv2D(filters=64,kernel_size=(5,5),input_shape=(32,32,3))
ann.add(x)
ann.add(Activation("relu"))
...
x1w = x.get_weights()[0][:,:,0,:]
for i in range(1,26):
plt.subplot(5,5,i)
plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
plt.show()
ann.fit(Xtrain, ytrain_indicator, epochs=5, batch_size=32)
x1w = x.get_weights()[0][:,:,0,:]
for i in range(1,26):
plt.subplot(5,5,i)
plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
plt.show()
------------------------更新---------------- ------
所以我再次尝试使用 0.01 的学习率而不是 1e-6,并通过将图像除以 255.0 使用在 0 和 1 之间而不是 0 和 255 之间归一化的图像。现在卷积滤波器发生变化,第一个卷积滤波器的输出如下所示:
您会注意到经过训练的过滤器发生了变化(变化不大)且学习率合理:
这是CIFAR-10测试集的图七:
这是第一个卷积层的输出:
如果我采用最后一个卷积层(中间没有密集层)并将其提供给未经训练的分类器,它类似于在准确性方面对原始图像进行分类,但如果我训练卷积层,最后一个卷积层输出提高分类器(随机森林)的准确性。
所以我会得出结论,卷积层确实是过滤器和权重。
在layer.get_weights()[0][:,:,:,:]中,[:,:,:,:]中的维度是权重的x位置,权重的y位置,第 n 个输入到相应的 conv 层(来自上一层,请注意,如果您尝试获取第一个 conv 层的权重,那么这个数字是 1,因为只有一个输入被驱动到第一个 conv 层)和第 k 个分别对应层中的过滤器或内核。因此,layer.get_weights()[0] 返回的数组形状可以解释为只有一个输入被驱动到该层,并生成 96 个 5x5 大小的过滤器。如果你想访问其中一个过滤器,你可以输入,比如说第 6 个过滤器 打印(layer.get_weights()[0][:,:,:,6].squeeze())。 但是,如果您需要第二个转换层的过滤器(参见下面的模型图像 link),请注意 32 个输入图像或矩阵中的每一个都有 64 个过滤器。如果你想获得其中任何一个的权重,例如为第 8 个输入图像生成的第 4 个过滤器的权重,那么你应该输入 打印(layer.get_weights()[0][:,:,8,4].squeeze())。 enter image description here