2

我正在构建一个具有多个输入的 LSTM 模型(数字由 给出n_inputs)。我缩放输入(0, 1)并将所有输入替换NaN-1. 现在我希望模型忽略这些NaN值,因此我使用如下掩码:

model= Sequential()
model.add(Masking(mask_value=-1, input_shape=(window, n_inputs)))
model.add(LSTM(units=n_units), return_sequences=True)
model.add(Dropout(dropout_rate))
model.add(LSTM(units=n_units))
model.add(Dropout(dropout_rate))
model.add(Dense(units=1))

如果任何输入具有价值,我担心Masking模型会完全忽略一个时间步长的数据NaN(我不确定如何检查是否是这种情况)。我想要的是:对于每个时间,只忽略NaN输入,但传递其他有效的输入。我的问题是:是否Masking排除至少一个输入的所有时间步长NaN?如果是这样,我怎样才能让模型只忽略NaN输入?

4

1 回答 1

1

好的,因为我不知道答案并且对此感到好奇,所以我做了一些实验。我首先创建了一个由 3 个时间步长和 3 个特征组成的序列:

inputs = np.ones([1, 3, 3]).astype(np.float32)

我创建了一个简单的网络,在其中打印两个中间层:

inp = tf.keras.layers.Input(shape=(3,3))
mask=tf.keras.layers.Masking(mask_value=-np.inf)(inp)
out=tf.keras.layers.Dense(1,
                           kernel_initializer=tf.keras.initializers.Ones(),
                           use_bias=False)(mask)

model_mask=tf.keras.models.Model(inp,mask)
model=tf.keras.models.Model(inp,out)
print(model_mask(inputs))
print(model(inputs))

我使用了 Dense 层,因为它支持 Masking 并且可以更好地理解正在发生的事情,但是 RNN 的过程是相同的。我还选择将掩码值设置为 -inf 以查看掩码值是否被很好地掩码。Dense 层的权重设置为 1,并且我禁用了偏差,因此该 Dense 层为每个时间步计算输入的总和。

如果我屏蔽时间步的所有输入:

inputs[0, 2, :] = -np.inf

这就是我所拥有的:

tf.Tensor(
[[[ 1.  1.  1.]
  [ 1.  1.  1.]
  [nan nan nan]]], shape=(1, 3, 3), dtype=float32)
tf.Tensor(
[[[ 3.]
  [ 3.]
  [nan]]], shape=(1, 3, 1), dtype=float32)

所以面具被正确地考虑到了。

如果我想屏蔽一个值

inputs[0, 2, 0] = -np.inf

我的输出是:

tf.Tensor(
[[[  1.   1.   1.]
  [  1.   1.   1.]
  [-inf   1.   1.]]], shape=(1, 3, 3), dtype=float32)
tf.Tensor(
[[[  3.]
  [  3.]
  [-inf]]], shape=(1, 3, 1), dtype=float32)

因此,我得出结论,未处理掩蔽。

您应该创建自己的面具。

我尝试了一个小例子,所以我希望这个例子可以用于你的项目。首先,我忘记了 keras 的 Vanilla Masking图层来使用我自己的蒙版。这个想法是创建一个掩码,在掩码值上设置 1,在实际值上设置 0。例如,如果您的值优于 0,则将 Nan 值替换为 -1 并创建custom_mask

inputs = np.array([[[1,2,1],[0.5,2,1],[1,0,3]]],dtype=np.float32)

inputs[:,1,0]=-1
inputs[:,2,2]=-1

custom_mask=inputs.copy()
custom_mask[inputs[:,:,:]>=0]=0
custom_mask[inputs[:,:,:]<0]=1

inputscustom_mask分别:

[[[ 1.  2.  1.]
  [-1.  2.  1.]
  [ 1.  0. -1.]]]
[[[0. 0. 0.]
  [1. 0. 0.]
  [0. 0. 1.]]]

然后,您将您的掩码 mutilply-1E9以将无限值放置在您想要掩码输入的位置。然后将其添加到您的张量中。一个简单的ReLu设置掩码值为 0 :

inp = tf.keras.layers.Input(shape=(3,3))
input_mask=tf.keras.activations.relu(inp-custom_mask*1E9)
out=tf.keras.layers.Dense(1,
                           kernel_initializer=tf.keras.initializers.Ones(),
                           use_bias=False)(input_mask)

model=tf.keras.models.Model(inp,out)
print(model(inputs))

等于 :

tf.Tensor(
[[[4.]
  [3.]
  [1.]]], shape=(1, 3, 1), dtype=float32)
于 2020-11-26T09:36:21.700 回答