缺少标签的深度多任务学习

phi*_*510 6 python neural-network deep-learning tensorflow

我有一个深度多任务网络,旨在处理三个独立的分类任务。虽然每个训练样例都有两个分类任务的标签,但只有大约 10% 到 15% 的训练样例具有第三个任务的标签。该网络有多个共享层,每个任务都有一个单独的头,由一个或多个全连接层和一个 softmax/sigmoid 输出层组成。

为了处理第三个任务中缺失的标签,我使用 tf.boolean_mask 来屏蔽每个批次中没有标签的示例,这很好用,除非在一个批次没有带标签的训练示例的极少数情况下;即整个批次中没有任务 3 的标签。在这种情况下,布尔掩码(正确)返回一个空张量,tf.softmax_cross_entropy_with_logits 返回 nan 在训练期间引发错误。

我目前对这个问题的解决方案只是检查一个批次是否没有第三个任务的标签,如果有,则在训练期间跳过该批次。虽然这避免了错误,但我想知道我是否可以编辑计算图来处理这种相对罕见的事件,这样我就不必跳过批处理。

这是第三个任务的输出层和总损失函数的代码片段。这个任务有全连接层,在这个输出层之前有多个共享层。

    # softmax output layer for natural categories
    with tf.variable_scope('Natural_Category_Output'):
        W = tf.get_variable('W', shape = [natural_layer_size, no_natural_categories], 
                            initializer = tf.glorot_uniform_initializer())
        b = tf.get_variable('b', shape = [no_natural_categories],
                            initializer = tf.glorot_uniform_initializer())

        natural_logits = tf.add(tf.matmul(natural_output, W), b, name = 'logits')
        masked_logits = tf.boolean_mask(natural_logits, natural_mask, axis = 0, name = 'masked_logits')

        natural_probabilities = tf.nn.softmax(natural_logits, name = 'probabilities')
        natural_predictions = tf.argmax(natural_logits, axis = 1, name = 'predictions')
        masked_predictions = tf.boolean_mask(natural_predictions, natural_mask, axis = 0, name = 'masked_predictions')

    # loss for the natural categories
    with tf.variable_scope('Natural_Category_Loss_Function'):
        masked_natural_category = tf.boolean_mask(binarized_natural_category, natural_mask, axis = 0, name = 'masked_natural_categories')
        natural_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels = masked_natural_category, 
                                                                                 logits = masked_logits), name = 'cross_entropy_loss')

        if uncertainty_weighting:
            # intialize weight variables
            natural_weight = tf.get_variable('natural_weight', shape = [], initializer = tf.constant_initializer(1.0))

            # augment the the loss function for the task
            natural_loss = tf.add(tf.divide(natural_loss, tf.multiply(tf.constant(2.0), tf.square(natural_weight))),
                                  tf.log(tf.square(natural_weight)), name = 'weighted_loss')

    # total loss function 
    with tf.variable_scope('Total_Loss'):
        loss = fs_loss + expense_loss + natural_loss
Run Code Online (Sandbox Code Playgroud)

有没有人有办法改变图表来处理没有标签的批次?

小智 4

基本上,你做得对。另一种方法是在计算损失之前使用“tf.gather”。我们假设样本没有标签,但标签为“-1”。

valid_idxs = tf.where(your_label > -1)[:, 0]
valid_logits = tf.gather(your_logits, valid_idxs)
valid_labels = tf.gather(your_label, valid_idxs)
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=valid_labels, logits=valid_logits)
Run Code Online (Sandbox Code Playgroud)