Ejemplo n.º 1
0
def compute_metrics(model, summarise=True):
    """Compute metrics.

    Args:
        model (str): Name of the model folder.
        summarise (bool, optional): Summarise the metrics rather than given the data
            back. Defaults to `True`.

    Returns:
        union[None, tuple[:class:`np.array`, :class:`np.array`]]: The metrics if
            `summarise` is `False`. Otherwise nothing.
    """
    rmses, mlls = [], []
    preds = wd_results.load(model, "preds.pickle")
    for (y, mean, var) in preds:
        rmses.append(metric.rmse(mean, y))
        mlls.append(metric.mll(mean, var, y))
    if summarise:
        with out.Section(model.upper()):
            for name, values in [("MLL", mlls), ("RMSE", rmses)]:
                with out.Section(name):
                    out.kv("Mean", np.mean(values))
                    out.kv("Std", np.std(values) / len(values)**0.5)
    else:
        return mlls, rmses
Ejemplo n.º 2
0
def _sync_folder(source: str, ip: str, target: RemotePath):
    with out.Section("Syncing to remote folder"):
        out.kv("Source", source)
        with out.Section("Target"):
            out.kv("Host", target.remote.host)
            out.kv("Path", target.path)
        try:
            ssh(
                target.remote,
                f'rsync -Pav -e "ssh -oStrictHostKeyChecking=no -i {config["ssh_key"]}"'
                f' {config["ssh_user"]}@{ip}:{source} {target.path}',
            )
        except subprocess.CalledProcessError as e:
            out.kv("Synchronisation error", str(e))
Ejemplo n.º 3
0
    def _minimise_l_bfgs_b(f,
                           vs,
                           f_calls=10000,
                           iters=1000,
                           trace=False,
                           names=None,
                           jit=False):
        names = _convert_and_validate_names(names)

        # Run function once to ensure that all variables are initialised and
        # available.
        val_init = f(vs)

        # SciPy doesn't perform zero iterations, so handle that edge case
        # manually.
        if iters == 0 or f_calls == 0:
            return B.to_numpy(val_init)

        # Extract initial value.
        x0 = B.to_numpy(vs.get_latent_vector(*names))

        # The optimiser expects to get `float64`s.
        def _convert(*xs):
            return [B.cast(np.float64, B.to_numpy(x)) for x in xs]

        # Wrap the function and get the list of function evaluations.
        f_vals, f_wrapped = wrap_f(vs, names, f, jit, _convert)

        # Perform optimisation routine.
        def perform_minimisation(callback_=lambda _: None):
            return fmin_l_bfgs_b(
                func=f_wrapped,
                x0=x0,
                maxiter=iters,
                maxfun=f_calls,
                callback=callback_,
                disp=0,
            )

        if trace:
            # Print progress during minimisation.
            with out.Progress(name='Minimisation of "{}"'.format(f.__name__),
                              total=iters) as progress:

                def callback(_):
                    progress({"Objective value": np.min(f_vals)})

                x_opt, val_opt, info = perform_minimisation(callback)

            with out.Section("Termination message"):
                out.out(convert(info["task"], str))
        else:
            # Don't print progress; simply perform minimisation.
            x_opt, val_opt, info = perform_minimisation()

        vs.set_latent_vector(x_opt, *names)  # Assign optimum.

        return val_opt  # Return optimal value.
Ejemplo n.º 4
0
def print_logs(path: str):
    """Display the tail of logs on all running instances.

    Args:
        path (str): Path to the log.
    """
    for ip, log in ssh_map([f"tail -n100 {path}"], broadcast=True).items():
        with out.Section(ip):
            out.out(log)
Ejemplo n.º 5
0
def compare(model1, model2):
    """Compare two models.

    Args:
        model1 (str): Model folder of the first model to compare.
        model2 (str): Model folder of the second model to compare.
    """
    mlls1, rmses1 = compute_metrics(model1, summarise=False)
    mlls2, rmses2 = compute_metrics(model2, summarise=False)
    with out.Section(f"{model1.upper()} - {model2.upper()}"):
        for name, values1, values2 in [("MLL", mlls1, mlls2),
                                       ("RMSE", rmses1, rmses2)]:
            diff = [x - y for x, y in zip(values1, values2)]
            with out.Section(name):
                mean = np.mean(diff)
                std = np.std(diff) / len(diff)**0.5
                out.kv("Mean", mean)
                out.kv("Std", std)
                out.kv("p-value", st.norm.cdf(-abs(mean) / std))
Ejemplo n.º 6
0
def test_out_newlines():
    # Test that newlines are correctly indented.
    with Mock() as mock:
        out.out("a\nb")

        with out.Section():
            out.out("c\nd")

    assert len(mock) == 2
    assert mock[0] == "a\nb\n"
    assert mock[1] == "    c\n    d\n"
