当前位置: 首页 > 面试题库 >

Keras嵌入层中的mask_zero如何工作?

董谦
2023-03-14
问题内容

我认为mask_zero=True当输入值为0时将输出0,因此以下各层可能会跳过计算或其他操作。

如何mask_zero运作?

例:

data_in = np.array([
  [1, 2, 0, 0]
])
data_in.shape
>>> (1, 4)

# model
x = Input(shape=(4,))
e = Embedding(5, 5, mask_zero=True)(x)

m = Model(inputs=x, outputs=e)
p = m.predict(data_in)
print(p.shape)
print(p)

实际输出为:(数字是随机的)

(1, 4, 5)
[[[ 0.02499047  0.04617121  0.01586803  0.0338897   0.009652  ]
  [ 0.04782704 -0.04035913 -0.0341589   0.03020919 -0.01157228]
  [ 0.00451764 -0.01433611  0.02606953  0.00328832  0.02650392]
  [ 0.00451764 -0.01433611  0.02606953  0.00328832  0.02650392]]]

但是,我认为输出将是:

[[[ 0.02499047  0.04617121  0.01586803  0.0338897   0.009652  ]
  [ 0.04782704 -0.04035913 -0.0341589   0.03020919 -0.01157228]
  [ 0 0 0 0 0]
  [ 0 0 0 0 0]]]

问题答案:

实际上,设置mask_zero=True嵌入层不会导致返回零向量。而是,嵌入层的行为不会改变,它将返回索引为零的嵌入向量。您可以通过检查Embedding层权重(即在您提到的示例中为m.layers[0].get_weights())来确认这一点。取而代之的是,它将影响诸如RNN层之类的后续层的行为。

如果检查Embedding层的源代码,则会看到一个称为的方法compute_mask

def compute_mask(self, inputs, mask=None):
    if not self.mask_zero:
        return None
    output_mask = K.not_equal(inputs, 0)
    return output_mask

此输出掩码将作为mask参数传递给支持掩码的以下层。这已经在__call__基本层的方法中实现了Layer

# Handle mask propagation.
previous_mask = _collect_previous_mask(inputs)
user_kwargs = copy.copy(kwargs)
if not is_all_none(previous_mask):
    # The previous layer generated a mask.
    if has_arg(self.call, 'mask'):
        if 'mask' not in kwargs:
            # If mask is explicitly passed to __call__,
            # we should override the default mask.
            kwargs['mask'] = previous_mask

这使得以下层可以忽略(即,在其计算中不考虑)此输入步骤。这是一个最小的示例:

data_in = np.array([
  [1, 0, 2, 0]
])

x = Input(shape=(4,))
e = Embedding(5, 5, mask_zero=True)(x)
rnn = LSTM(3, return_sequences=True)(e)

m = Model(inputs=x, outputs=rnn)
m.predict(data_in)

array([[[-0.00084503, -0.00413611,  0.00049972],
        [-0.00084503, -0.00413611,  0.00049972],
        [-0.00144554, -0.00115775, -0.00293898],
        [-0.00144554, -0.00115775, -0.00293898]]], dtype=float32)

如您所见,第二和第四时间步的LSTM层的输出分别与第一和第三时间步的输出相同。这意味着这些时间步骤已被掩盖。

更新:
在计算损耗时,还将考虑使用掩码,因为使用以下功能对损耗函数进行了内部增强以支持掩码weighted_masked_objective

def weighted_masked_objective(fn):
    """Adds support for masking and sample-weighting to an objective function.
    It transforms an objective function `fn(y_true, y_pred)`
    into a sample-weighted, cost-masked objective function
    `fn(y_true, y_pred, weights, mask)`.
    # Arguments
        fn: The objective function to wrap,
            with signature `fn(y_true, y_pred)`.
    # Returns
        A function with signature `fn(y_true, y_pred, weights, mask)`.
    """

编译模型时:

weighted_losses = [weighted_masked_objective(fn) for fn in loss_functions]

您可以使用以下示例对此进行验证:

data_in = np.array([[1, 2, 0, 0]])
data_out = np.arange(12).reshape(1,4,3)

x = Input(shape=(4,))
e = Embedding(5, 5, mask_zero=True)(x)
d = Dense(3)(e)

m = Model(inputs=x, outputs=d)
m.compile(loss='mse', optimizer='adam')
preds = m.predict(data_in)
loss = m.evaluate(data_in, data_out, verbose=0)
print(preds)
print('Computed Loss:', loss)

[[[ 0.009682    0.02505393 -0.00632722]
  [ 0.01756451  0.05928303  0.0153951 ]
  [-0.00146054 -0.02064196 -0.04356086]
  [-0.00146054 -0.02064196 -0.04356086]]]
Computed Loss: 9.041069030761719

# verify that only the first two outputs 
# have been considered in the computation of loss
print(np.square(preds[0,0:2] - data_out[0,0:2]).mean())

9.041070036475277


 类似资料:
  • 我正在使用TensorFlow后端。 我正在按顺序应用卷积、最大池、展平和密集层。卷积需要3D输入(高度、宽度、color\u channels\u深度)。 在卷积之后,它变为(高度、宽度、过滤器的数量)。 在应用最大池化高度和宽度变化之后。但是,在应用展平层之后,到底会发生什么?例如,如果展平之前的输入是(24, 24, 32),那么它是如何展平的? 对于每个过滤器号的高度、重量,它是像(24*

  • 问题内容: 我目前正在使用Keras模型,该模型具有一个嵌入层作为第一层。为了可视化单词之间的关系和相似性,我需要一个函数,该函数返回词汇表中每个元素的单词和向量的映射(例如’love’-[0.21、0.56,…,0.65、0.10] )。 有什么办法吗? 问题答案: 您可以使用嵌入层的方法来获得词嵌入(即,本质上,嵌入层的权重就是嵌入向量):

  • 嘿,伙计们,我已经建立了一个有效的LSTM模型,现在我正在尝试(不成功)添加一个嵌入层作为第一层。 这个解决方案对我不起作用。在提问之前,我还阅读了这些问题:Keras输入解释:输入形状、单位、批次大小、尺寸等,了解Keras LSTM和Keras示例。 我的输入是一种由27个字母组成的语言的字符的单键编码(1和0)。我选择将每个单词表示为10个字符的序列。每个单词的输入大小是(10,27),我有

  • layer_from_config layer_from_config(config, custom_objects={}) 从配置生成Keras层对象 参数 config:形如{'class_name':str, 'config':dict}的字典 custom_objects: 字典,用以将定制的非Keras对象之类名/函数名映射为类/函数对象 返回值 层对象,包含Model,Sequent

  • 在模型中添加LSTM层之前,我不确定是否需要添加密集输入层。例如,使用以下模型: LSTM层是否为输入层,密集层是否为输出层(即无隐藏层)?或者Keras是否创建了一个输入层,这意味着LSTM层将是一个隐藏层?

  • 我想创建一个Keras模型,包括一个嵌入层,然后是两个具有dropout 0.5的LSTM,最后是一个具有softmax激活的密集层。 第一个LSTM应该将顺序输出传播到第二层,而在第二层中,我只想在处理完整个序列后获得LSTM的隐藏状态。 我尝试了以下方法: 但是,我遇到以下错误: 显然,LSTM并没有返回我所期望的形状输出。如何修复此问题?