class_docstr: Pipeline for multi-task training.
  
  This handles a set of losses and labels. It is intended to mainly work with
  `MultiLabelDatasetBuilder`.
  
  Use subclassing to customize the losses and metrics.
  
  Example usage:
  
  ```python
  context_feature_spec = {}
  example_feature_spec = {
      "example_feature_1": tf.io.FixedLenFeature(
          shape=(1,), dtype=tf.float32, default_value=0.0)
  }
  mask_feature_name = "list_mask"
  label_spec_tuple = ("utility",
                      tf.io.FixedLenFeature(
                          shape=(1,),
                          dtype=tf.float32,
                          default_value=_PADDING_LABEL))
  label_spec = {"task1": label_spec_tuple, "task2": label_spec_tuple}
  weight_spec = ("weight",
                 tf.io.FixedLenFeature(
                     shape=(1,), dtype=tf.float32, default_value=1.))
  dataset_hparams = DatasetHparams(
      train_input_pattern="train.dat",
      valid_input_pattern="valid.dat",
      train_batch_size=128,
      valid_batch_size=128)
  pipeline_hparams = PipelineHparams(
      model_dir="model/",
      num_epochs=2,
      steps_per_epoch=5,
      validation_steps=2,
      learning_rate=0.01,
      loss={
          "task1": "softmax_loss",
          "task2": "pairwise_logistic_loss"
      },
      loss_weights={
          "task1": 1.0,
          "task2": 2.0
      },
      export_best_model=True)
  model_builder = MultiTaskModelBuilder(...)
  dataset_builder = MultiLabelDatasetBuilder(
      context_feature_spec,
      example_feature_spec,
      mask_feature_name,
      label_spec,
      dataset_hparams,
      sample_weight_spec=weight_spec)
  pipeline = MultiTaskPipeline(model_builder, dataset_builder, pipeline_hparams)
  pipeline.train_and_validate(verbose=1)
  ```
class_docstr_tok: ["Pipeline","for","multi-task","training",".","This","handles","a","set","of","losses","and","labels",".","It","is","intended","to","mainly","work","with","`","MultiLabelDatasetBuilder","`",".","Use","subclassing","to","customize","the","losses","and","metrics",".","Example","usage",":","``","`","python","context_feature_spec","=","{","}","example_feature_spec","=","{","``","example_feature_1","''",":","tf.io.FixedLenFeature","(","shape=","(","1",",",")",",","dtype=tf.float32",",","default_value=0.0",")","}","mask_feature_name","=","``","list_mask","''","label_spec_tuple","=","(","``","utility","''",",","tf.io.FixedLenFeature","(","shape=","(","1",",",")",",","dtype=tf.float32",",","default_value=_PADDING_LABEL",")",")","label_spec","=","{","``","task1","''",":","label_spec_tuple",",","``","task2","''",":","label_spec_tuple","}","weight_spec","=","(","``","weight","''",",","tf.io.FixedLenFeature","(","shape=","(","1",",",")",",","dtype=tf.float32",",","default_value=1",".",")",")","dataset_hparams","=","DatasetHparams","(","train_input_pattern=","''","train.dat","''",",","valid_input_pattern=","''","valid.dat","''",",","train_batch_size=128",",","valid_batch_size=128",")","pipeline_hparams","=","PipelineHparams","(","model_dir=","''","model\/","''",",","num_epochs=2",",","steps_per_epoch=5",",","validation_steps=2",",","learning_rate=0.01",",","loss=","{","``","task1","''",":","``","softmax_loss","''",",","``","task2","''",":","``","pairwise_logistic_loss","''","}",",","loss_weights=","{","``","task1","''",":","1.0",",","``","task2","''",":","2.0","}",",","export_best_model=True",")","model_builder","=","MultiTaskModelBuilder","(","...",")","dataset_builder","=","MultiLabelDatasetBuilder","(","context_feature_spec",",","example_feature_spec",",","mask_feature_name",",","label_spec",",","dataset_hparams",",","sample_weight_spec=weight_spec",")","pipeline","=","MultiTaskPipeline","(","model_builder",",","dataset_builder",",","pipeline_hparams",")","pipeline.train_and_validate","(","verbose=1",")","``","`"]
docstr: See `AbstractPipeline`.
code: def build_weighted_metrics(
      self,
  ) -> Dict[str, List[tf.keras.metrics.Metric]]:
      """See `AbstractPipeline`."""
  
      def eval_metrics():
          return [
              _get_metric(
                  "weighted_metric/",
                  metrics.RankingMetricKey.NDCG,
                  topn=topn,
              )
              for topn in [1, 5, 10, None]
          ]
  
      return {
          task_name: eval_metrics() for task_name in self._hparams.loss
      }
  
imports: import abc
  import dataclasses
  import os
  from typing import Any, Dict, List, Optional, Tuple, Union
  import tensorflow
  from tensorflow_ranking.python import data
  from tensorflow_ranking.python.keras import losses
  from tensorflow_ranking.python.keras import metrics
  from tensorflow_ranking.python.keras import model
  from tensorflow_ranking.python.keras import saved_model
  from tensorflow_ranking.python.keras import strategy_utils
label_desc: Use image node_id 3 for calling the MultiTaskPipeline obj's underlying member method code with example usage: obj.build_weighted_metrics() and returns: unknown, unknown