Ejemplo n.º 7
0
def test_section():
    with Mock() as mock:
        out.out("before")

        with out.Section():
            out.out("message1")

        with out.Section("name"):
            out.out("message2")

            with out.Section():
                out.out("message3")

        out.out("after")

    assert len(mock) == 6
    assert mock[0] == "before\n"
    assert mock[1] == "    message1\n"
    assert mock[2] == "name:\n"
    assert mock[3] == "    message2\n"
    assert mock[4] == "        message3\n"
    assert mock[5] == "after\n"
Ejemplo n.º 8
0
    def minimise_l_bfgs_b(f,
                          vs,
                          f_calls=10000,
                          iters=1000,
                          trace=False,
                          names=None):
        names = [] if names is None else names

        # Run function once to ensure that all variables are initialised and
        # available.
        val_init = f(vs)

        # SciPy doesn't perform zero iterations, so handle that edge case
        # manually.
        if iters == 0 or f_calls == 0:
            return B.to_numpy(val_init)

        # Extract initial value.
        x0 = B.to_numpy(vs.get_vector(*names))

        # Wrap the function and get the list of function evaluations.
        f_vals, f_wrapped = wrap_f(vs, names, f)

        # Perform optimisation routine.
        def perform_minimisation(callback_=lambda _: None):
            return fmin_l_bfgs_b(func=f_wrapped,
                                 x0=x0,
                                 maxiter=iters,
                                 maxfun=f_calls,
                                 callback=callback_,
                                 disp=0)

        if trace:
            # Print progress during minimisation.
            with out.Progress(name='Minimisation of "{}"'.format(f.__name__),
                              total=iters) as progress:
                def callback(_):
                    progress({'Objective value': np.min(f_vals)})

                x_opt, val_opt, info = perform_minimisation(callback)

            with out.Section('Termination message'):
                out.out(info['task'].decode('utf-8'))
        else:
            # Don't print progress; simply perform minimisation.
            x_opt, val_opt, info = perform_minimisation()

        vs.set_vector(x_opt, *names)  # Assign optimum.

        return val_opt  # Return optimal value.
Ejemplo n.º 9
0
def _sync_folder(source: str, ip: str, target: LocalPath):
    with out.Section("Syncing to local folder"):
        out.kv("Source", source)
        out.kv("Target", target.path)
        try:
            execute_command(
                "rsync",
                "-Pav",
                "-e",
                f'ssh -oStrictHostKeyChecking=no -i {config["ssh_key"]}',
                f'{config["ssh_user"]}@{ip}:{source}',
                target.path,
            )
        except subprocess.CalledProcessError as e:
            out.kv("Synchronisation error", str(e))
Ejemplo n.º 10
0
def sync(sources: List[str], target: Path, ips: List[str] = None):
    """Synchronise data.

    Args:
        sources (list[str]): List of sources to sync.
        target (:class:`.util.Path`): Directory to sync to.
        ips (list[str], optional): IPs to sync. Defaults to all running IPs.
    """
    if ips is None:
        ips = get_running_ips()

    for ip in ips:
        with out.Section(ip):
            for source in sources:
                _sync_folder(source, ip, target)
Ejemplo n.º 11
0
def exception(x, e):
    """In the case that an exception is raised during function evaluation,
    print a warning and return NaN for the function value and gradient.

    Args:
        x (tensor): Current input.
        e (:class:`Exception`): Caught exception.

    Returns:
        tuple: Tuple containing NaN and NaNs for the gradient.
    """
    with out.Section("Caught exception during function evaluation"):
        out.out(traceback.format_exc().strip())
    grad_nan = np.empty(x.shape)
    grad_nan[:] = np.nan
    return np.nan, grad_nan
Ejemplo n.º 12
0
def kernel_analysis(data, scheme, model, metric, until=4):
    """Analyse the prediction for a kernel."""
    k = wd_results.load(data, "data.pickle")["k"]
    t, mean, var = wd_results.load(data, scheme, model, "k_pred.pickle")
    inds = t <= until
    if metric == "smll":
        return smll(mean[inds], var[inds], k[inds])
    elif metric == "rmse":
        return rmse(mean[inds], k[inds])
    else:
        raise ValueError(f'Bad metric "{metric}".')


for model, kernel in [("gpcm", "eq"), ("cgpcm", "ceq-1"),
                      ("rgpcm", "matern12")]:
    with out.Section(model.upper()):
        with out.Section("SMLL"):
            out.kv("MF", kernel_analysis(kernel, "mean-field", model, "smll"))
            out.kv("S", kernel_analysis(kernel, "structured", model, "smll"))
        with out.Section("RMSE"):
            out.kv("MF", kernel_analysis(kernel, "mean-field", model, "rmse"))
            out.kv("S", kernel_analysis(kernel, "structured", model, "rmse"))


