عرض على TensorFlow.org | تشغيل في Google Colab | عرض المصدر على جيثب | تحميل دفتر |
يقدم هذا البرنامج التعليمي برامج التشفير التلقائية مع ثلاثة أمثلة: الأساسيات ، وتقليل التشويش من الصورة ، واكتشاف الشذوذ.
يعد التشفير التلقائي نوعًا خاصًا من الشبكات العصبية التي يتم تدريبها على نسخ مدخلاتها إلى مخرجاتها. على سبيل المثال ، بالنظر إلى صورة رقم مكتوب بخط اليد ، يقوم المشفر التلقائي أولاً بتشفير الصورة في تمثيل كامن ذو أبعاد أقل ، ثم يقوم بفك تشفير التمثيل الكامن إلى صورة ما. يتعلم المشفر التلقائي ضغط البيانات مع تقليل خطأ إعادة الإعمار.
لمعرفة المزيد حول أجهزة التشفير التلقائي ، يرجى قراءة الفصل 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
قم بتحميل مجموعة البيانات
للبدء ، ستقوم بتدريب برنامج التشفير التلقائي الأساسي باستخدام مجموعة بيانات Fashion MNIST. تبلغ كل صورة في مجموعة البيانات هذه 28 × 28 بكسل.
(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
، التي تعيد بناء الصورة الأصلية من الفضاء الكامن.
لتحديد النموذج الخاص بك ، استخدم Keras Model Subclassing API .
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()
المثال الثاني: تقليل ضوضاء الصورة
يمكن أيضًا تدريب وحدة التشفير التلقائي على إزالة الضوضاء من الصور. في القسم التالي ، ستقوم بإنشاء نسخة صاخبة من مجموعة بيانات Fashion MNIST عن طريق تطبيق ضوضاء عشوائية على كل صورة. ستقوم بعد ذلك بتدريب برنامج تشفير تلقائي باستخدام الصورة الصاخبة كمدخلات ، والصورة الأصلية كهدف.
دعنا نعيد استيراد مجموعة البيانات لحذف التعديلات التي تم إجراؤها مسبقًا.
(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()
حدد المشفر التلقائي التلافيفي
في هذا المثال ، ستقوم بتدريب المشفر التلقائي التلافيفي باستخدام طبقات Conv2D في encoder
، وطبقات Conv2DTranspose في decoder
.
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())
l10n-placeholder17 l10n-placeholder18l10n-placeholder18 l10n-placeholder16autoencoder.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>
دعنا نلقي نظرة على ملخص برنامج التشفير. لاحظ كيف يتم اختزال الصور من 28 × 28 إلى 7 × 7.
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 _________________________________________________________________
تقوم وحدة فك التشفير بتجميع عينات الصور من 7 × 7 إلى 28 × 28.
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 _________________________________________________________________
رسم كل من الصور المزعجة والصور منزوعة الضوضاء التي تنتجها وحدة التشفير التلقائي.
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 . تحتوي مجموعة البيانات هذه على 5000 مخطط كهربائي للقلب ، لكل منها 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 بواسطة Victor Dibia. بالنسبة لحالة الاستخدام في العالم الحقيقي ، يمكنك معرفة كيف تكتشف Airbus الحالات الشاذة في بيانات القياس عن بُعد لمحطة الفضاء الدولية باستخدام TensorFlow. لمعرفة المزيد حول الأساسيات ، ضع في اعتبارك قراءة منشور المدونة هذا بواسطة François Chollet. لمزيد من التفاصيل ، راجع الفصل 14 من التعلم العميق من تأليف إيان جودفيلو ويوشوا بنجيو وآرون كورفيل.