def load_tf_s2s(filepath: str, state_dict: Dict) -> tf.keras.Model: model_dir = os.path.join(filepath, 'model') if not [f for f in os.listdir(model_dir) if not f.startswith('.')]: logger.warning('No seq2seq or threshold estimation net found in {}.'.format(model_dir)) return None # load threshold estimator net, initialize encoder and decoder and load seq2seq weights threshold_net = tf.keras.models.load_model(os.path.join(model_dir, 'threshold_net.h5'), compile=False) latent_dim = state_dict['latent_dim'] n_features = state_dict['shape'][-1] encoder_net = EncoderLSTM(latent_dim) decoder_net = DecoderLSTM(latent_dim, n_features, state_dict['output_activation']) seq2seq = Seq2Seq(encoder_net, decoder_net, threshold_net, n_features, beta=state_dict['beta']) seq2seq.load_weights(os.path.join(model_dir, 'seq2seq.ckpt')) return seq2seq
def __init__(self, n_features: int, seq_len: int, threshold: Union[float, np.ndarray] = None, seq2seq: tf.keras.Model = None, threshold_net: tf.keras.Sequential = None, latent_dim: int = None, output_activation: str = None, beta: float = 1.) -> None: """ Seq2Seq-based outlier detector. Parameters ---------- n_features Number of features in the time series. seq_len Sequence length fed into the Seq2Seq model. threshold Threshold used for outlier detection. Can be a float or feature-wise array. seq2seq A trained seq2seq model if available. threshold_net Layers for the threshold estimation network wrapped in a tf.keras.Sequential class if no 'seq2seq' is specified. latent_dim Latent dimension of the encoder and decoder. output_activation Activation used in the Dense output layer of the decoder. beta Weight on the threshold estimation loss term. """ super().__init__() if threshold is None: threshold = 0. logger.warning( 'No explicit threshold level set. Threshold defaults to 0. ' 'A threshold can be inferred using `infer_threshold`.') self.threshold = threshold self.shape = (-1, seq_len, n_features) self.latent_dim = latent_dim self.output_activation = output_activation if threshold_net is None and seq2seq is None: # default threshold network threshold_net = tf.keras.Sequential([ InputLayer(input_shape=(seq_len, latent_dim)), Dense(64, activation=tf.nn.relu), Dense(64, activation=tf.nn.relu), ]) # check if model can be loaded, otherwise initialize a Seq2Seq model if isinstance(seq2seq, tf.keras.Model): self.seq2seq = seq2seq elif isinstance(latent_dim, int) and isinstance( threshold_net, tf.keras.Sequential): encoder_net = EncoderLSTM(latent_dim) decoder_net = DecoderLSTM(latent_dim, n_features, output_activation) self.seq2seq = Seq2Seq(encoder_net, decoder_net, threshold_net, n_features, beta=beta) else: raise TypeError( 'No valid format detected for `seq2seq` (tf.keras.Model), ' '`latent_dim` (int) or `threshold_net` (tf.keras.Sequential)') # set metadata self.meta['detector_type'] = 'offline' self.meta['data_type'] = 'time-series'
assert z.shape[1] == latent_dim + 2 assert gamma.shape[1] == n_gmm model_weights = model.weights[1].numpy().copy() trainer(model, loss_fn, X, epochs=5, verbose=False, batch_size=1000) assert (model_weights != model.weights[1].numpy()).any() @pytest.mark.parametrize('tf_v_aegmm_mnist', list(range(n_tests)), indirect=True) def test_aegmm_vaegmm(tf_v_aegmm_mnist): pass seq_len = 10 tests_seq2seq = [(DecoderLSTM(latent_dim, 1, None), 1), (DecoderLSTM(latent_dim, 2, None), 2)] n_tests = len(tests_seq2seq) @pytest.fixture def tf_seq2seq_sine(request): # create artificial sine time series X = np.sin(np.linspace(-50, 50, 10000)).astype(np.float32) # init model decoder_net_, n_features = tests_seq2seq[request.param] encoder_net = EncoderLSTM(latent_dim) threshold_net = tf.keras.Sequential([ InputLayer(input_shape=(seq_len, latent_dim)), Dense(10, activation=tf.nn.relu)