第一层的Keras权重不变

时间:2018-07-11 14:40:16

标签: python tensorflow keras deep-learning

我对Keras还是很陌生,我正在编写一个自定义层,该层实现高斯函数[exp(-(w*x-mean)^2/sigma^2),其中W,均值,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的第一层(只是想确保它运行时不会产生错误,不关心准确性)并训练模型后,损失似乎在经过大约经过4个时期,训练后只有“均值”和“西格玛”的数量发生了变化,而“ W”的数量保持不变。但是,如果将其作为第二层,则不会发生这种情况。

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

是不是在更新Keras的第一层权重(更确切地说是第一个参数),还是我丢失了某些东西?我可以强迫它更新吗?
谢谢!

1 个答案:

答案 0 :(得分: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进行注册,并且将得到正确的培训。您应该对图层中的所有可训练参数执行此操作。