【问题标题】:Restricting the output values of layers in Keras限制 Keras 中层的输出值
【发布时间】:2017-06-14 20:00:42
【问题描述】:

我在下面的代码中定义了我的 MLP。我想提取layer_2的值。

def gater(self):
    dim_inputs_data = Input(shape=(self.train_dim[1],))
    dim_svm_yhat = Input(shape=(3,))
    layer_1 = Dense(20,
                    activation='sigmoid')(dim_inputs_data)
    layer_2 = Dense(3, name='layer_op_2',
                    activation='sigmoid', use_bias=False)(layer_1)
    layer_3 = Dot(1)([layer_2, dim_svm_yhat])
    out_layer = Dense(1, activation='tanh')(layer_3)
    model = Model(input=[dim_inputs_data, dim_svm_yhat], output=out_layer)
    adam = optimizers.Adam(lr=0.01)
    model.compile(loss='mse', optimizer=adam, metrics=['accuracy'])
    return model

假设layer_2的输出为矩阵形式

0.1 0.7 0.8
0.1 0.8 0.2
0.1 0.5 0.5
....

我希望将下面的内容送入 layer_3 而不是上面

0 0 1
0 1 0
0 1 0

基本上,我希望将第一个最大值转换为 1,将其他最大值转换为 0。 这在 keras 中如何实现?

【问题讨论】:

    标签: keras keras-layer


    【解决方案1】:

    谁决定输出值的范围?

    神经网络中任何层的输出范围由用于该层的激活函数决定。例如,如果您使用tanh 作为激活函数,您的输出值将被限制为[-1,1](并且这些值是连续的,请检查值如何从[-inf,+inf](x 轴上的输入)映射到@ 987654325@(y轴输出)here,理解这一步很重要)

    您应该做的是添加一个自定义激活函数,将您的值限制为阶跃函数,即 [-inf, +inf] 为 1 或 0,并将其应用于该层。

    我怎么知道要使用哪个函数?

    您需要创建满足您所有需求的y=some_function(输入到输出的映射)并将其转换为 Python 代码,就像这样:

    from keras import backend as K
    
    def binaryActivationFromTanh(x, threshold) :
    
        # convert [-inf,+inf] to [-1, 1]
        # you can skip this step if your threshold is actually within [-inf, +inf]
    
        activated_x = K.tanh(x)
    
        binary_activated_x = activated_x > threshold
    
        # cast the boolean array to float or int as necessary
        # you shall also cast it to Keras default
        # binary_activated_x = K.cast_to_floatx(binary_activated_x)
    
        return binary_activated_x
    

    制作完你的自定义激活函数后,就可以像这样使用了

    x = Input(shape=(1000,))
    y = Dense(10, activation=binaryActivationFromTanh)(x)
    

    现在测试这些值,看看您是否获得了预期的值。您现在可以将这部分放入更大的神经网络中。

    强烈不鼓励添加新层以增加对输出的限制,除非它仅用于激活(例如 keras.layers.LeakyReLU)。

    【讨论】:

    • 嗨,我遇到了类似的问题。我的想法是,即使使用自定义激活,也不能保证每个输出行中的 3 个中只有一个“1”。在这种情况下,最好有 3 个输出节点而不是 Dense(3) 输出。你有什么意见?谢谢
    • @RaymondM 1 指的是什么?我需要更多的输入来理解你的问题。也许你可以问一个新的?
    • 您好,我正在使用您建议的功能并进行了很好的修改以适合我的。但是,当我尝试进一步修改以 0 替换小于阈值 = 0.5 的值时,binary_activated_x = K.cast_to_floatx(binary_activated_x) 不起作用。我该如何改变?
    【解决方案2】:

    在两者之间使用 Numpy。下面是一个随机矩阵的例子:

      a = np.random.random((5, 5)) # simulate random value output of your layer
      result = (a == a.max(axis=1)[:,None]).astype(int)
    

    另请参阅此线程:Numpy: change max in each row to 1, all other numbers to 0

    然后将result 作为输入输入到下一层。

    为了包装 Numpy 计算,您可以使用 Lambda 层。在此处查看示例:https://keras.io/layers/core/#lambda

    编辑:

    建议不起作用。我保留答案只是为了保留相关的 cmets。

    【讨论】:

    • 你能指出将 numpy 与 keras 结合使用的示例吗?据我了解,仅支持 keras 后端操作。
    • 嗯。如果您查看示例,则每件事都取决于后端,例如 K.something 或 K.mean 您不能包装 numpy。
    • 您不能在 Lambda 层中使用 numpy 操作,所有操作都必须是符号的。
    猜你喜欢
    • 2020-09-09
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 2020-07-20
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多