Example #1
0
def ensure_armory_dirs(request):
    """
    CI doesn't mount volumes
    """
    saved_model_dir = paths.docker().saved_model_dir
    dataset_dir = paths.docker().dataset_dir
    output_dir = paths.docker().output_dir

    os.makedirs(saved_model_dir, exist_ok=True)
    os.makedirs(dataset_dir, exist_ok=True)
    os.makedirs(output_dir, exist_ok=True)
Example #2
0
def get_art_model(model_kwargs, wrapper_kwargs, weights_file=None):
    model = ResNet50(weights=None, **model_kwargs)

    if weights_file:
        saved_model_dir = paths.docker().saved_model_dir
        filepath = os.path.join(saved_model_dir, weights_file)

        if not os.path.isfile(filepath):
            download_file_from_s3(
                "armory-public-data",
                f"model-weights/{weights_file}",
                f"{saved_model_dir}/{weights_file}",
            )

        model.load_weights(filepath)

    wrapped_model = KerasClassifier(
        model,
        clip_values=(
            np.array([
                0.0 - IMAGENET_MEANS[0],
                0.0 - IMAGENET_MEANS[1],
                0.0 - IMAGENET_MEANS[2],
            ]),
            np.array([
                255.0 - IMAGENET_MEANS[0],
                255.0 - IMAGENET_MEANS[1],
                255.0 - IMAGENET_MEANS[2],
            ]),
        ),
        **wrapper_kwargs,
    )
    return wrapped_model
Example #3
0
    def save(self, config: dict, results: dict, adv_examples=None):
        """
        Saves a results json-formattable output to file

        adv_examples are (optional) instances of the actual examples used.
            It will be saved in a binary format.
        """
        if adv_examples is not None:
            raise NotImplementedError("saving adversarial examples")

        scenario_name = config["scenario"]["name"]
        filename = f"{scenario_name}_{int(time.time())}.json"
        logger.info(
            f"Saving evaluation results saved to <output_dir>/{filename}")
        with open(os.path.join(paths.docker().output_dir, filename), "w") as f:
            output_dict = {
                "armory_version": armory.__version__,
                "config": config,
                "results": results,
            }
            f.write(json.dumps(output_dict, sort_keys=True, indent=4) + "\n")
Example #4
0
def maybe_download_weights_from_s3(weights_file: str) -> str:
    """

    :param weights_file:
    :return:
    """
    saved_model_dir = paths.docker().saved_model_dir
    filepath = os.path.join(saved_model_dir, weights_file)

    if os.path.isfile(filepath):
        logger.info(f"Using available {weights_file} in Armory `saved_model_dir`")
    else:
        logger.info(
            f"{weights_file} not found in Armory `saved_model_dir`. Attempting to pull weights from S3"
        )
        download_file_from_s3(
            "armory-public-data",
            f"model-weights/{weights_file}",
            f"{saved_model_dir}/{weights_file}",
        )
    return filepath
Example #5
0
from importlib import import_module

import numpy as np
import pytest

from armory.data import datasets
from armory import paths

DATASET_DIR = paths.docker().dataset_dir


