在 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))
我需要帮助将自定义权重设置为用于 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))