universal_attention/train.py
def train_reptile(
    meta_encoder: layers.Layer,
    run_name: str,
    batch_size: int,
    num_subtask_batches: int,
    subtask_learning_rate: float,
    meta_learning_rate: float,
    target_learning_rate: float,
    max_steps: Optional[int] = None,
    initial_step: int = 0,
    initial_checkpoint: Optional[str] = None,
    subtask_summary_every: Optional[int] = None,
    checkpoint_every: Optional[int] = None,
    eval_every: Optional[int] = None,
    target_epochs: int = 1,
) -> float:
    """
    Meta-train encoder with Reptile, evaluating on the target task periodically
    and at the end of training.

    NOTE: not all arguments to this function should should be left at their
    default values! This will lead to an infinite training run with no logs,
    checkpoints, or evaluation results.

    Parameters
    ----------
    meta_encoder: tf.keras.layers.Layer
        The encoder to train.
    run_name: str
        The name to associate logs and checkpoints with.
    batch_size: int
        Batch size to use for subtask and target training.
    num_subtask_batches: int
        The number of subtask batches to train on per meta step.
        In the Reptile paper, "k" or "inner loop steps."
    subtask_learning_rate: float
        Learning rate to use for subtask training.
    meta_learning_rate: float
        Learning rate to use for meta-steps.
    target_learning_rate: float
        Learning rate to use when training on the target task.
    max_steps: int (default: None)
        Maximum number of steps to train for.
        If 0 or None (default), train forever.
    initial_step: int (default: 0)
        Initial step to begin plotting at. Used to continue training runs.
    initial_checkpoint: path (default: None)
        If provided, path to "meta-classifier" checkpoint to initialize encoder.
    subtask_summary_every: int (default: None)
        Number of meta-steps between plotting summaries for a subtask.
        If 0 or None (default), do not plot summaries for subtasks.
    checkpoint_every: int (default: None)
        Number of meta-steps between saving checkpoints.  If 0 or
        None (default), do not save checkpoints until the end of training.
    eval_every: int (default: None)
        Number of meta-steps between evaluation by transfer-learning to the
        target task. If 0 or None (default), do not evaluate until the end
        of training.
    target_epochs: int (default: 1)
        Number of epochs to train the target model for during evaluation.

    Returns
    -------
    validation_accuracy: float
        The final target validation accuracy for this run.
    """
    print("=== Beginning a Reptile training run ===")
    logging.set_verbosity(logging.ERROR)  # Suppress spurious Keras warnings
    random.seed(FLAGS.random_seed)
    tf.random.set_seed(FLAGS.random_seed)

    checkpoint_dir = os.path.join(FLAGS.checkpoint_dir, run_name, "meta")
    os.makedirs(checkpoint_dir, exist_ok=True)
    meta_writer = tf.summary.create_file_writer(
        os.path.join(FLAGS.tb_log_dir, run_name, "meta")
    )

    def preprocess(splits):
        return {
            split: dataset.repeat().prefetch(tf.data.experimental.AUTOTUNE)
            for split, dataset in splits.items()
        }

    target_task = data.load_target_dataset(batch_size)
    subtasks = [
        (preprocess(splits), info)
        for splits, info in data.load_meta_datasets(batch_size)
    ]

    # Fill out a dummy "meta classifier" so that the two encoders' weights match
    meta_classifier = models.attending_classifier(meta_encoder, target_task)

    # See Reptile paper; momentum found to hurt meta-optimization
    meta_optimizer = optimizers.Adam(meta_learning_rate, beta_1=0.0)
    meta_step = initial_step

    if initial_checkpoint:
        meta_classifier.load_weights(initial_checkpoint)

    # A non-weight-sharing copy of the encoder, used in subtasks to optimize
    # the task network without impacting the meta-weights.
    task_encoder = meta_encoder.from_config(meta_encoder.get_config())

    # Make one full classifier with a persistent head per task
    subtask_models = [
        (models.attending_classifier(task_encoder, task), task)
        for task in subtasks
    ]

    for classifier, _ in subtask_models:
        classifier.compile(
            optimizers.SGD(subtask_learning_rate),
            loss={
                "prediction": losses.SparseCategoricalCrossentropy(
                    from_logits=True
                )
            },
        )

    def target_eval(step):
        print(f"=== Beginning target eval ===")
        task_encoder.set_weights(meta_encoder.get_weights())
        return train_target(
            encoder=task_encoder,
            num_epochs=target_epochs,
            batch_size=batch_size,
            learning_rate=target_learning_rate,
            run_name=run_name,
            meta_step=step,
        ).history

    def subtask_step(step):
        classifier, task = random.choice(subtask_models)
        print(f"[{meta_step}] Training on subtask: {task[1].name}")

        summary = subtask_summary_every and (step % subtask_summary_every == 0)
        task_encoder.set_weights(meta_encoder.get_weights())

        with meta_writer.as_default():
            train_subtask(
                classifier=classifier,
                task=task,
                num_batches=num_subtask_batches,
                plot_summaries=summary,
                meta_step=meta_step,
            )

    while (not max_steps) or (meta_step <= max_steps):
        # Periodic evaluation
        if eval_every and (meta_step % FLAGS.eval_every == 0):
            history = target_eval(meta_step)
            with meta_writer.as_default():
                tf.summary.scalar(
                    "Target training accuracy",
                    history["prediction_top_1_accuracy"][-1],
                    step=meta_step,
                )
                tf.summary.scalar(
                    "Target validation accuracy",
                    history["val_prediction_top_1_accuracy"][-1],
                    step=meta_step,
                )

        # Meta-training
        subtask_step(meta_step)
        meta_gradients = [
            orig - new
            for (orig, new) in zip(meta_encoder.weights, task_encoder.weights)
        ]
        meta_optimizer.apply_gradients(
            zip(meta_gradients, task_encoder.variables)
        )

        # Periodic checkpointing
        if (
            checkpoint_every
            and meta_step
            and (meta_step % checkpoint_every == 0)
        ):
            meta_classifier.save(
                os.path.join(
                    checkpoint_dir, f"{run_name}.meta:{meta_step}.hdf5"
                )
            )

        meta_step += 1

    # Final evaluation
    print("Done with meta-training!")
    eval_history = target_eval(meta_step)
    return eval_history["val_prediction_top_1_accuracy"][-1]

    Meta-train encoder with Reptile, evaluating on the target task periodically
    and at the end of training.

    NOTE: not all arguments to this function should should be left at their
    default values! This will lead to an infinite training run with no logs,
    checkpoints, or evaluation results.

    Parameters
    ----------
    meta_encoder: tf.keras.layers.Layer
        The encoder to train.
    run_name: str
        The name to associate logs and checkpoints with.
    batch_size: int
        Batch size to use for subtask and target training.
    num_subtask_batches: int
        The number of subtask batches to train on per meta step.
        In the Reptile paper, "k" or "inner loop steps."
    subtask_learning_rate: float
        Learning rate to use for subtask training.
    meta_learning_rate: float
        Learning rate to use for meta-steps.
    target_learning_rate: float
        Learning rate to use when training on the target task.
    max_steps: int (default: None)
        Maximum number of steps to train for.
        If 0 or None (default), train forever.
    initial_step: int (default: 0)
        Initial step to begin plotting at. Used to continue training runs.
    initial_checkpoint: path (default: None)
        If provided, path to "meta-classifier" checkpoint to initialize encoder.
    subtask_summary_every: int (default: None)
        Number of meta-steps between plotting summaries for a subtask.
        If 0 or None (default), do not plot summaries for subtasks.
    checkpoint_every: int (default: None)
        Number of meta-steps between saving checkpoints.  If 0 or
        None (default), do not save checkpoints until the end of training.
    eval_every: int (default: None)
        Number of meta-steps between evaluation by transfer-learning to the
        target task. If 0 or None (default), do not evaluate until the end
        of training.
    target_epochs: int (default: 1)
        Number of epochs to train the target model for during evaluation.

    Returns
    -------
    validation_accuracy: float
        The final target validation accuracy for this run.
    
