如何从 Tensorflow 中 layer.layers class 中定义的层 subclass 获取权重?

How to get weights from a layer subclass defined inside a layer.layers class in Tensorflow?

我有下面的代码,在 convProjection class 中,我从 keras 定义了一个 Conv1D 层。 我想定义 Conv1D 的权重。尽管因为它没有被初始化,所以用 self.Projection.get_weights() returns 得到一个空数组的权重。我试图在调用中手动初始化它,但它似乎不起作用。在这种情况下,如何获得 Conv1D 层的权重?我还需要在操作它们之后将它们设置回去。

kernelSize = 32
stride = 16
class convProjections(layers.Layer):
    def __init__(self, kernelSize,stride):
        super(convProjections, self).__init__()
        self.Projection = layers.Conv1D(filters = projection_dim,kernel_size = kernelSize,strides = stride)
    def call(self, inputData):
        Projections = self.Projection(inputData)
        convWeights = self.Projection.get_weights()
        ####I will do some something here with convWeights####

        return Projections

def model
    inputs = layers.Input(shape=input_shape)
    patches = convProjections(kernelSize,stride)(inputs)
    logits = layers.Dense(8,  activation='softmax')(patches )
    model = keras.Model(inputs=inputs, outputs=logits)

最好,我想坚持使用 Model subclassing 来定义我的模型。但对解决方案持开放态度

您必须正确构建 convProjections。您必须在图层的 build(self, inputs_shape) 方法中创建图层权重。然后你必须在call方法中使用这些权重来使用tf.nn.conv1d操作卷积。在 call 的最后,你可以用 self.convWeights.

做任何你想做的事
class convProjections(layers.Layer):

    def __init__(self, projection_dim, kernelSize, stride, use_bias=True):
        super(convProjections, self).__init__()
        self.projection_dim = projection_dim
        self.kernelSize = kernelSize
        self.stride = stride
        self.use_bias = use_bias

    def build(self, input_shape):
        self.convWeights = self.add_weight(
            shape=(self.kernelSize, input_shape[-1], self.projection_dim),
            initializer="random_normal",
            trainable=True,
        )
        if self.use_bias:
            self.convBias = self.add_weight(
                shape=(self.projection_dim,), initializer="random_normal", trainable=True
            )

    def call(self, inputData):

        conv = tf.nn.conv1d(
            inputData, 
            filters=self.convWeights, 
            stride=[1,self.stride,1], 
            padding='SAME',
            data_format='NWC'
        )

        if self.use_bias:
            conv = tf.nn.bias_add(conv, self.convBias)

        ### DO SOMETHING WITH self.convWeights ###

        print(self.convWeights.shape)

        return conv

构建模型:

input_shape = (24,6)
kernelSize = 32
stride = 1
projection_dim = 64

inputs = layers.Input(shape=input_shape)
patches = convProjections(projection_dim,kernelSize,stride)(inputs)
outputs = layers.Dense(8,  activation='softmax')(patches)
model = Model(inputs=inputs, outputs=outputs)