【问题标题】:Does Keras ignore labels of masked values?Keras 是否忽略掩码值的标签?
【发布时间】:2020-07-23 17:28:53
【问题描述】:

我正在使用 Keras 实现 LSTM 模型。我将我的序列填充到一定长度,以便以正确的方式将数据集输入到模型中。

目前,我的模型如下:

model = tf.keras.Sequential()
model.add(Masking(mask_value=0., input_shape=(timesteps, features)))
model.add(LSTM(units=100, return_sequences=True, input_shape=(timesteps, features)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

Keras 会在损失函数中自动跳过掩码值的标签吗?

【问题讨论】:

    标签: python machine-learning keras lstm loss-function


    【解决方案1】:

    是的,如果您的模型使用掩码,那么目标函数(即损失函数)将自动增强以支持掩码,因此在计算损失时忽略掩码样本/时间步长。实际上,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)`.
        """
        if fn is None:
            return None
    
        def weighted(y_true, y_pred, weights, mask=None):
            """Wrapper function.
            # Arguments
                y_true: `y_true` argument of `fn`.
                y_pred: `y_pred` argument of `fn`.
                weights: Weights tensor.
                mask: Mask tensor.
            # Returns
                Scalar tensor.
            """
            # score_array has ndim >= 2
            score_array = fn(y_true, y_pred)
            if mask is not None:
                # Cast the mask to floatX to avoid float64 upcasting in Theano
                mask = K.cast(mask, K.floatx())
                # mask should have the same shape as score_array
                score_array *= mask
                #  the loss per batch should be proportional
                #  to the number of unmasked samples.
                score_array /= K.mean(mask) + K.epsilon()
    
            # apply sample weighting
            if weights is not None:
                # reduce score_array to same ndim as weight array
                ndim = K.ndim(score_array)
                weight_ndim = K.ndim(weights)
                score_array = K.mean(score_array,
                                     axis=list(range(weight_ndim, ndim)))
                score_array *= weights
                score_array /= K.mean(K.cast(K.not_equal(weights, 0), K.floatx()))
            return K.mean(score_array)
        return weighted
    

    【讨论】:

    • 谢谢。如果我在我的数据集上使用scikit-learnStandardScaler(可能零向量已缩放为非零值),屏蔽是否可能无效?
    • @pairon 实际上,在均值标准缩放之后,它们可能不再是全零向量;因此,零掩蔽将无效。为防止这种情况,您可以先执行缩放,然后将零填充添加到序列中。
    • 另一个问题。当我在测试集上使用predict时,预测期间是否忽略了测试集的填充向量?
    • @pairon Masking 应该在训练和推理阶段都处于活动状态。所以,是的,它们也会在预测中被忽略。
    • 谢谢。那么,在预测阶段我获得的填充向量的值不等于 0 是否正常?我的输出示例:[9.3943197e-01 9.6559024e-01 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04 6.2561035e-04只有前两个值不引用填充向量。
    猜你喜欢
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 2016-10-11
    • 2021-09-21
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多