Meta-train encoder with Reptile, evaluating on the target task periodically
and at the end of training.

not all arguments to this function should should be left at their
default values. This will lead to an infinite training run with no logs,
checkpoints, or evaluation results.

Parameters

tf.keras.layers.Layer
The encoder to train.
run_name: str
The name to associate logs and checkpoints with.
batch_size: int
Batch size to use for subtask and target training.
num_subtask_batches: int
The number of subtask batches to train on per meta step.
In the Reptile paper, "k" or "inner loop steps."
subtask_learning_rate: float
Learning rate to use for subtask training.
meta_learning_rate: float
Learning rate to use for meta-steps.
target_learning_rate: float
Learning rate to use when training on the target task.
max_steps: int (default: None)
Maximum number of steps to train for.
If 0 or None (default), train forever.
initial_step: int (default: 0)
Initial step to begin plotting at. Used to continue training runs.
initial_checkpoint: path (default: None)
If provided, path to "meta-classifier" checkpoint to initialize encoder.
subtask_summary_every: int (default: None)
Number of meta-steps between plotting summaries for a subtask.
If 0 or None (default), do not plot summaries for subtasks.
checkpoint_every: int (default: None)
Number of meta-steps between saving checkpoints.  If 0 or
None (default), do not save checkpoints until the end of training.
eval_every: int (default: None)
Number of meta-steps between evaluation by transfer-learning to the
target task. If 0 or None (default), do not evaluate until the end
of training.
target_epochs: int (default: 1)
Number of epochs to train the target model for during evaluation.

