好的,因为我不知道答案并且对此感到好奇,所以我做了一些实验。我首先创建了一个由 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
与inputs
和custom_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)