Кластеризація/[Несупервізовані алгоритми машинного навчання] є ефективним способом виявлення організації даних по відношенню один до одного, таких як подібні (внутрішні елементи) та різні (викинуті елементи) значення даних.
Однак є й інші способи виявлення подібних і різних даних за допомогою моделей глибокого навчання. Моделі глибокого навчання можуть змінювати дані, а потім реконструювати лише важливу інформацію про ці дані. Цей процес дозволяє видаляти різні (викинуті елементи) дані, залишаючи лише подібні (внутрішні елементи) після реконструкції.
У цьому пості демонструються кілька моделей глибокого навчання, які можуть фільтрувати викинуті дані. Конфігурації моделей називаються автоенкодерами, і вони зазвичай використовуються для обробки зображень (наприклад, трансляція зображень і генерація зображень). Вони перетворюють вхідний сигнал або зображення у бажаний вихідний сигнал або зображення відповідно.
Модель 0
У цій конфігурації моделі використовується шар timeDistributed для перетворення виходу шару lstm3 у стовпчиковий масив.
// npm install @tensorflow/tfjs
const tf = require('@tensorflow/tfjs');
const timesteps = 1000;
const feature_num = 1;
const input = tf.input({shape: [timesteps, feature_num]});
console.log("input shape: ", JSON.stringify(input.shape));
const lstm0 = tf.layers.lstm({units: 32, activation: 'relu', inputShape: [timesteps, feature_num], returnSequences: true });
const input_lstm0 = lstm0.apply(input);
console.log("input_lstm0 shape: ", JSON.stringify(input_lstm0.shape));
const lstm1 = tf.layers.lstm({units: 16, activation: 'relu', returnSequences: false });
const input_l0_l1 = lstm1.apply(input_lstm0);
console.log("input_l0_l1 shape: ", JSON.stringify(input_l0_l1.shape));
const rv = tf.layers.repeatVector({n: timesteps});
const input_l0_l1_rv = rv.apply(input_l0_l1);
console.log("input_l0_l1_rv shape: ", JSON.stringify(input_l0_l1_rv.shape));
const lstm2 = tf.layers.lstm({units: 16, activation: 'relu', returnSequences: true});
const input_l0_l1_rv_l2 = lstm2.apply(input_l0_l1_rv);
console.log("input_l0_l1_rv_l2 shape: ", JSON.stringify(input_l0_l1_rv_l2.shape));
const lstm3 = tf.layers.lstm({units: 32, activation: 'relu', returnSequences: true});
const input_l0_l1_rv_l2_l3 = lstm3.apply(input_l0_l1_rv_l2);
console.log("input_l0_l1_rv_l2_l3 shape: ", JSON.stringify(input_l0_l1_rv_l2_l3.shape));
// returnSequences=false має бути встановлено на останньому шарі lstm, щоб зменшити [timesteps, 32] до timesteps=1000.
// Можна використати додатковий шар dense або використовувати input_l0_l1_rv_l2_l3 безпосередньо як вихід.
// const dense0 = tf.layers.dense({units: 1000});
// АБО
// Застосувати dense-шар до кожного з 1000 timesteps незалежно.
// Якщо returnSequences=true на останньому шарі lstm, повертаються значення 1000 timesteps
const dense0 = tf.layers.timeDistributed({ layer: tf.layers.dense({units: 1}) });
const output = dense0.apply(input_l0_l1_rv_l2_l3);
console.log("output shape: ", JSON.stringify(output.shape));
const model = tf.model({inputs: input, outputs: output});
model.compile({optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError, metrics: ['mse']});
Модель 1
У цій конфігурації моделі вихід lstm3 виводиться безпосередньо як рядковий масив.
// npm install @tensorflow/tfjs
const tf = require('@tensorflow/tfjs');
const timesteps = 1000;
const feature_num = 1;
const input = tf.input({shape: [timesteps, feature_num]});
console.log("input shape: ", JSON.stringify(input.shape));
const lstm0 = tf.layers.lstm({units: 32, activation: 'relu', inputShape: [timesteps, feature_num], returnSequences: true });
const input_lstm0 = lstm0.apply(input);
console.log("input_lstm0 shape: ", JSON.stringify(input_lstm0.shape));
const lstm1 = tf.layers.lstm({units: 16, activation: 'relu', returnSequences: false });
const input_l0_l1 = lstm1.apply(input_lstm0);
console.log("input_l0_l1 shape: ", JSON.stringify(input_l0_l1.shape));
const rv = tf.layers.repeatVector({n: timesteps});
const input_l0_l1_rv = rv.apply(input_l0_l1);
console.log("input_l0_l1_rv shape: ", JSON.stringify(input_l0_l1_rv.shape));
const lstm2 = tf.layers.lstm({units: 16, activation: 'relu', returnSequences: true});
const input_l0_l1_rv_l2 = lstm2.apply(input_l0_l1_rv);
console.log("input_l0_l1_rv_l2 shape: ", JSON.stringify(input_l0_l1_rv_l2.shape));
const lstm3 = tf.layers.lstm({units: 32, activation: 'relu', returnSequences: false});
const output = lstm3.apply(input_l0_l1_rv_l2);
console.log("output shape: ", JSON.stringify(output.shape));
const model = tf.model({inputs: input, outputs: output});
model.compile({optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError, metrics: ['mse']});
Далі, введіть відповідні дані в модель для фільтрації даних.
Введення даних у модель і навчання моделі для двох випадків: контрольованого та неконтрольованого
const Y = Array.from({length: 1000}, (val, ind) => { return 1; });
const n_index = [60, 95, 589, 955];
var X = [];
var c=0;
for (var i=0; i { return [v]; });
// const Ycol = Y.map((v,i) => { return [v]; });
// const X_tf = tf.tensor(Xcol);
// const Y_tf = tf.tensor(Ycol);
Контрольований випадок
У цьому випадку модель навчається за допомогою Xtf для X та Ytf для Y (X без викинутих елементів). Модель навчається виводити “тип даних X” без викинутих елементів.
// Навчання моделі передбачити Y, масив без викинутих елементів.
const history = model.fit(X_tf, Y_tf, {epochs: 100});
console.log("history: ", history);
const result = model.predict(X_tf);
const out = result.data();
console.log("out: ", out);
Неконтрольований випадок
У цьому випадку модель навчається, використовуючи X_tf для X та Y. Модель буде навчатися передбачати “тип даних X”/саму себе.
Перетворення шарів нейронної мережі фільтрує викинуті дані, оскільки їх мало; вона реконструює внутрішні/типові дані, що представляють X.
// Виявлення викинутих елементів
const history = model.fit(X_tf, X_tf, {epochs: 100});
console.log("history: ", history);
const result = model.predict(X_tf);
const out = result.data();
console.log("out: ", out);
Викинуті дані мають бути зменшені в реконструйованому виході, як сигнал, оброблений через фільтр низьких частот.
Відніміть вхід X від реконструйованого X, щоб побачити викинуті елементи!
Бажаю удачі та приємних практик! 👋
💻 GitHub | 🔔 Підписатись на Practicing Datscy @ Medium | 🌷 Practicing Datscy @ Dev.to
Посилання
- Виявлення аномалій в часових рядах за допомогою Python (Натхнення для цього блогу) — https://levelup.gitconnected.com/anomaly-detection-in-time-series-data-with-python-5a15089636db
Перекладено з: Deep Learning models that detect similar and disimilar data-points