Returns

float
The final target validation accuracy for this run.
Meta - train encoder with Reptile evaluating on the target task periodically and at the end of training . not all arguments to this function should should be left at their default values . This will lead to an infinite training run with no logs checkpoints or evaluation results . Parameters tf . keras . layers . Layer The encoder to train . run_name : str The name to associate logs and checkpoints with . batch_size : int Batch size to use for subtask and target training . num_subtask_batches : int The number of subtask batches to train on per meta step . In the Reptile paper " k " or " inner loop steps . " subtask_learning_rate : float Learning rate to use for subtask training . meta_learning_rate : float Learning rate to use for meta - steps . target_learning_rate : float Learning rate to use when training on the target task . max_steps : int ( default : None ) Maximum number of steps to train for . If 0 or None ( default ) train forever . initial_step : int ( default : 0 ) Initial step to begin plotting at . Used to continue training runs . initial_checkpoint : path ( default : None ) If provided path to " meta - classifier " checkpoint to initialize encoder . subtask_summary_every : int ( default : None ) Number of meta - steps between plotting summaries for a subtask . If 0 or None ( default ) do not plot summaries for subtasks . checkpoint_every : int ( default : None ) Number of meta - steps between saving checkpoints . If 0 or None ( default ) do not save checkpoints until the end of training . eval_every : int ( default : None ) Number of meta - steps between evaluation by transfer - learning to the target task . If 0 or None ( default ) do not evaluate until the end of training . target_epochs : int ( default : 1 ) Number of epochs to train the target model for during evaluation . Returns float The final target validation accuracy for this run .
def train_reptile(
    meta_encoder: layers.Layer,
    run_name: str,
    batch_size: int,
    num_subtask_batches: int,
    subtask_learning_rate: float,
    meta_learning_rate: float,
    target_learning_rate: float,
    max_steps: Optional[int] = None,
    initial_step: int = 0,
    initial_checkpoint: Optional[str] = None,
    subtask_summary_every: Optional[int] = None,
    checkpoint_every: Optional[int] = None,
    eval_every: Optional[int] = None,
    target_epochs: int = 1,
) -> float:
    print("=== Beginning a Reptile training run ===")
    logging.set_verbosity(logging.ERROR)  
    random.seed(FLAGS.random_seed)
    tf.random.set_seed(FLAGS.random_seed)
    checkpoint_dir = os.path.join(FLAGS.checkpoint_dir, run_name, "meta")
    os.makedirs(checkpoint_dir, exist_ok=True)
    meta_writer = tf.summary.create_file_writer(
        os.path.join(FLAGS.tb_log_dir, run_name, "meta")
    )
    def preprocess(splits):
        return {
            split: dataset.repeat().prefetch(tf.data.experimental.AUTOTUNE)
            for split, dataset in splits.items()
        }
    target_task = data.load_target_dataset(batch_size)
    subtasks = [
        (preprocess(splits), info)
        for splits, info in data.load_meta_datasets(batch_size)
    ]
    meta_classifier = models.attending_classifier(meta_encoder, target_task)
    meta_optimizer = optimizers.Adam(meta_learning_rate, beta_1=0.0)
    meta_step = initial_step
    if initial_checkpoint:
        meta_classifier.load_weights(initial_checkpoint)
    task_encoder = meta_encoder.from_config(meta_encoder.get_config())
    subtask_models = [
        (models.attending_classifier(task_encoder, task), task)
        for task in subtasks
    ]
    for classifier, _ in subtask_models:
        classifier.compile(
            optimizers.SGD(subtask_learning_rate),
            loss={
                "prediction": losses.SparseCategoricalCrossentropy(
                    from_logits=True
                )
            },
        )
    def target_eval(step):
        print(f"=== Beginning target eval ===")
        task_encoder.set_weights(meta_encoder.get_weights())
        return train_target(
            encoder=task_encoder,
            num_epochs=target_epochs,
            batch_size=batch_size,
            learning_rate=target_learning_rate,
            run_name=run_name,
            meta_step=step,
        ).history
    def subtask_step(step):
        classifier, task = random.choice(subtask_models)
        print(f"[{meta_step}] Training on subtask: {task[1].name}")
        summary = subtask_summary_every and (step % subtask_summary_every == 0)
        task_encoder.set_weights(meta_encoder.get_weights())
        with meta_writer.as_default():
            train_subtask(
                classifier=classifier,
                task=task,
                num_batches=num_subtask_batches,
                plot_summaries=summary,
                meta_step=meta_step,
            )
    while (not max_steps) or (meta_step <= max_steps):
        if eval_every and (meta_step % FLAGS.eval_every == 0):
            history = target_eval(meta_step)
            with meta_writer.as_default():
                tf.summary.scalar(
                    "Target training accuracy",
                    history["prediction_top_1_accuracy"][-1],
                    step=meta_step,
                )
                tf.summary.scalar(
                    "Target validation accuracy",
                    history["val_prediction_top_1_accuracy"][-1],
                    step=meta_step,
                )
        subtask_step(meta_step)
        meta_gradients = [
            orig - new
            for (orig, new) in zip(meta_encoder.weights, task_encoder.weights)
        ]
        meta_optimizer.apply_gradients(
            zip(meta_gradients, task_encoder.variables)
        )
        if (
            checkpoint_every
            and meta_step
            and (meta_step % checkpoint_every == 0)
        ):
            meta_classifier.save(
                os.path.join(
                    checkpoint_dir, f"{run_name}.meta:{meta_step}.hdf5"
                )
            )
        meta_step += 1
    print("Done with meta-training!")
    eval_history = target_eval(meta_step)
    return eval_history["val_prediction_top_1_accuracy"][-1]
