【问题标题】:Keras multiply parallel layers' outputs with constrained weigthsKeras 将并行层的输出与约束权重相乘
【发布时间】:2020-05-31 22:08:35
【问题描述】:

我有 3 个并行 MLP,想在 Keras 中获取以下内容:

Out = W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3

其中 Out_MLPs 是每个 MLP 的输出层,维度为 (10,),W1、W2 和 W3 是三个可训练的权重(浮点数),它们满足以下条件:

W1 + W2 + W3 = 1

使用 Keras 函数式 API 实现此功能的最佳方式是什么?如果我们有 N 个并行层呢?

【问题讨论】:

    标签: keras keras-layer tf.keras


    【解决方案1】:

    您需要对一组可学习的权重应用 softmax,以确保它们的总和为 1。

    我们在自定义层中初始化我们的可学习权重。该层接收我们的 MLP 的输出,并按照我们的逻辑 W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3 组合它们。输出将是一个形状为 (10,) 的张量。

    class W_ADD(Layer):
    
        def __init__(self, n_output):
            super(W_ADD, self).__init__()
            self.W = tf.Variable(initial_value=tf.random.uniform(shape=[1,1,n_output], minval=0, maxval=1),
                trainable=True) # (1,1,n_inputs)
    
        def call(self, inputs):
    
            # inputs is a list of tensor of shape [(n_batch, n_feat), ..., (n_batch, n_feat)]
            # expand last dim of each input passed [(n_batch, n_feat, 1), ..., (n_batch, n_feat, 1)]
            inputs = [tf.expand_dims(i, -1) for i in inputs]
            inputs = Concatenate(axis=-1)(inputs) # (n_batch, n_feat, n_inputs)
            weights = tf.nn.softmax(self.W, axis=-1) # (1,1,n_inputs)
            # weights sum up to one on last dim
    
            return tf.reduce_sum(weights*inputs, axis=-1) # (n_batch, n_feat)
    

    在这个虚拟示例中,我创建了一个具有 3 个并行 MLP 的网络

    inp1 = Input((100))
    inp2 = Input((100))
    inp3 = Input((100))
    x1 = Dense(32, activation='relu')(inp1)
    x2 = Dense(32, activation='relu')(inp2)
    x3 = Dense(32, activation='relu')(inp3)
    x1 = Dense(10, activation='linear')(x1)
    x2 = Dense(10, activation='linear')(x2)
    x3 = Dense(10, activation='linear')(x3)
    mlp_outputs = [x1,x2,x3]
    out = W_ADD(n_output=len(mlp_outputs))(mlp_outputs)
    
    m = Model([inp1,inp2,inp3], out)
    m.compile('adam','mse')
    
    X1 = np.random.uniform(0,1, (1000,100))
    X2 = np.random.uniform(0,1, (1000,100))
    X3 = np.random.uniform(0,1, (1000,100))
    y = np.random.uniform(0,1, (1000,10))
    
    m.fit([X1,X2,X3], y, epochs=10)
    

    如您所见,这在 N 个并行层的情况下很容易推广

    【讨论】:

    • softmax 是您拥有的更好、更清洁的解决方案。不,输出约束不是问题……想想每个多类 NN 以及与结果相关的相对不确定性程度。你也可以自己测试 tf.nn.softmax([0.3,0.9,0.8], axis=-1)。告诉我
    • 谢谢,我剩下的问题是:“是否可以避免串联?”
    • 您可以播放和调整提供的代码。我使用串联是因为它可以轻松管理维度。我认为使用它没有任何问题......不要忘记接受它作为答案;-)
    • 我有 TF 2.2 和 tf.keras 我没问题...colab.research.google.com/drive/…
    • 太棒了!!!按照我们的示例,这些是原始权重 m.get_weights()[-1]。为了让它们在 [0-1] 范围内,就像在层计算中一样,softmax 完成工作 tf.nn.softmax(m.get_weights()[-1])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 2018-08-03
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多