示例#1
0
def load_tf_ae(filepath: str) -> tf.keras.Model:
    """
    Load AE.

    Parameters
    ----------
    filepath
        Save directory.

    Returns
    -------
    Loaded AE.
    """
    model_dir = os.path.join(filepath, 'model')
    if not [f for f in os.listdir(model_dir) if not f.startswith('.')]:
        logger.warning(
            'No encoder, decoder or ae found in {}.'.format(model_dir))
        return None
    encoder_net = tf.keras.models.load_model(
        os.path.join(model_dir, 'encoder_net.h5'))
    decoder_net = tf.keras.models.load_model(
        os.path.join(model_dir, 'decoder_net.h5'))
    ae = AE(encoder_net, decoder_net)
    ae.load_weights(os.path.join(model_dir, 'ae.ckpt'))
    return ae
示例#2
0
    def __init__(self,
                 threshold: float = None,
                 ae: tf.keras.Model = None,
                 encoder_net: tf.keras.Sequential = None,
                 decoder_net: tf.keras.Sequential = None,
                 data_type: str = None) -> None:
        """
        AE-based outlier detector.

        Parameters
        ----------
        threshold
            Threshold used for outlier score to determine outliers.
        ae
            A trained tf.keras model if available.
        encoder_net
            Layers for the encoder wrapped in a tf.keras.Sequential class if no 'ae' is specified.
        decoder_net
            Layers for the decoder wrapped in a tf.keras.Sequential class if no 'ae' is specified.
        data_type
            Optionally specify the data type (tabular, image or time-series). Added to metadata.
        """
        super().__init__()

        if threshold is None:
            logger.warning(
                'No threshold level set. Need to infer threshold using `infer_threshold`.'
            )

        self.threshold = threshold

        # check if model can be loaded, otherwise initialize AE model
        if isinstance(ae, tf.keras.Model):
            self.ae = ae
        elif isinstance(encoder_net, tf.keras.Sequential) and isinstance(
                decoder_net, tf.keras.Sequential):
            self.ae = AE(encoder_net, decoder_net)
        else:
            raise TypeError(
                'No valid format detected for `ae` (tf.keras.Model) '
                'or `encoder_net`, `decoder_net` (tf.keras.Sequential).')

        # set metadata
        self.meta['detector_type'] = 'offline'
        self.meta['data_type'] = data_type
    def __init__(self,
                 threshold: float = None,
                 ae: tf.keras.Model = None,
                 model: tf.keras.Model = None,
                 encoder_net: tf.keras.Sequential = None,
                 decoder_net: tf.keras.Sequential = None,
                 model_hl: List[tf.keras.Model] = None,
                 hidden_layer_kld: dict = None,
                 w_model_hl: list = None,
                 temperature: float = 1.,
                 data_type: str = None) -> None:
        """
        Autoencoder (AE) based adversarial detector.

        Parameters
        ----------
        threshold
            Threshold used for adversarial score to determine adversarial instances.
        ae
            A trained tf.keras autoencoder model if available.
        model
            A trained tf.keras classification model.
        encoder_net
            Layers for the encoder wrapped in a tf.keras.Sequential class if no 'ae' is specified.
        decoder_net
            Layers for the decoder wrapped in a tf.keras.Sequential class if no 'ae' is specified.
        model_hl
            List with tf.keras models for the hidden layer K-L divergence computation.
        hidden_layer_kld
            Dictionary with as keys the hidden layer(s) of the model which are extracted and used
            during training of the AE, and as values the output dimension for the hidden layer.
        w_model_hl
            Weights assigned to the loss of each model in model_hl.
        temperature
            Temperature used for model prediction scaling.
            Temperature <1 sharpens the prediction probability distribution.
        data_type
            Optionally specifiy the data type (tabular, image or time-series). Added to metadata.
        """
        super().__init__()

        if threshold is None:
            logger.warning(
                'No threshold level set. Need to infer threshold using `infer_threshold`.'
            )

        self.threshold = threshold
        self.model = model
        for layer in self.model.layers:  # freeze model layers
            layer.trainable = False

        # check if model can be loaded, otherwise initialize AE model
        if isinstance(ae, tf.keras.Model):
            self.ae = ae
        elif isinstance(encoder_net, tf.keras.Sequential) and isinstance(
                decoder_net, tf.keras.Sequential):
            self.ae = AE(encoder_net, decoder_net)  # define AE model
        else:
            raise TypeError(
                'No valid format detected for `ae` (tf.keras.Model) '
                'or `encoder_net` and `decoder_net` (tf.keras.Sequential).')

        # intermediate feature map outputs for KLD and loss weights
        self.hidden_layer_kld = hidden_layer_kld
        if isinstance(model_hl, list):
            self.model_hl = model_hl
        elif isinstance(hidden_layer_kld, dict):
            self.model_hl = []
            for hidden_layer, output_dim in hidden_layer_kld.items():
                self.model_hl.append(
                    DenseHidden(self.model, hidden_layer, output_dim))
        else:
            self.model_hl = None
        self.w_model_hl = w_model_hl
        if self.w_model_hl is None and isinstance(self.model_hl, list):
            self.w_model_hl = list(np.ones(len(self.model_hl)))

        self.temperature = temperature

        # set metadata
        self.meta['detector_type'] = 'offline'
        self.meta['data_type'] = data_type
input_dim = 784
latent_dim = 50

encoder_net = tf.keras.Sequential([
    InputLayer(input_shape=(input_dim, )),
    Dense(128, activation=tf.nn.relu),
    Dense(latent_dim, activation=None)
])

