TensorFlow.org पर देखें | Google Colab में चलाएं | GitHub पर स्रोत देखें | नोटबुक डाउनलोड करें |
यह ट्यूटोरियल तीन उदाहरणों के साथ ऑटोएन्कोडर्स का परिचय देता है: मूल बातें, इमेज डीनोइज़िंग, और विसंगति का पता लगाना।
एक ऑटोएन्कोडर एक विशेष प्रकार का तंत्रिका नेटवर्क है जिसे इसके इनपुट को इसके आउटपुट में कॉपी करने के लिए प्रशिक्षित किया जाता है। उदाहरण के लिए, हस्तलिखित अंक की एक छवि को देखते हुए, एक ऑटोएन्कोडर पहले छवि को कम आयामी गुप्त प्रतिनिधित्व में एन्कोड करता है, फिर गुप्त प्रतिनिधित्व को एक छवि में वापस डीकोड करता है। एक ऑटोएन्कोडर पुनर्निर्माण त्रुटि को कम करते हुए डेटा को संपीड़ित करना सीखता है।
ऑटोएन्कोडर के बारे में अधिक जानने के लिए, कृपया इयान गुडफेलो, योशुआ बेंगियो और आरोन कौरविल द्वारा डीप लर्निंग से अध्याय 14 को पढ़ने पर विचार करें।
TensorFlow और अन्य पुस्तकालयों को आयात करें
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.metrics import accuracy_score, precision_score, recall_score
from sklearn.model_selection import train_test_split
from tensorflow.keras import layers, losses
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.models import Model
डेटासेट लोड करें
शुरू करने के लिए, आप फैशन एमएनआईएसटी डेटासेट का उपयोग करके मूल ऑटोएन्कोडर को प्रशिक्षित करेंगे। इस डेटासेट की प्रत्येक छवि 28x28 पिक्सेल की है।
(x_train, _), (x_test, _) = fashion_mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
print (x_train.shape)
print (x_test.shape)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step 40960/29515 [=========================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 0s 0us/step 26435584/26421880 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 16384/5148 [===============================================================================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step 4431872/4422102 [==============================] - 0s 0us/step (60000, 28, 28) (10000, 28, 28)
पहला उदाहरण: बेसिक ऑटोएन्कोडर
दो घने परतों के साथ एक ऑटोएन्कोडर को परिभाषित करें: एक encoder
, जो छवियों को 64 आयामी गुप्त वेक्टर में संपीड़ित करता है, और एक decoder
, जो अव्यक्त स्थान से मूल छवि का पुनर्निर्माण करता है।
अपने मॉडल को परिभाषित करने के लिए, केरस मॉडल सबक्लासिंग एपीआई का उपयोग करें।
latent_dim = 64
class Autoencoder(Model):
def __init__(self, latent_dim):
super(Autoencoder, self).__init__()
self.latent_dim = latent_dim
self.encoder = tf.keras.Sequential([
layers.Flatten(),
layers.Dense(latent_dim, activation='relu'),
])
self.decoder = tf.keras.Sequential([
layers.Dense(784, activation='sigmoid'),
layers.Reshape((28, 28))
])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
autoencoder = Autoencoder(latent_dim)
autoencoder.compile(optimizer='adam', loss=losses.MeanSquaredError())
इनपुट और लक्ष्य दोनों के रूप में x_train
का उपयोग करके मॉडल को प्रशिक्षित करें। encoder
डेटासेट को 784 आयामों से अव्यक्त स्थान पर संपीड़ित करना सीखेगा, और decoder
मूल छवियों को फिर से बनाना सीखेगा। .
autoencoder.fit(x_train, x_train,
epochs=10,
shuffle=True,
validation_data=(x_test, x_test))
Epoch 1/10 1875/1875 [==============================] - 4s 2ms/step - loss: 0.0243 - val_loss: 0.0140 Epoch 2/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0116 - val_loss: 0.0106 Epoch 3/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0100 - val_loss: 0.0098 Epoch 4/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0094 - val_loss: 0.0094 Epoch 5/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0092 - val_loss: 0.0092 Epoch 6/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0090 - val_loss: 0.0091 Epoch 7/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0090 - val_loss: 0.0090 Epoch 8/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0089 - val_loss: 0.0090 Epoch 9/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0088 - val_loss: 0.0089 Epoch 10/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0088 - val_loss: 0.0089 <keras.callbacks.History at 0x7ff1d35df550>
अब जब मॉडल प्रशिक्षित हो गया है, तो आइए परीक्षण सेट से छवियों को एन्कोडिंग और डिकोड करके इसका परीक्षण करें।
encoded_imgs = autoencoder.encoder(x_test).numpy()
decoded_imgs = autoencoder.decoder(encoded_imgs).numpy()
n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
# display original
ax = plt.subplot(2, n, i + 1)
plt.imshow(x_test[i])
plt.title("original")
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# display reconstruction
ax = plt.subplot(2, n, i + 1 + n)
plt.imshow(decoded_imgs[i])
plt.title("reconstructed")
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
दूसरा उदाहरण: छवि निरूपण
छवियों से शोर को दूर करने के लिए एक ऑटोएन्कोडर को भी प्रशिक्षित किया जा सकता है। निम्नलिखित अनुभाग में, आप प्रत्येक छवि पर यादृच्छिक शोर लागू करके फैशन एमएनआईएसटी डेटासेट का एक शोर संस्करण तैयार करेंगे। फिर आप शोर छवि का उपयोग इनपुट के रूप में और लक्ष्य के रूप में मूल छवि का उपयोग करके एक ऑटोएन्कोडर को प्रशिक्षित करेंगे।
आइए पहले किए गए संशोधनों को छोड़ने के लिए डेटासेट को फिर से आयात करें।
(x_train, _), (x_test, _) = fashion_mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]
print(x_train.shape)
(60000, 28, 28, 1)
छवियों में यादृच्छिक शोर जोड़ना
noise_factor = 0.2
x_train_noisy = x_train + noise_factor * tf.random.normal(shape=x_train.shape)
x_test_noisy = x_test + noise_factor * tf.random.normal(shape=x_test.shape)
x_train_noisy = tf.clip_by_value(x_train_noisy, clip_value_min=0., clip_value_max=1.)
x_test_noisy = tf.clip_by_value(x_test_noisy, clip_value_min=0., clip_value_max=1.)
शोर छवियों को प्लॉट करें।
n = 10
plt.figure(figsize=(20, 2))
for i in range(n):
ax = plt.subplot(1, n, i + 1)
plt.title("original + noise")
plt.imshow(tf.squeeze(x_test_noisy[i]))
plt.gray()
plt.show()
कन्वेन्शनल ऑटोएन्कोडर को परिभाषित करें
इस उदाहरण में, आप encoder
में Conv2D परतों का उपयोग करके एक दृढ़ ऑटोएन्कोडर को प्रशिक्षित करेंगे, और decoder
में Conv2DTranspose परतों का उपयोग करेंगे।
class Denoise(Model):
def __init__(self):
super(Denoise, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(16, (3, 3), activation='relu', padding='same', strides=2),
layers.Conv2D(8, (3, 3), activation='relu', padding='same', strides=2)])
self.decoder = tf.keras.Sequential([
layers.Conv2DTranspose(8, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2DTranspose(16, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2D(1, kernel_size=(3, 3), activation='sigmoid', padding='same')])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
autoencoder = Denoise()
autoencoder.compile(optimizer='adam', loss=losses.MeanSquaredError())
autoencoder.fit(x_train_noisy, x_train,
epochs=10,
shuffle=True,
validation_data=(x_test_noisy, x_test))
Epoch 1/10 1875/1875 [==============================] - 8s 3ms/step - loss: 0.0169 - val_loss: 0.0107 Epoch 2/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0095 - val_loss: 0.0086 Epoch 3/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0082 - val_loss: 0.0080 Epoch 4/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0078 - val_loss: 0.0077 Epoch 5/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0076 - val_loss: 0.0075 Epoch 6/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0074 - val_loss: 0.0074 Epoch 7/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0073 - val_loss: 0.0073 Epoch 8/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0072 - val_loss: 0.0072 Epoch 9/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0071 - val_loss: 0.0071 Epoch 10/10 1875/1875 [==============================] - 6s 3ms/step - loss: 0.0070 - val_loss: 0.0071 <keras.callbacks.History at 0x7ff1c45a31d0>
आइए एनकोडर के सारांश पर एक नज़र डालें। ध्यान दें कि कैसे छवियों को 28x28 से 7x7 तक घटाया जाता है।
autoencoder.encoder.summary()
Model: "sequential_2" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 14, 14, 16) 160 conv2d_1 (Conv2D) (None, 7, 7, 8) 1160 ================================================================= Total params: 1,320 Trainable params: 1,320 Non-trainable params: 0 _________________________________________________________________
डिकोडर छवियों को 7x7 से 28x28 तक वापस ऊपर ले जाता है।
autoencoder.decoder.summary()
Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_transpose (Conv2DTra (None, 14, 14, 8) 584 nspose) conv2d_transpose_1 (Conv2DT (None, 28, 28, 16) 1168 ranspose) conv2d_2 (Conv2D) (None, 28, 28, 1) 145 ================================================================= Total params: 1,897 Trainable params: 1,897 Non-trainable params: 0 _________________________________________________________________प्लेसहोल्डर22
ऑटोएन्कोडर द्वारा निर्मित शोर वाली छवियों और निरूपित छवियों दोनों को प्लॉट करना।
encoded_imgs = autoencoder.encoder(x_test).numpy()
decoded_imgs = autoencoder.decoder(encoded_imgs).numpy()
n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
# display original + noise
ax = plt.subplot(2, n, i + 1)
plt.title("original + noise")
plt.imshow(tf.squeeze(x_test_noisy[i]))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# display reconstruction
bx = plt.subplot(2, n, i + n + 1)
plt.title("reconstructed")
plt.imshow(tf.squeeze(decoded_imgs[i]))
plt.gray()
bx.get_xaxis().set_visible(False)
bx.get_yaxis().set_visible(False)
plt.show()
तीसरा उदाहरण: विसंगति का पता लगाना
अवलोकन
इस उदाहरण में, आप ECG5000 डेटासेट पर विसंगतियों का पता लगाने के लिए एक ऑटोएन्कोडर को प्रशिक्षित करेंगे। इस डेटासेट में 5,000 इलेक्ट्रोकार्डियोग्राम हैं, प्रत्येक में 140 डेटा बिंदु हैं। आप डेटासेट के सरलीकृत संस्करण का उपयोग करेंगे, जहां प्रत्येक उदाहरण को या तो 0
(असामान्य लय के अनुरूप) या 1
(सामान्य लय के अनुरूप) लेबल किया गया है। आप असामान्य लय की पहचान करने में रुचि रखते हैं।
ऑटोएन्कोडर का उपयोग करके आप विसंगतियों का पता कैसे लगाएंगे? याद रखें कि एक ऑटोएन्कोडर को पुनर्निर्माण त्रुटि को कम करने के लिए प्रशिक्षित किया जाता है। आप केवल सामान्य लय पर एक ऑटोएन्कोडर को प्रशिक्षित करेंगे, फिर इसका उपयोग सभी डेटा के पुनर्निर्माण के लिए करेंगे। हमारी परिकल्पना यह है कि असामान्य लय में उच्च पुनर्निर्माण त्रुटि होगी। फिर आप एक लय को एक विसंगति के रूप में वर्गीकृत करेंगे यदि पुनर्निर्माण त्रुटि एक निश्चित सीमा से अधिक हो जाती है।
ईसीजी डेटा लोड करें
आप जिस डेटासेट का उपयोग करेंगे, वह Timeseriesclassification.com में से एक पर आधारित है।
# Download the dataset
dataframe = pd.read_csv('http://storage.googleapis.com/download.tensorflow.org/data/ecg.csv', header=None)
raw_data = dataframe.values
dataframe.head()
# The last element contains the labels
labels = raw_data[:, -1]
# The other data points are the electrocadriogram data
data = raw_data[:, 0:-1]
train_data, test_data, train_labels, test_labels = train_test_split(
data, labels, test_size=0.2, random_state=21
)
डेटा को [0,1]
पर सामान्य करें।
min_val = tf.reduce_min(train_data)
max_val = tf.reduce_max(train_data)
train_data = (train_data - min_val) / (max_val - min_val)
test_data = (test_data - min_val) / (max_val - min_val)
train_data = tf.cast(train_data, tf.float32)
test_data = tf.cast(test_data, tf.float32)
आप केवल सामान्य लय का उपयोग करके ऑटोएन्कोडर को प्रशिक्षित करेंगे, जिन्हें इस डेटासेट में 1
के रूप में लेबल किया गया है। सामान्य लय को असामान्य लय से अलग करें।
train_labels = train_labels.astype(bool)
test_labels = test_labels.astype(bool)
normal_train_data = train_data[train_labels]
normal_test_data = test_data[test_labels]
anomalous_train_data = train_data[~train_labels]
anomalous_test_data = test_data[~test_labels]
एक सामान्य ईसीजी प्लॉट करें।
plt.grid()
plt.plot(np.arange(140), normal_train_data[0])
plt.title("A Normal ECG")
plt.show()
एक विषम ईसीजी प्लॉट करें।
plt.grid()
plt.plot(np.arange(140), anomalous_train_data[0])
plt.title("An Anomalous ECG")
plt.show()
मॉडल बनाएं
class AnomalyDetector(Model):
def __init__(self):
super(AnomalyDetector, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Dense(32, activation="relu"),
layers.Dense(16, activation="relu"),
layers.Dense(8, activation="relu")])
self.decoder = tf.keras.Sequential([
layers.Dense(16, activation="relu"),
layers.Dense(32, activation="relu"),
layers.Dense(140, activation="sigmoid")])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
autoencoder = AnomalyDetector()
autoencoder.compile(optimizer='adam', loss='mae')
ध्यान दें कि ऑटोएन्कोडर को केवल सामान्य ईसीजी का उपयोग करके प्रशिक्षित किया जाता है, लेकिन पूर्ण परीक्षण सेट का उपयोग करके मूल्यांकन किया जाता है।
history = autoencoder.fit(normal_train_data, normal_train_data,
epochs=20,
batch_size=512,
validation_data=(test_data, test_data),
shuffle=True)
Epoch 1/20 5/5 [==============================] - 1s 33ms/step - loss: 0.0576 - val_loss: 0.0531 Epoch 2/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0552 - val_loss: 0.0514 Epoch 3/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0519 - val_loss: 0.0499 Epoch 4/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0483 - val_loss: 0.0475 Epoch 5/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0445 - val_loss: 0.0451 Epoch 6/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0409 - val_loss: 0.0432 Epoch 7/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0377 - val_loss: 0.0415 Epoch 8/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0348 - val_loss: 0.0401 Epoch 9/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0319 - val_loss: 0.0388 Epoch 10/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0293 - val_loss: 0.0378 Epoch 11/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0273 - val_loss: 0.0369 Epoch 12/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0259 - val_loss: 0.0361 Epoch 13/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0249 - val_loss: 0.0354 Epoch 14/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0239 - val_loss: 0.0346 Epoch 15/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0230 - val_loss: 0.0340 Epoch 16/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0222 - val_loss: 0.0335 Epoch 17/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0215 - val_loss: 0.0331 Epoch 18/20 5/5 [==============================] - 0s 9ms/step - loss: 0.0211 - val_loss: 0.0331 Epoch 19/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0208 - val_loss: 0.0329 Epoch 20/20 5/5 [==============================] - 0s 8ms/step - loss: 0.0206 - val_loss: 0.0327
plt.plot(history.history["loss"], label="Training Loss")
plt.plot(history.history["val_loss"], label="Validation Loss")
plt.legend()
<matplotlib.legend.Legend at 0x7ff1d339b790>
यदि पुनर्निर्माण त्रुटि सामान्य प्रशिक्षण उदाहरणों से एक मानक विचलन से अधिक है, तो आप जल्द ही एक ईसीजी को विषम के रूप में वर्गीकृत करेंगे। सबसे पहले, आइए प्रशिक्षण सेट से एक सामान्य ईसीजी, ऑटोएन्कोडर द्वारा एन्कोड और डीकोड किए जाने के बाद पुनर्निर्माण, और पुनर्निर्माण त्रुटि की साजिश करें।
encoded_data = autoencoder.encoder(normal_test_data).numpy()
decoded_data = autoencoder.decoder(encoded_data).numpy()
plt.plot(normal_test_data[0], 'b')
plt.plot(decoded_data[0], 'r')
plt.fill_between(np.arange(140), decoded_data[0], normal_test_data[0], color='lightcoral')
plt.legend(labels=["Input", "Reconstruction", "Error"])
plt.show()
एक समान प्लॉट बनाएं, इस बार एक विषम परीक्षण उदाहरण के लिए।
encoded_data = autoencoder.encoder(anomalous_test_data).numpy()
decoded_data = autoencoder.decoder(encoded_data).numpy()
plt.plot(anomalous_test_data[0], 'b')
plt.plot(decoded_data[0], 'r')
plt.fill_between(np.arange(140), decoded_data[0], anomalous_test_data[0], color='lightcoral')
plt.legend(labels=["Input", "Reconstruction", "Error"])
plt.show()
विसंगतियों का पता लगाएं
पुनर्निर्माण हानि एक निश्चित सीमा से अधिक है या नहीं, इसकी गणना करके विसंगतियों का पता लगाएं। इस ट्यूटोरियल में, आप प्रशिक्षण सेट से सामान्य उदाहरणों के लिए औसत औसत त्रुटि की गणना करेंगे, फिर भविष्य के उदाहरणों को विषम के रूप में वर्गीकृत करेंगे यदि पुनर्निर्माण त्रुटि प्रशिक्षण सेट से एक मानक विचलन से अधिक है।
प्रशिक्षण सेट से सामान्य ईसीजी पर पुनर्निर्माण त्रुटि प्लॉट करें
reconstructions = autoencoder.predict(normal_train_data)
train_loss = tf.keras.losses.mae(reconstructions, normal_train_data)
plt.hist(train_loss[None,:], bins=50)
plt.xlabel("Train loss")
plt.ylabel("No of examples")
plt.show()
ऐसा थ्रेशोल्ड मान चुनें जो माध्य से एक मानक विचलन हो।
threshold = np.mean(train_loss) + np.std(train_loss)
print("Threshold: ", threshold)
Threshold: 0.03241627
यदि आप परीक्षण सेट में विषम उदाहरणों के लिए पुनर्निर्माण त्रुटि की जांच करते हैं, तो आप देखेंगे कि अधिकांश में थ्रेशोल्ड की तुलना में अधिक पुनर्निर्माण त्रुटि है। थ्रेशोल्ड को बदलकर, आप अपने क्लासिफायरियर की सटीकता और रिकॉल को समायोजित कर सकते हैं।
reconstructions = autoencoder.predict(anomalous_test_data)
test_loss = tf.keras.losses.mae(reconstructions, anomalous_test_data)
plt.hist(test_loss[None, :], bins=50)
plt.xlabel("Test loss")
plt.ylabel("No of examples")
plt.show()
एक ईसीजी को एक विसंगति के रूप में वर्गीकृत करें यदि पुनर्निर्माण त्रुटि सीमा से अधिक है।
def predict(model, data, threshold):
reconstructions = model(data)
loss = tf.keras.losses.mae(reconstructions, data)
return tf.math.less(loss, threshold)
def print_stats(predictions, labels):
print("Accuracy = {}".format(accuracy_score(labels, predictions)))
print("Precision = {}".format(precision_score(labels, predictions)))
print("Recall = {}".format(recall_score(labels, predictions)))
preds = predict(autoencoder, test_data, threshold)
print_stats(preds, test_labels)
Accuracy = 0.944 Precision = 0.9921875 Recall = 0.9071428571428571
अगले कदम
ऑटोएन्कोडर के साथ विसंगति का पता लगाने के बारे में अधिक जानने के लिए, विक्टर डिबिया द्वारा TensorFlow.js के साथ निर्मित इस उत्कृष्ट इंटरैक्टिव उदाहरण को देखें। वास्तविक दुनिया में उपयोग के मामले के लिए, आप सीख सकते हैं कि कैसे एयरबस TensorFlow का उपयोग करके ISS टेलीमेट्री डेटा में विसंगतियों का पता लगाता है । बुनियादी बातों के बारे में अधिक जानने के लिए, फ्रांकोइस चॉलेट द्वारा इस ब्लॉग पोस्ट को पढ़ने पर विचार करें। अधिक जानकारी के लिए, इयान गुडफेलो, योशुआ बेंगियो और आरोन कौरविल द्वारा डीप लर्निंग से अध्याय 14 देखें।