在Keras模型中设置权重

时间:2017-11-09 18:47:50

标签: tensorflow keras convolution

我需要帮助将自定义权重设置为用于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内核。手动执行2D卷积,步长为1且无填充,产生:

[[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作为后端。

1 个答案:

答案 0 :(得分:4)

keras中的内核遵循以下形式:(height, width, input_channels, output_channels) - 即使您正在使用channels_first

您认为它使用形状(3,2,2,1)

是正确的

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

当您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))