Keras屏蔽是否影响重量更新和损失计算?

rryofs0p  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(133)

我正在处理时间序列,并了解到keras.layers.Maskingkeras.layers.Embedding对于在网络中创建mask值非常有用,该值指示要“跳过”的时间步。mask值在整个网络中传播,以供任何支持它的层使用。
Keras documentation没有指定mask值的任何进一步影响。我的期望是掩码将应用于模型训练和评估中的所有函数,但我没有看到任何支持这一点的证据。

  1. mask值是否会影响反向传播?
  2. mask值是否影响损失函数或指标?
    1.使用model.compile()中的sample_weight参数来告诉Keras“忽略”损失函数中的屏蔽时间步是明智还是愚蠢?
3qpi33ja

3qpi33ja1#

我做了一些实验来回答这些问题。
下面是我的示例代码:

import tensorflow as tf
import tensorflow.keras as keras
import numpy as np
# Fix the random seed for repeatable results
np.random.seed(5)
tf.random.set_seed(5)

x = np.array([[[3, 0], [1, 4], [3, 2], [4, 0], [4, 5]],
              [[1, 2], [3, 1], [1, 3], [5, 1], [3, 5]]], dtype='float64')

# Choose some values to be masked out
mask = np.array([[False, False,  True,  True,  True],
                 [ True,  True, False, False,  True]]) # True:keep.   False:ignore

samples, timesteps, features_in = x.shape
features_out = 1

y_true = np.random.rand(samples, timesteps, features_out)
# y_true[~mask] = 1e6 # TEST MODIFICATION

# Apply the mask to x
mask_value = 0 # Set to any value
x[~mask] = [mask_value] * features_in

input_tensor = keras.Input(shape=(timesteps, features_in))
this_layer = input_tensor
this_layer = keras.layers.Masking(mask_value=mask_value)(this_layer)
this_layer = keras.layers.Dense(10)(this_layer)
this_layer = keras.layers.Dense(features_out)(this_layer)

model = keras.Model(input_tensor, this_layer)
model.compile(loss='mae', optimizer='adam')

model.fit(x=x, y=y_true, epochs=100, verbose=0)

y_pred = model.predict(x)
print("y_pred = ")
print(y_pred)

print("model weights = ")
print(model.get_weights()[1])

print(f"{'model.evaluate':>14s} = {model.evaluate(x, y_true, verbose=0):.5f}")

# See if the loss computed by model.evaluate() is equal to the masked loss
error = y_true - y_pred
masked_loss = np.abs(error[mask]).mean()
unmasked_loss = np.abs(error).mean()
print(f"{'masked loss':>14s} = {masked_loss:.5f}")
print(f"{'unmasked loss':>14s} = {unmasked_loss:.5f}")

哪些输出

y_pred = 
[[[-0.28896046]
  [-0.28896046]
  [ 0.1546848 ]
  [-1.1596009 ]
  [ 1.5819632 ]]

 [[ 0.59000516]
  [-0.39362794]
  [-0.28896046]
  [-0.28896046]
  [ 1.7996234 ]]]
model weights = 
[-0.06686568  0.06484845 -0.06918766  0.06470951  0.06396528  0.06470013
  0.06247645 -0.06492618 -0.06262784 -0.06445726]
model.evaluate = 0.60170
   masked loss = 1.00283
 unmasked loss = 0.90808

掩模和损耗计算

令人惊讶的是,“mae”(平均绝对误差)损失计算并没有从计算中排除屏蔽的时间步骤。相反,它假设这些时间步骤的损失为零--完美的预测。因此,每个屏蔽的时间步骤实际上都减少了计算的损失!
更详细地解释:上面的示例代码输入x有10个时间步。其中4个被掩码删除,因此剩下6个有效的时间步。“平均绝对误差”损失计算将6个有效时间步的损失相加,然后除以 10 而不是除以 6。在我看来这是一个bug。

输出值被屏蔽

屏蔽时间步长的输出值不会影响模型定型或评估(这是应该的)。
这可以通过设置以下内容轻松测试:
y_true[~mask] = 1e6
模型权重、预测和损失保持完全相同。

输入值被屏蔽

屏蔽时间步长的输入值不会影响模型定型或评估(这是应该的)。
类似地,我可以将mask_value从0更改为任何其他数字,而得到的模型权重、预测和损失保持完全相同。

总结:

Q1:实际上是的-掩码影响损失函数,该函数通过反向传播用于更新权重。
Q2:是的,但口罩会以一种意想不到的方式影响损失。
Q3:一开始很愚蠢--面具应该已经被应用到损失计算中了。但是,也许sample_weights对纠正意外的损失计算方法是有价值的...
请注意,我使用的是Tensorflow 2.7.0。

相关问题