python - 手动更改 Keras 卷积层的权重

标签 python tensorflow keras convolution

有一种方法可以手动更改 tf.layers.Conv2d ( https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/layers/Conv2D ) 的权重吗?因为此类仅接受输入、要使用的内核数量等...并且权重由 Tensorflow 自动存储和计算,但我想办法(如 tf.nn.conv2d - https://www.tensorflow.org/api_docs/python/tf/nn/conv2d )来直接将权重传递给类。

有人有什么建议吗?

也许可以手动加载和更改该层关联变量的值?我发现这个解决方案非常糟糕,但它可以工作。

谢谢。

最佳答案

假设您有一个像这样的基本卷积神经网络:

import tensorflow as tf
import numpy as np

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(filters=16, kernel_size=(3, 3), 
                           strides=(1, 1), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), 
                           strides=(1, 1), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dropout(5e-1),
    tf.keras.layers.Dense(10, activation='softmax')
])

默认情况下,所有卷积层的名称都是'conv2d...'

list(map(lambda x: x.name, model.layers))
['conv2d_19',
 'max_pooling2d_19',
 'conv2d_20',
 'max_pooling2d_20',
 'flatten_8',
 'dense_16',
 'dropout_8',
 'dense_17']

使用它,您可以遍历所有卷积层。

for layer in filter(lambda x: 'conv2d' in x.name, model.layers):
    print(layer)
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x00000295BE4EB048>
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x00000295C1617448>

对于所有这些层,您可以获得权重形状和偏置形状。

for layer in filter(lambda x: 'conv' in x.name, model.layers):
    weights_shape, bias_shape = map(lambda x: x.shape, layer.get_weights())

然后您可以将 layer.set_weights() 与您想要的值一起使用,因为您知道正确的形状。比方说 0.12345。让我们使用 np.full 来做到这一点,它用您想要的任何值填充指定形状的数组。

for layer in filter(lambda x: 'conv2d' in x.name, model.layers):
    weights_shape, bias_shape = map(lambda x: x.shape, layer.get_weights())
    layer.set_weights([np.full(weights_shape, 0.12345),
                       np.full(bias_shape,    0.12345)])

现在的权重:

[array([[[[0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345],
          [0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345],
          [0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345],
          ...,
          [0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345],
          [0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345],
          [0.12345, 0.12345, 0.12345, ..., 0.12345, 0.12345, 0.12345]]]],
       dtype=float32),
 array([0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345,
        0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345,
        0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345,
        0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345, 0.12345,
        0.12345, 0.12345, 0.12345, 0.12345], dtype=float32)]

完全复制/粘贴示例:

import tensorflow as tf
import numpy as np

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(filters=16, kernel_size=(3, 3), 
                           strides=(1, 1), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), 
                           strides=(1, 1), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dropout(5e-1),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.build(input_shape=(None, 28, 28, 1))

for layer in filter(lambda x: 'conv2d' in x.name, model.layers):
    weights_shape, bias_shape = map(lambda x: x.shape, layer.get_weights())
    layer.set_weights([np.full(weights_shape, 0.12345),
                       np.full(bias_shape,    0.12345)])

关于python - 手动更改 Keras 卷积层的权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64612657/

相关文章:

python - TensorFlow 问题 google colab ; tensorflow._api.v1.compat.v 2' has no attribute ' __internal__

python-3.x - 连接模型时,Keras 出现无梯度错误

tensorflow - 有没有办法使用 Tensorflow(使用 Keras)或 PyTorch 删除 NN 层之间的 1-2(或更多)特定神经元连接?

python - WTForms 在下拉列表中显示外键字段的名称

Python生成具有随机步长的范围数组

python - Pandas 系列中用于减法或除法的 sum 或 prod 的替代方法

python - ValueError : Input 0 of layer conv2d is incompatible with the layer: : expected min_ndim=4, 发现 ndim=3。收到完整形状 : (2240, 70, 3)

python - Pandas 猜测分隔符 sep=None

Python 无法将 tensorflow 导入 Mac OS X 10.8

tensorflow - BERT - 池化输出与序列输出的第一个向量不同