在 Keras 模型中设置权重

Setting weights in Keras model

我需要帮助将自定义权重设置为用于 2D 卷积的微型自定义 Keras 模型。我有一个看起来像这样的输入:

X = [[[3, 2, -4],
      [0, 5, 4],
      [2, -1, -7],
      [-7, 0, 1]],
     [[-8, 9, 1],
      [-3, 6, 0],
      [0, -4, 2],
      [5, 1, 1]]]

因此,可以将其想象成只有两个通道的 4x3 图像。我的内核看起来像这样:

kernel = [[[2, 1],
           [0, -1],
           [0, -1]],
          [[1, 2],
           [2, -1],
           [2, -2]]]

所以,一个二维的 3x2 内核。手动执行步幅为 1 且无填充的 2D 卷积,得到:

[[10, 14],
 [27, 16]]

不幸的是,下面的 Keras 代码:

model = Sequential()
conv2d = Conv2D(filters=1, kernel_size=(3,2), strides=1, input_shape=(2,4,3), use_bias=False)
model.add(conv2d)
layer = model.layers[0]
layer.set_weights([np.array(kernel).reshape(3, 2, 2, 1)])
print(model.predict(np.array(X).reshape((1,) + np.shape(X))))

输出:

[[19, -6],
 [-39, 16]]

我无法弄清楚 Keras 如何为卷积组织内核。到目前为止,看起来非常违反直觉,但我可能遗漏了一些东西。

我正在使用 Keras 2.0.9 和 Tensorflow 1.4.0 作为后端。

keras 中的内核遵循以下形状:(height, width, input_channels, output_channels)——即使您使用的是 channels_first

你认为它使用的形状是对的 (3,2,2,1)

但是您的手动计算正在考虑倒置的形状。在您的手动计算中,您使用的是 (input_channels, height, width)

当您 reshape 内核时,您没有正确地重新排序这些维度。只是重塑不等同于 "transposing" 数组。 Reshape 只是对数据进行重新分组,而无需进行任何类型的重新排序。

要在 keras 中获得正确的结果,您需要正确交换轴:

#start as (input_channels, height, width) = (2,3,2)    
kernel = np.array([[[2, 1],
       [0, -1],
       [0, -1]],
      [[1, 2],
       [2, -1],
       [2, -2]]])

#change to (height, input_channels, width) = (3,2,2)   
kernel = kernel.swapaxes(0,1)

#change to (height, width, input_channels) = (3,2,2)
kernel = kernel.swapaxes(1,2)

#add output_channels
kernel = kernel.reshape((3,2,2,1))