def plot_kernel_predictions(model, data_name, legend=True, first=False):
    """Plot the prediction for a kernel."""
    k = wd_results.load(data_name, "data.pickle")["k"]
    t, mean1, var1 = wd_results.load(data_name, "structured", model,
                                     "k_pred.pickle")
    t, mean2, var2 = wd_results.load(data_name, "mean-field", model,
                                     "k_pred.pickle")
Ejemplo n.º 13
0
# Load predictions.
preds_f = {}
preds_f_test = {}
preds_k = {}
preds_psd = {}
for model in models:
    preds_f[model.name] = wd.load(model.name.lower(), "pred_f.pickle")
    preds_f_test[model.name] = wd.load(model.name.lower(),
                                       "pred_f_test.pickle")
    preds_k[model.name] = wd.load(model.name.lower(), "pred_k.pickle")
    preds_psd[model.name] = wd.load(model.name.lower(), "pred_psd.pickle")

# Print performances.
for name in ["GPCM", "CGPCM", "RGPCM"]:
    with out.Section(name):
        t, mean, var = preds_f_test[name]
        out.kv("RMSE", metric.rmse(mean, y_test))
        out.kv("MLL", metric.mll(mean, var, y_test))


def plot_psd(name, y_label=True, style="pred", finish=True):
    """Plot prediction for the PSD."""
    freqs, mean, lower, upper = preds_psd[name]
    freqs -= freqs[0]

    inds = freqs <= 0.2
    freqs = freqs[inds]
    mean = mean[inds]
    lower = lower[inds]
    upper = upper[inds]
Ejemplo n.º 14
0
Archivo: smk.py Proyecto: wesselb/gpcm
        n_z=n_z,
        t=t,
    )
    model.fit(t, y, iters=30_000)
    k_pred_struc = extract(model.condition(t, y).predict_kernel(t_k))
    psd_pred_struc = extract(model.condition(t, y).predict_psd())

    wd.save((k_pred_mf, psd_pred_mf, k_pred_struc, psd_pred_struc),
            "preds.pickle")
else:
    k_pred_mf, psd_pred_mf, k_pred_struc, psd_pred_struc = wd.load(
        "preds.pickle")

# Report metrics.

with out.Section("Structured"):
    t, mean, var, _, _ = k_pred_struc
    inds = t <= 3
    out.kv("MLL", metric.mll(mean[inds], var[inds], k[inds]))
    out.kv("RMSE", metric.rmse(mean[inds], k[inds]))
with out.Section("Mean field"):
    t, mean, var, _, _ = k_pred_mf
    inds = t <= 3
    out.kv("MLL", metric.mll(mean[inds], var[inds], k[inds]))
    out.kv("RMSE", metric.rmse(mean[inds], k[inds]))

plt.figure(figsize=(7.5, 3.75))

# Plot prediction for kernel.

