首页 文章

第一层的Keras重量没有变化

提问于
浏览
2

我在写一个实现高斯函数的自定义层[ exp(-(w*x-mean)^2/sigma^2) ,其中W,mean,sigma都是随机生成的] .
以下是自定义图层的代码:

class Gaussian(Layer):
    def __init__(self,**kwargs):
        super(Gaussian, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create trainable weights for this layer.
        self.W_init = np.random.rand(1,input_shape[1])
        self.W = K.variable(self.W_init, name="W")

        # Create trainable means for this layer.
        self.mean_init = np.random.rand(1,input_shape[1])
        self.mean = K.variable(self.mean_init, name="mean")

        # Create trainable sigmas for this layer.
        self.sigma_init = np.random.rand(1,input_shape[1])
        self.sigma = K.variable(self.sigma_init, name="sigma")

        self.trainable_weights = [self.mean, self.sigma]
        super(Gaussian, self).build(input_shape)  # Be sure to call this somewhere!

    def call(self, x):
        result = tf.multiply(x, self.W)
        result = tf.subtract(x, self.mean)
        result = tf.multiply(tf.square(result),-1)
        result = tf.divide(result, tf.square(self.sigma))
        return result

    def compute_output_shape(self, input_shape):
        return input_shape

将它作为第一层放在Keras mnist tutorial之后(只是想确保它运行而不会产生错误,如果我把它作为第二层,那就不会发生 . )

我在没有自定义层的情况下再次运行了Keras mnist教程,发现第一层的权重也没有改变 .

是不是更新第一层的权重(更具体地说是第一个参数)是Keras的事情还是我错过了什么?我可以强制更新吗?
谢谢!

1 回答

  • 2

    你没有正确地实现你的层,Keras没有意识到你的权重,这意味着他们没有受到梯度下降的训练 . 看看this示例:

    from keras import backend as K
    from keras.engine.topology import Layer
    import numpy as np
    
    class MyLayer(Layer):
    
        def __init__(self, output_dim, **kwargs):
            self.output_dim = output_dim
            super(MyLayer, self).__init__(**kwargs)
    
        def build(self, input_shape):
            # Create a trainable weight variable for this layer.
            self.kernel = self.add_weight(name='kernel', 
                                          shape=(input_shape[1], self.output_dim),
                                          initializer='uniform',
                                          trainable=True)
            super(MyLayer, self).build(input_shape)  # Be sure to call this at the end
    
        def call(self, x):
            return K.dot(x, self.kernel)
    
        def compute_output_shape(self, input_shape):
            return (input_shape[0], self.output_dim)
    

    在这里你必须使用 add_weight 来获得一个可训练的重量,而不是像你现在一样使用 K.variable . 这样你的重量将在Keras注册,并且他们将被正确训练 . 您应该对图层中的所有可训练参数执行此操作 .

相关问题