Back to Models
model_keras
v1.0.0
KerasLSTM Autoencoder for sequential and temporal anomaly detection. Uses Keras LSTM layers with RepeatVector architecture, treating features as time steps for sequence reconstruction.
$ openuba install model_keras OpenUBA
tensorflow
License: Apache-2.0
lstmautoencodersequentialtemporalkerasdeep-learning
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| epochs | integer | 5 | Number of training epochs |
| batch_size | integer | 32 | Training batch size |
model.yaml
1name: model_keras
2version: 1.0.0
3runtime: tensorflow
4description: LSTM Autoencoder for sequential anomaly detection
5parameters:
6 epochs:
7 type: integer
8 default: 5
9 description: Number of training epochs
10 batch_size:
11 type: integer
12 default: 32
13 description: Training batch size
14MODEL.py
1
2import pandas as pd
3import numpy as np
4from tensorflow import keras
5from tensorflow.keras import layers
6from typing import Dict, Any
7
8class Model:
9 def __init__(self):
10 self.model = None
11 self.input_dim = 10
12
13 def _build_model(self, input_dim):
14 """
15 Build a Keras LSTM-based Autoencoder (treating params as sequence for demo)
16 """
17 # Reshaping input to (features, 1) for LSTM
18 model = keras.Sequential([
19 layers.Input(shape=(input_dim, 1)),
20 layers.LSTM(16, activation='relu', return_sequences=False),
21 layers.RepeatVector(input_dim),
22 layers.LSTM(16, activation='relu', return_sequences=True),
23 layers.TimeDistributed(layers.Dense(1))
24 ])
25 model.compile(optimizer='adam', loss='mae')
26 return model
27
28 def train(self, ctx) -> Dict[str, Any]:
29 """
30 Train Keras model
31 """
32 ctx.logger.info("Starting Keras LSTM training...")
33
34 if ctx.df is None or ctx.df.empty:
35 ctx.logger.warning("No data, generating dummy")
36 X = np.random.randn(100, 10).astype(np.float32)
37 else:
38 X = ctx.df.select_dtypes(include=[np.number]).values.astype(np.float32)
39
40 self.input_dim = X.shape[1]
41
42 # Reshape for LSTM: [samples, time_steps, features] -> treating features as time steps here for structural demo
43 X_reshaped = X.reshape((X.shape[0], X.shape[1], 1))
44
45 self.model = self._build_model(self.input_dim)
46
47 history = self.model.fit(X_reshaped, X_reshaped, epochs=5, batch_size=32, verbose=0)
48 final_loss = history.history['loss'][-1]
49
50 ctx.logger.info(f"Training completed. Final MAE: {final_loss}")
51
52 return {
53 "status": "success",
54 "model_type": "Keras LSTM Autoencoder",
55 "final_loss": float(final_loss)
56 }
57
58 def infer(self, ctx) -> pd.DataFrame:
59 """
60 Inference
61 """
62 ctx.logger.info("Starting Keras inference...")
63
64 if ctx.df is None or ctx.df.empty:
65 X = np.random.randn(20, self.input_dim).astype(np.float32)
66 ids = [f"user_{i}" for i in range(20)]
67 else:
68 X = ctx.df.select_dtypes(include=[np.number]).values.astype(np.float32)
69 if X.shape[1] != self.input_dim:
70 # simple truncation/padding
71 if X.shape[1] > self.input_dim:
72 X = X[:, :self.input_dim]
73 else:
74 padding = np.zeros((X.shape[0], self.input_dim - X.shape[1]), dtype=np.float32)
75 X = np.hstack((X, padding))
76
77 if "entity_id" in ctx.df.columns:
78 ids = ctx.df["entity_id"].values
79 else:
80 ids = [f"entity_{i}" for i in range(len(X))]
81
82 if self.model is None:
83 self.model = self._build_model(self.input_dim)
84
85 X_reshaped = X.reshape((X.shape[0], X.shape[1], 1))
86 reconstructions = self.model.predict(X_reshaped, verbose=0)
87 reconstructions = reconstructions.reshape((X.shape[0], X.shape[1]))
88
89 mae = np.mean(np.abs(X - reconstructions), axis=1)
90
91 results = []
92 for i, score in enumerate(mae):
93 risk = min(100.0, float(score) * 100)
94 results.append({
95 "entity_id": str(ids[i]),
96 "risk_score": float(risk),
97 "anomaly_type": "seq_outlier" if risk > 50 else "normal",
98 "details": {"mae": float(score)}
99 })
100
101 return pd.DataFrame(results)
102
103 def execute(self, data=None):
104 # shim for v1
105 class MockCtx:
106 def __init__(self, d): self.df = d if d else pd.DataFrame(); self.logger = type('obj', (object,), {'info': print, 'warning': print})
107 return self.infer(MockCtx(pd.DataFrame(data) if data else None)).to_dict('records')
108