def train_reptile ( meta_encoder : layers . Layer , run_name : str , batch_size : int , num_subtask_batches : int , subtask_learning_rate : float , meta_learning_rate : float , target_learning_rate : float , max_steps : Optional [ int ] = None , initial_step : int = 0 , initial_checkpoint : Optional [ str ] = None , subtask_summary_every : Optional [ int ] = None , checkpoint_every : Optional [ int ] = None , eval_every : Optional [ int ] = None , target_epochs : int = 1 , ) -> float : print ( "=== Beginning a Reptile training run ===" ) logging . set_verbosity ( logging . ERROR ) random . seed ( FLAGS . random_seed ) tf . random . set_seed ( FLAGS . random_seed ) checkpoint_dir = os . path . join ( FLAGS . checkpoint_dir , run_name , "meta" ) os . makedirs ( checkpoint_dir , exist_ok = True ) meta_writer = tf . summary . create_file_writer ( os . path . join ( FLAGS . tb_log_dir , run_name , "meta" ) ) def preprocess ( splits ) : return { split : dataset . repeat ( ) . prefetch ( tf . data . experimental . AUTOTUNE ) for split , dataset in splits . items ( ) } target_task = data . load_target_dataset ( batch_size ) subtasks = [ ( preprocess ( splits ) , info ) for splits , info in data . load_meta_datasets ( batch_size ) ] meta_classifier = models . attending_classifier ( meta_encoder , target_task ) meta_optimizer = optimizers . Adam ( meta_learning_rate , beta_1 = 0.0 ) meta_step = initial_step if initial_checkpoint : meta_classifier . load_weights ( initial_checkpoint ) task_encoder = meta_encoder . from_config ( meta_encoder . get_config ( ) ) subtask_models = [ ( models . attending_classifier ( task_encoder , task ) , task ) for task in subtasks ] for classifier , _ in subtask_models : classifier . compile ( optimizers . SGD ( subtask_learning_rate ) , loss = { "prediction" : losses . SparseCategoricalCrossentropy ( from_logits = True ) } , ) def target_eval ( step ) : print ( f"=== Beginning target eval ===" ) task_encoder . set_weights ( meta_encoder . get_weights ( ) ) return train_target ( encoder = task_encoder , num_epochs = target_epochs , batch_size = batch_size , learning_rate = target_learning_rate , run_name = run_name , meta_step = step , ) . history def subtask_step ( step ) : classifier , task = random . choice ( subtask_models ) print ( f"[{meta_step}] Training on subtask: {task[1].name}" ) summary = subtask_summary_every and ( step % subtask_summary_every == 0 ) task_encoder . set_weights ( meta_encoder . get_weights ( ) ) with meta_writer . as_default ( ) : train_subtask ( classifier = classifier , task = task , num_batches = num_subtask_batches , plot_summaries = summary , meta_step = meta_step , ) while ( not max_steps ) or ( meta_step <= max_steps ) : if eval_every and ( meta_step % FLAGS . eval_every == 0 ) : history = target_eval ( meta_step ) with meta_writer . as_default ( ) : tf . summary . scalar ( "Target training accuracy" , history [ "prediction_top_1_accuracy" ] [ - 1 ] , step = meta_step , ) tf . summary . scalar ( "Target validation accuracy" , history [ "val_prediction_top_1_accuracy" ] [ - 1 ] , step = meta_step , ) subtask_step ( meta_step ) meta_gradients = [ orig - new for ( orig , new ) in zip ( meta_encoder . weights , task_encoder . weights ) ] meta_optimizer . apply_gradients ( zip ( meta_gradients , task_encoder . variables ) ) if ( checkpoint_every and meta_step and ( meta_step % checkpoint_every == 0 ) ) : meta_classifier . save ( os . path . join ( checkpoint_dir , f"{run_name}.meta:{meta_step}.hdf5" ) ) meta_step += 1 print ( "Done with meta-training!" ) eval_history = target_eval ( meta_step ) return eval_history [ "val_prediction_top_1_accuracy" ] [ - 1 ]
Meta-train encoder with Reptile, evaluating on the target task periodically
and at the end of training.
Meta - train encoder with Reptile evaluating on the target task periodically and at the end of training .
"""
    Meta-train encoder with Reptile, evaluating on the target task periodically
    and at the end of training.

    NOTE: not all arguments to this function should should be left at their
    default values! This will lead to an infinite training run with no logs,
    checkpoints, or evaluation results.

    Parameters
    ----------
    meta_encoder: tf.keras.layers.Layer
        The encoder to train.
    run_name: str
        The name to associate logs and checkpoints with.
    batch_size: int
        Batch size to use for subtask and target training.
    num_subtask_batches: int
        The number of subtask batches to train on per meta step.
        In the Reptile paper, "k" or "inner loop steps."
    subtask_learning_rate: float
        Learning rate to use for subtask training.
    meta_learning_rate: float
        Learning rate to use for meta-steps.
    target_learning_rate: float
        Learning rate to use when training on the target task.
    max_steps: int (default: None)
        Maximum number of steps to train for.
        If 0 or None (default), train forever.
    initial_step: int (default: 0)
        Initial step to begin plotting at. Used to continue training runs.
    initial_checkpoint: path (default: None)
        If provided, path to "meta-classifier" checkpoint to initialize encoder.
    subtask_summary_every: int (default: None)
        Number of meta-steps between plotting summaries for a subtask.
        If 0 or None (default), do not plot summaries for subtasks.
    checkpoint_every: int (default: None)
        Number of meta-steps between saving checkpoints.  If 0 or
        None (default), do not save checkpoints until the end of training.
    eval_every: int (default: None)
        Number of meta-steps between evaluation by transfer-learning to the
        target task. If 0 or None (default), do not evaluate until the end
        of training.
    target_epochs: int (default: 1)
        Number of epochs to train the target model for during evaluation.

    Returns
    -------
    validation_accuracy: float
        The final target validation accuracy for this run.
    """ # Suppress spurious Keras warnings # Fill out a dummy "meta classifier" so that the two encoders' weights match # See Reptile paper; momentum found to hurt meta-optimization # A non-weight-sharing copy of the encoder, used in subtasks to optimize # the task network without impacting the meta-weights. # Make one full classifier with a persistent head per task # Periodic evaluation # Meta-training # Periodic checkpointing # Final evaluation
meta_encoder
layers.Layer
run_name
str
batch_size
int
num_subtask_batches
int
subtask_learning_rate
float
meta_learning_rate
float
target_learning_rate
float
max_steps
Optional[int]
initial_step
int
initial_checkpoint
Optional[str]
subtask_summary_every
Optional[int]
checkpoint_every
Optional[int]
eval_every
Optional[int]
target_epochs
int