@pytest.mark.usefixtures("ensure_armory_dirs")
def test_keras_mnist():
    classifier_module = import_module("armory.baseline_models.keras.mnist")
    classifier_fn = getattr(classifier_module, "get_art_model")
    classifier = classifier_fn(model_kwargs={}, wrapper_kwargs={})
    preprocessing_fn = getattr(classifier_module, "preprocessing_fn")

    train_dataset = datasets.mnist(
        split_type="train",
        epochs=1,
        batch_size=600,
        dataset_dir=DATASET_DIR,
        preprocessing_fn=preprocessing_fn,
    )
    test_dataset = datasets.mnist(
        split_type="test",
        epochs=1,
        batch_size=100,
        dataset_dir=DATASET_DIR,
        preprocessing_fn=preprocessing_fn,
Example #6
0
    def __init__(self,
                 config_path: Union[str, dict],
                 container_config_name="eval-config.json"):
        self.host_paths = paths.host()
        self.docker_paths = paths.docker()

        if os.name != "nt":
            self.user_id, self.group_id = os.getuid(), os.getgid()
        else:
            self.user_id, self.group_id = 0, 0

        self.extra_env_vars = dict()
        if isinstance(config_path, str):
            try:
                self.config = load_config(config_path)
            except json.decoder.JSONDecodeError:
                logger.error(f"Could not decode {config_path} as a json file.")
                if not config_path.lower().endswith(".json"):
                    logger.warning(f"{config_path} is not a '*.json' file")
                    logger.warning(
                        "If using `armory run`, use a json config file.")
                raise
        elif isinstance(config_path, dict):
            self.config = config_path
        else:
            raise ValueError(
                f"config_path {config_path} must be a str or dict")
        (
            self.container_subdir,
            self.tmp_dir,
            self.output_dir,
        ) = volumes_util.tmp_output_subdir()
        self.tmp_config = os.path.join(self.tmp_dir, container_config_name)
        self.external_repo_dir = paths.get_external(self.tmp_dir)
        self.docker_config_path = Path(
            os.path.join(self.docker_paths.tmp_dir,
                         container_config_name)).as_posix()

        kwargs = dict(runtime="runc")
        if self.config["sysconfig"].get("use_gpu", None):
            kwargs["runtime"] = "nvidia"
            gpus = self.config["sysconfig"].get("gpus")
            if gpus is not None:
                self.extra_env_vars["NVIDIA_VISIBLE_DEVICES"] = gpus

        if self.config["sysconfig"].get("external_github_repo", None):
            self._download_external()
            self.extra_env_vars.update(
                {"PYTHONPATH": self.docker_paths.external_repo_dir})

        if self.config["sysconfig"].get("use_armory_private", None):
            self._download_private()

        image_name = self.config["sysconfig"].get("docker_image")
        kwargs["image_name"] = image_name

        # Download docker image on host
        docker_client = docker.from_env()
        try:
            docker_client.images.get(kwargs["image_name"])
        except ImageNotFound:
            logger.info(f"Image {image_name} was not found. Downloading...")
            docker_api.pull_verbose(docker_client, image_name)
        except requests.exceptions.ConnectionError:
            logger.error(
                f"Docker connection refused. Is Docker Daemon running?")
            raise

        self.manager = ManagementInstance(**kwargs)
Example #7
0
def _generator_from_tfds(
    dataset_name: str,
    split_type: str,
    batch_size: int,
    epochs: int,
    dataset_dir: str,
    preprocessing_fn: Callable,
    as_supervised: bool = True,
    supervised_xy_keys=None,
    download_and_prepare_kwargs=None,
    variable_length=False,
    shuffle_files=True,
    cache_dataset: bool = True,
):
    """
    If as_supervised=False, must designate keys as a tuple in supervised_xy_keys:
        supervised_xy_keys=('video', 'label')  # ucf101 dataset
    if variable_length=True and batch_size > 1:
        output batches are 1D np.arrays of objects
    """
    if not dataset_dir:
        dataset_dir = paths.docker().dataset_dir

    if cache_dataset:
        _cache_dataset(
            dataset_dir,
            dataset_name=dataset_name,
        )

    default_graph = tf.compat.v1.keras.backend.get_session().graph

    ds, ds_info = tfds.load(
        dataset_name,
        split=split_type,
        as_supervised=as_supervised,
        data_dir=dataset_dir,
        with_info=True,
        download_and_prepare_kwargs=download_and_prepare_kwargs,
        shuffle_files=shuffle_files,
    )
    if not as_supervised:
        try:
            x_key, y_key = supervised_xy_keys
        except (TypeError, ValueError):
            raise ValueError(
                f"When as_supervised=False, supervised_xy_keys must be a (x_key, y_key)"
                f" tuple, not {supervised_xy_keys}")
        if not isinstance(x_key, str) or not isinstance(y_key, str):
            raise ValueError(f"supervised_xy_keys be a tuple of strings,"
                             f" not {type(x_key), type(y_key)}")
        ds = ds.map(lambda x: (x[x_key], x[y_key]))

    ds = ds.repeat(epochs)
    if shuffle_files:
        ds = ds.shuffle(batch_size * 10, reshuffle_each_iteration=True)
    if variable_length and batch_size > 1:
        ds = ds.batch(1, drop_remainder=False)
    else:
        ds = ds.batch(batch_size, drop_remainder=False)
    ds = ds.prefetch(tf.data.experimental.AUTOTUNE)
    ds = tfds.as_numpy(ds, graph=default_graph)

    generator = ArmoryDataGenerator(
        ds,
        size=ds_info.splits[split_type].num_examples,
        batch_size=batch_size,
        epochs=epochs,
        preprocessing_fn=preprocessing_fn,
        variable_length=bool(variable_length and batch_size > 1),
    )

    return generator