decoder_net = tf.keras.Sequential([
    InputLayer(input_shape=(latent_dim, )),
    Dense(128, activation=tf.nn.relu),
    Dense(input_dim, activation=tf.nn.sigmoid)
])

ae = AE(encoder_net, decoder_net)
vae = VAE(encoder_net, decoder_net, latent_dim)
tests = [ae, vae]


@pytest.fixture
def tf_v_ae_mnist(request):
    # load and preprocess MNIST data
    (X_train, _), (X_test, _) = tf.keras.datasets.mnist.load_data()
    X = X_train.reshape(60000,
                        input_dim)[:1000]  # only train on 1000 instances
    X = X.astype(np.float32)
    X /= 255

    # init model, predict with untrained model, train and predict with trained model
    model = request.param
示例#5
0
        super(MyModel, self).__init__()
        self.dense = Dense(n_classes, activation='softmax')

    def call(self, x: np.ndarray) -> tf.Tensor:
        return self.dense(x)


model = MyModel()

encoder_net = tf.keras.Sequential(
    [InputLayer(input_shape=(n_features, )),
     Dense(latent_dim)])
decoder_net = tf.keras.Sequential(
    [InputLayer(input_shape=(latent_dim, )),
     Dense(n_features)])
AutoEncoder = AE(encoder_net, decoder_net)

# model, proba, return_class, shape
tests_predict = [(model, True, False, None), (model, False, True, None),
                 (model, False, False, (n, n_classes)),
                 (AutoEncoder, False, False, None),
                 (AutoEncoder, True, False, None)]
n_tests = len(tests_predict)


@pytest.fixture
def update_predict_batch(request):
    return tests_predict[request.param]


@pytest.mark.parametrize('update_predict_batch',
示例#6
0
def fetch_detector(filepath: str, detector_type: str, dataset: str,
                   detector_name: str, model=None):
    filepath = os.path.join(filepath, detector_name)
    if not os.path.isdir(filepath):
        logger.warning('Directory {} does not exist and is now created.'.format(filepath))
        os.mkdir(filepath)
    url = 'https://storage.googleapis.com/seldon-models/alibi-detect/'
    if detector_type == 'adversarial':
        url = os.path.join(url, 'ad', dataset, model, detector_name)
    elif detector_type == 'outlier':
        url = os.path.join(url, 'od', dataset, detector_name)
    # fetch and save metadata
    path_meta = os.path.join(url, 'meta.pickle')
    meta = cp.load(urlopen(path_meta))
    with open(os.path.join(filepath, 'meta.pickle'), 'wb') as f:
        pickle.dump(meta, f)
    # fetch and save state dict
    path_state = os.path.join(url, meta['name'] + '.pickle')
    state_dict = cp.load(urlopen(path_state))
    with open(os.path.join(filepath, meta['name'] + '.pickle'), 'wb') as f:
        pickle.dump(state_dict, f)
    # load detector
    url_models = os.path.join(url, 'model')
    model_path = os.path.join(filepath, 'model')
    if not os.path.isdir(model_path):
        os.mkdir(model_path)
    if meta['name'] == 'AdversarialAE':
        # encoder and decoder
        enc_path = tf.keras.utils.get_file(
            os.path.join(model_path, 'encoder_net.h5'),
            os.path.join(url_models, 'encoder_net.h5')
        )
        dec_path = tf.keras.utils.get_file(
            os.path.join(model_path, 'decoder_net.h5'),
            os.path.join(url_models, 'decoder_net.h5')
        )
        encoder_net = tf.keras.models.load_model(enc_path)
        decoder_net = tf.keras.models.load_model(dec_path)
        # classifier
        if dataset == 'cifar10' and model == 'resnet56':
            custom_objects = {'backend': backend}
        else:
            custom_objects = None
        clf_path = tf.keras.utils.get_file(
            os.path.join(model_path, 'model.h5'),
            os.path.join(url_models, 'model.h5')
        )
        clf = tf.keras.models.load_model(clf_path, custom_objects=custom_objects)
        # autoencoder
        ae = AE(encoder_net, decoder_net)
        # hidden layers
        hidden_layer_kld = state_dict['hidden_layer_kld']
        if isinstance(hidden_layer_kld, dict):
            model_hl = []
            for i, (hidden_layer, output_dim) in enumerate(hidden_layer_kld.items()):
                ckpt_tmp = 'model_hl_' + str(i) + '.ckpt.index'
                data_0_tmp = 'model_hl_' + str(i) + '.ckpt.data-00000-of-00002'
                data_1_tmp = 'model_hl_' + str(i) + '.ckpt.data-00001-of-00002'
                ckpt = tf.keras.utils.get_file(
                    os.path.join(model_path, ckpt_tmp),
                    os.path.join(url_models, ckpt_tmp)
                )
                data_0 = tf.keras.utils.get_file(  # noqa
                    os.path.join(model_path, data_0_tmp),
                    os.path.join(url_models, data_0_tmp)
                )
                data_1 = tf.keras.utils.get_file(  # noqa
                    os.path.join(model_path, data_1_tmp),
                    os.path.join(url_models, data_1_tmp)
                )
                m = DenseHidden(clf, hidden_layer, output_dim)
                m.load_weights(ckpt[:-6])
                model_hl.append(m)
        else:
            model_hl = None
        # adversarial detector
        detector = init_ad_ae(state_dict, ae, clf, model_hl)
    else:
        raise NotImplementedError
    return detector