Keras:连接输入和输出的约束

问题描述 投票:2回答:2

有没有办法可以对序列的预测施加约束?

比如说,如果我的建模如下:

model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(150, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='linear')))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['acc'])

我可以以某种方式捕获model.pred(x) <= x的约束

docs表明我们可以为网络权重添加约束。但是,他们没有提到如何映射输入和输出之间的关系或约束。

python tensorflow constraints keras
2个回答
4
投票

从来没有听说过....但是有很多方法可以使用功能API模型和自定义函数来实现。

下面,有一个可能的答案,但首先,这真的是最好的吗?

如果您正在尝试创建自动编码器,则不应该关心限制输出。否则,你的模型将不会真正学到很多东西。

也许最好的办法就是首先将输入归一化(在-1和+1之间),然后在最后使用tanh激活。

Funtional API model to preserve the input:

inputTensor = Input(n_timesteps_in, n_features)

out = LSTM(150, input_shape=)(inputTensor)
out = RepeatVector(n_timesteps_in)(out) #this line sounds funny in your model...
out = LSTM(150, return_sequences=True)(out)
out = TimeDistributed(Dense(n_features))(out)
out = Activation(chooseOneActivation)(out)

out = Lambda(chooseACustomFunction)([out,inputTensor])

model = Model(inputTensor,out)
model.compile(...)

自定义限制选项

有无限的方法可以做到这一点,这里有一些可能或可能不是你需要的例子。但是你可以自由地开发类似的东西。

以下选项将各个输出限制为各自的输入。但您可能更喜欢使用限制在最大输入范围内的所有输出。

如果是这样,请使用以下内容:maxInput = max(originalInput, axis=1, keepdims=True)

1 - A simple stretched 'tanh':

您可以使用tanh(范围从-1到+1)并将其乘以输入来简单地定义顶部和底部限制。

使用Activation('tanh')图层,以及Lambda图层中的以下自定义函数:

import keras.backend as K

def stretchedTanh(x):

    originalOutput = x[0]
    originalInput = x[1]

    return K.abs(originalInput) * originalOutput

我不完全确定这将是一个健康的选择。如果想要创建一个自动编码器,这个模型很容易找到一个解决方案,输出尽可能接近1的所有tanh激活,而不是真正查看输入。

2 - Modified 'relu'

首先,您可以根据输入简单地输出clip输出,改变relu激活。在上面的模型中使用Activation('relu')(out),在Lambda层使用以下自定义函数:

def modifiedRelu(x):
    negativeOutput = (-1) * x[0] #ranging from -infinite to 0
    originalInput = x[1] 

    #ranging from -infinite to originalInput
    return negativeOutput + originalInput #needs the same shape between input and output

当一切都超过极限并且反向传播无法返回时,这可能有一个缺点。 ('relu'可能会出现问题)。

3 - Half linear, half modified tanh

在这种情况下,您不需要Activation图层,或者您可以将其用作'linear'

import keras.backend as K

def halfTanh(x):

    originalOutput = x[0]
    originalInput = x[1]  #assuming all inputs are positive

    #find the positive outputs and get a tensor with 1's at their positions
    positiveOutputs = K.greater(originalOuptut,0)
    positiveOutputs = K.cast(positiveOutputs,K.floatx())

    #now the 1's are at the negative positions
    negativeOutputs = 1 - positiveOutputs

    tanhOutputs = K.tanh(originalOutput) #function limited to -1 or +1
    tanhOutputs = originalInput * sigmoidOutputs #raises the limit from 1 to originalInput

    #use the conditions above to select between the negative and the positive side
    return positiveOutputs * tanhOutputs + negativeOutputs * originalOutputs

2
投票

Keras提供了一种简单的方法来处理这些微不足道的约束。我们可以写out = Minimum()([out, input_tensor])

完整的例子

import keras
from keras.layers.merge import Maximum, Minimum
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot

n_timesteps_in = 20 
n_features=2
input_tensor = keras.layers.Input(shape = [n_timesteps_in, n_features])

out = keras.layers.LSTM(150)(input_tensor)
out = keras.layers.RepeatVector(n_timesteps_in)(out) 
out = keras.layers.LSTM(150, return_sequences=True)(out)
out = keras.layers.TimeDistributed(keras.layers.Dense(n_features))(out)

out = Minimum()([out, input_tensor])
model = keras.Model(input_tensor, out )
SVG(model_to_dot(model,  show_shapes=True, show_layer_names=True, rankdir='HB').create(prog='dot', format='svg'))

这是模型的网络结构。它显示了输入和输出如何用于计算钳位输出。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.