【问题标题】:Why would you add a variable to the _trainable_weights list of a layer?为什么要将变量添加到层的 _trainable_weights 列表中?
【发布时间】:2019-10-23 21:06:33
【问题描述】:

在这个笔记本https://nbviewer.jupyter.org/github/krasserm/bayesian-machine-learning/blob/master/bayesian_neural_networks.ipynb中,作者定义了函数

def mixture_prior_params(sigma_1, sigma_2, pi):
    params = K.variable([sigma_1, sigma_2, pi], name='mixture_prior_params')
    sigma = np.sqrt(pi * sigma_1 ** 2 + (1 - pi) * sigma_2 ** 2)
    return params, sigma

创建一个变量并返回一个元组。然后调用这个方法

prior_params, prior_sigma = mixture_prior_params(sigma_1=1.0, sigma_2=0.1, pi=0.2)

然后,在自定义层类DenseVariational中,在build方法中,将prior_params全局变量添加到私有列表_trainable_weights

def build(self, input_shape):
    self._trainable_weights.append(prior_params)
    ...

为什么需要或想要这样做?例如,如果我尝试打印自定义层或由该自定义层制成的模型的可训练参数

# Create the model with DenseVariational layers
model = Model(x_in, x_out)
print("model.trainable_weights =", model.trainable_weights)

我可以看到每个DenseVariational 层都包含一个mixture_prior_params 可训练参数。为什么要在层外声明mixture_prior_params,更具体地说,sigma_1sigma_2pi,如果它们是层的可训练参数?

【问题讨论】:

    标签: keras keras-layer


    【解决方案1】:

    在查看了这个问题 Can I share weights between keras layers but have other parameters differ? 及其答案 (https://stackoverflow.com/a/45258859/3924118) 并在模型训练后打印了模型的可训练变量的值之后,这似乎是一种共享变量的方式跨不同层,假设该变量的值在模型训练后似乎跨层相等。

    我创建了一个简单的示例(使用 TensorFlow 2.0.0 和 Keras 2.3.1)来说明这一点

    import numpy as np
    from keras import activations, initializers
    from keras import backend as K
    from keras import optimizers
    from keras.layers import Input
    from keras.layers import Layer
    from keras.models import Model
    
    shared_variable = K.variable([0.3], name='my_shared_variable')
    
    
    class MyLayer(Layer):
        def __init__(self, output_dim, activation=None, **kwargs):
            self.output_dim = output_dim
            self.activation = activations.get(activation)
            super().__init__(**kwargs)
    
        def build(self, input_shape):
            self._trainable_weights.append(shared_variable)
            self.my_weight = self.add_weight(name='my_weight',
                                             shape=(input_shape[1], self.output_dim),
                                             initializer=initializers.normal(),
                                             trainable=True)
            super().build(input_shape)
    
        def call(self, x):
            return self.activation(K.dot(x, self.my_weight * shared_variable))
    
        def compute_output_shape(self, input_shape):
            return input_shape[0], self.output_dim
    
    
    if __name__ == "__main__":
        # Define the architecture of the model.
        x_in = Input(shape=(1,))
        h1 = MyLayer(20, activation='relu')(x_in)
        h2 = MyLayer(20, activation='relu')(h1)
        x_out = MyLayer(1)(h2)
    
        model = Model(x_in, x_out)
        print("h1.trainable_weights (before training) =", model.layers[1].trainable_weights[0])
        print("h2.trainable_weights (before training) =", model.layers[2].trainable_weights[0])
    
        # Prepare the model for training.
        model.compile(loss="mse", optimizer=optimizers.Adam(lr=0.03))
    
        # Generate dataset.
        X = np.linspace(-0.5, 0.5, 100).reshape(-1, 1)
        y = 10 * np.sin(2 * np.pi * X)
    
        # Train the model.
        model.fit(X, y, batch_size=1, epochs=100, verbose=0)
    
        print("h1.trainable_weights (after training) =", model.layers[1].trainable_weights[0])
        print("h2.trainable_weights (after training) =", model.layers[2].trainable_weights[0])
    

    输出是

    h1.trainable_weights (before training) = <tf.Variable 'my_shared_variable:0' shape=(1,) dtype=float32, numpy=array([0.3], dtype=float32)>
    h2.trainable_weights (before training) = <tf.Variable 'my_shared_variable:0' shape=(1,) dtype=float32, numpy=array([0.3], dtype=float32)>
    h1.trainable_weights (after training) = <tf.Variable 'my_shared_variable:0' shape=(1,) dtype=float32, numpy=array([0.7049409], dtype=float32)>
    h2.trainable_weights (after training) = <tf.Variable 'my_shared_variable:0' shape=(1,) dtype=float32, numpy=array([0.7049409], dtype=float32)>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2021-09-11
      相关资源
      最近更新 更多