plt.subplot(1, 2, 1)
Ejemplo n.º 15
0
def manage_cluster(
    commands: List[List[str]],
    instance_type: str,
    key_name: str,
    security_group_id: str,
    image_id: str,
    sync_sources: List[str],
    sync_target: Path,
    monitor_aws_repo: str,
    monitor_call: str,
    monitor_delay: int,
):
    """Manage the cluster.

    Args:
        commands (list[list[str]]): One list of commands for every experiment.
        image_id (str): Image ID.
        instance_type (str): Type of the instance.
        key_name (str): Name of the key pair.
        security_group_id (str): Security group.
        sync_sources (list[str]): List of sources to sync.
        sync_target (:class:`.util.Path`): Directory to sync to.
        monitor_aws_repo (str, optional): Path to the root of this repo. The repo
            must consider the virtual environment "venv" which has the repo installed
            in editable mode.
        monitor_call (str): Call to start the monitor. See :mod:`.monitor`.
        monitor_delay (int): Number of seconds to wait before starting the monitor.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--spawn",
        type=int,
        help="Spawn instances.",
    )
    parser.add_argument(
        "--start",
        action="store_true",
        help="Start experiments.",
    )
    parser.add_argument(
        "--terminate",
        action="store_true",
        help="Terminate all instances. This is a kill switch.",
    )
    parser.add_argument(
        "--kill",
        action="store_true",
        help="Kill all running experiments, but keep the instances running.",
    )
    parser.add_argument(
        "--stop",
        action="store_true",
        help="Stop all running instances",
    )
    parser.add_argument(
        "--sync-stopped",
        action="store_true",
        help="Synchronise all stopped instances.",
    )
    parser.add_argument(
        "--sync-sleep",
        default=120,
        type=int,
        help="Number of seconds to sleep before syncing again.",
    )
    args = parser.parse_args()

    if args.sync_stopped:
        with out.Section("Syncing all stopped instances in five batches"):
            for batch in np.array_split(get_state("stopped"), 5):
                # Batches can be empty.
                if len(batch) == 0:
                    continue

                # Start the instances.
                start(*batch)

                try:
                    # Wait for the instances to have booted.
                    out.out(
                        "Waiting a minute for the instances to have booted...")
                    time.sleep(60)

                    # Refresh the instances to get the IPs.
                    instance_ids = [
                        instance["InstanceId"] for instance in batch
                    ]
                    batch = get_instances(*instance_ids)

                    # Sync.
                    sync(
                        sync_sources,
                        sync_target,
                        ips=[
                            instance["PublicIpAddress"] for instance in batch
                        ],
                    )
                finally:
                    # Stop the instances again.
                    stop(*batch)

        out.out("Syncing completed: not continuing execution of script.")
        exit()

    if args.spawn:
        with out.Section("Starting all stopped instances"):
            start_stopped()

        with out.Section("Spawning instances"):
            spawn(
                image_id=image_id,
                total_count=args.spawn,
                instance_type=instance_type,
                key_name=key_name,
                security_group_id=security_group_id,
            )

        while not check_all_running():
            out.out("Waiting for all instances to be running...")
            time.sleep(5)

        out.out("Waiting a minute for all instances to have booted...")
        time.sleep(60)

    if args.kill:
        with out.Section("Killing all experiments"):
            kill_all()

    if args.stop:
        with out.Section("Stopping all instances"):
            stop_running()

    if args.terminate:
        with out.Section("Terminating all instances"):
            terminate_all()

    if args.start:
        num_instances = len(get_running_ips())
        pieces = np.array_split(commands, num_instances)
        # Ensure that we have regular Python lists.
        pieces = [piece.tolist() for piece in pieces]

        with out.Section("Starting experiments"):
            out.kv("Number of commands", len(commands))
            out.kv("Number of instances", num_instances)
            out.kv("Maximum runs per instance",
                   max([len(piece) for piece in pieces]))
            ssh_map(
                *[[
                    *config["setup_commands"],
                    *sum(piece, []),
                    *config["teardown_commands"],
                ] for piece in pieces],
                start_experiment=True,
                in_experiment=True,
                start_monitor=True,
                monitor_aws_repo=monitor_aws_repo,
                monitor_delay=monitor_delay,
                monitor_call=monitor_call,
            )

    while True:
        out.kv("Instances still running", len(get_running_ips()))
        sync(sync_sources, sync_target)
        out.out(f"Sleeping for {args.sync_sleep} second(s)...")
        time.sleep(args.sync_sleep)
Ejemplo n.º 16
0
# Setup script.
wd = WorkingDirectory("_experiments", "crude_oil_aggregate")

# Load all experiments and compute metrics.
names = ["GPCM", "CGPCM", "RGPCM"]
mlls = {name: [] for name in names}
rmses = {name: [] for name in names}
for year in range(2012, 2017 + 1):
    wd_results = WorkingDirectory("_experiments", "crude_oil", str(year), observe=True)
    t, y = wd_results.load("data.pickle")["test"]
    for name in names:
        _, mean, var = wd_results.load(name.lower(), "pred_f_test.pickle")
        mlls[name].append(metric.mll(mean, var, y))
        rmses[name].append(metric.rmse(mean, y))

# Print aggregate results.
for name in names:
    with out.Section(name):
        out.kv("MLL", np.mean(mlls[name]))
        out.kv("MLL (std)", np.std(mlls[name]) / len(mlls[name]) ** 0.5)
        out.kv("RMSE", np.mean(rmses[name]))
        out.kv("RMSE (std)", np.std(rmses[name]) / len(rmses[name]) ** 0.5)

# Compare results.
for name1, name2 in [("RGPCM", "CGPCM"), ("RGPCM", "GPCM"), ("CGPCM", "GPCM")]:
    with out.Section(f"{name1} - {name2}"):
        out.kv("MLL", np.mean(mlls[name1]) - np.mean(mlls[name2]))
        out.kv("MLL (p)", ttest_rel(mlls[name1], mlls[name2]).pvalue)
        out.kv("RMSE", np.mean(rmses[name1]) - np.mean(rmses[name2]))
        out.kv("RMSE (p)", ttest_rel(rmses[name1], rmses[name2]).pvalue)