【问题标题】:How to correctly get layer weights from Conv2D in keras?如何正确从 keras 中的 Conv2D 获取层权重?
【发布时间】:2017-09-04 11:27:32
【问题描述】:

我将 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.调用

layer.get_weights()[0]

这会返回一个形状数组 (5, 5, 1, 96)。 1 是因为图像是 1 通道的。

2.采用 5 x 5 过滤器

layer.get_weights()[0][:,:,:,j][:,:,0]

非常难看,但我不知道如何简化这一点,非常感谢任何 cmets。

我不确定这些 5 x 5 的方格。它们实际上是过滤器吗?
如果不能,请告诉如何正确地从模型中抓取过滤器?

【问题讨论】:

    标签: keras convolution keras-layer


    【解决方案1】:

    我试图只显示前 25 个的权重。我和你有同样的问题,这是过滤器还是其他东西。它似乎与源自深度信念网络或堆叠 RBM 的过滤器不同。

    这是未经训练的可视化权重:

    这里是训练好的权重:

    奇怪的是训练后没有任何变化!如果你比较它们,它们是相同的。

    然后 DBN RBM 在顶部过滤第 1 层,在底部过滤第 2 层:

    如果我设置 kernel_initialization="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 测试集的图片七:

    这是第一个卷积层的输出:

    如果我采用最后一个卷积层(中间没有密集层)并将其提供给未经训练的分类器,它类似于在准确性方面对原始图像进行分类,但如果我训练卷积层,最后一个卷积层输出会增加分类器的准确性(随机森林)。

    所以我会得出结论,卷积层确实是过滤器和权重。

    【讨论】:

    • 感谢您的回答!这是一件非常奇怪的事情:在随机初始化的情况下,权重是相似的。我正在使用推荐用于转换层的 glorot 初始化。对我来说最困惑的问题是:我们正在训练网络,但权重相同。我们训练了什么?对此没有答案...
    • 那么权重的第三维是什么?在x1w = x.get_weights()[0][:,:,0,:] 中,[:,:,0,:] 中的 0。我认为前两个维度是内核 x 和 y,最后一个是内核的数量——但我不知道第三维是什么。似乎是前一层输出的维度,但我不明白为什么或这究竟意味着什么。
    • 0 是红色通道。三个维度是红绿蓝。第一个是x,第二个是y,第三个是channel,最后一个是第n个卷积层。
    【解决方案2】:

    在layer.get_weights()[0][:,:,:,:]中,[:,:,:,:]中的维度是权重的x位置,权重的y位置,第n个输入到相应的卷积层(来自上一层,请注意,如果您尝试获得第一个卷积层的权重,则此数字为 1,因为只有一个输入被驱动到第一个卷积层)和第 k 个过滤器或内核分别对应的层。因此,layer.get_weights()[0] 返回的数组形状可以解释为只有一个输入被驱动到该层,并生成了 96 个 5x5 大小的过滤器。如果您想访问其中一个过滤器,您可以输入,比如说第 6 个过滤器 打印(layer.get_weights()[0][:,:,:,6].squeeze())。 但是,如果您需要第二个 conv 层的过滤器(请参阅下面附加的模型图像链接),那么请注意,对于 32 个输入图像或矩阵中的每一个,您将拥有 64 个过滤器。如果您想获得其中任何一个的权重,例如为第 8 个输入图像生成的第 4 个过滤器的权重,那么您应该输入 打印(layer.get_weights()[0][:,:,8,4].squeeze())。 enter image description here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-28
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2019-06-18
      • 1970-01-01
      相关资源
      最近更新 更多