有一种方法可以手动更改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 )直接将权重传递给班级。
有人有建议吗?
也许可以手动加载并更改该层关联变量的值?我发现此解决方案非常糟糕,但可以正常工作。
谢谢。
答案 0 :(得分:1)
假设您有一个像这样的基本卷积神经网络:
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)])
答案 1 :(得分:0)
感谢尼古拉斯的建议。
我没有使用Keras进行网络建模,实际上我需要直接使用Tensorflow,尤其是在tf-slim库中。
您提出的解决方案可以替代权重,但要克服的问题是我还需要更改这些权重用于计算卷积运算的方式。更具体地说,我想将一个权重向量传递给Conv层,该向量以某种方式代表以前的权重矩阵,因此在进行卷积之前,我需要重构一个矩阵并将其传递给该层。
有什么建议可以做到这一点?
谢谢。