Yardım Kaggle üzerinde TensorFlow ile Büyük Bariyer Resifi korumak Meydan Üyelik

Otomatik Kodlayıcılara Giriş

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Bu öğretici, otomatik kodlayıcıları üç örnekle tanıtır: temel bilgiler, görüntü gürültü giderme ve anormallik algılama.

Otomatik kodlayıcı, girdisini çıktısına kopyalamak üzere eğitilmiş özel bir sinir ağı türüdür. Örneğin, elle yazılmış bir rakamın bir görüntüsü verildiğinde, bir otomatik kodlayıcı önce görüntüyü daha düşük boyutlu bir gizli gösterime kodlar, ardından gizli gösterimin kodunu tekrar bir görüntüye dönüştürür. Bir otomatik kodlayıcı, yeniden oluşturma hatasını en aza indirirken verileri sıkıştırmayı öğrenir.

Autoencoders hakkında daha fazla bilgi edinmek için gelen bölüm 14 okuma düşünün lütfen Derin Öğrenme Ian Goodfellow, Yoshua Bengio ve Aaron Courville tarafından.

TensorFlow ve diğer kitaplıkları içe aktarın

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

Veri kümesini yükleyin

Başlamak için, Fashon MNIST veri setini kullanarak temel otomatik kodlayıcıyı eğiteceksiniz. Bu veri setindeki her görüntü 28x28 pikseldir.

(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)
(60000, 28, 28)
(10000, 28, 28)

İlk örnek: Temel otomatik kodlayıcı

Temel otomatik kodlayıcı sonuçları

Bir: iki yoğun tabakalar bir autoencoder tanımlama encoder 64 boyutlu gizli vektörüne görüntüleri sıkıştırır, ve bir decoder gizli alan orijinal görüntüyü yeniden yapılandırır.

Modelinizi tanımlamak için kullanmak Keras Modeli 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())

Kullanarak modeli Train x_train giriş ve hedefin hem de. encoder gizli uzaya 784 boyutlardan veri kümesi sıkıştırmak için öğreneceksiniz ve decoder orijinal görüntüleri yeniden öğrenecektir. .

autoencoder.fit(x_train, x_train,
                epochs=10,
                shuffle=True,
                validation_data=(x_test, x_test))
Epoch 1/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.0237 - val_loss: 0.0131
Epoch 2/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0115 - val_loss: 0.0105
Epoch 3/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0100 - val_loss: 0.0097
Epoch 4/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0094 - val_loss: 0.0095
Epoch 5/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0092 - val_loss: 0.0091
Epoch 6/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0090 - val_loss: 0.0091
Epoch 7/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0089 - val_loss: 0.0090
Epoch 8/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0088 - val_loss: 0.0089
Epoch 9/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0088 - val_loss: 0.0089
Epoch 10/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0087 - val_loss: 0.0088
<tensorflow.python.keras.callbacks.History at 0x7ff99c0d3a10>

Artık model eğitildiğine göre, test setinden görüntüleri kodlayarak ve kodunu çözerek test edelim.

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()

png

İkinci örnek: Görüntü gürültü giderme

Görüntü gürültü giderme sonuçları

Bir otomatik kodlayıcı, görüntülerdeki paraziti gidermek için de eğitilebilir. Aşağıdaki bölümde, her bir görüntüye rastgele gürültü uygulayarak Fashion MNIST veri setinin gürültülü bir versiyonunu oluşturacaksınız. Ardından, giriş olarak gürültülü görüntüyü ve hedef olarak orijinal görüntüyü kullanarak bir otomatik kodlayıcı eğiteceksiniz.

Daha önce yapılan değişiklikleri atlamak için veri kümesini yeniden içe aktaralım.

(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)

Görüntülere rastgele gürültü ekleme

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.)

Gürültülü görüntüleri çizin.

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()

png

Bir evrişimli otomatik kodlayıcı tanımlayın

Bu örnekte, kıvrımlı bir kullanarak autoencoder eğitecek Conv2D katmanları encoder ve Conv2DTranspose katmanları 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()
WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is intended to be used by Functional model.
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 [==============================] - 6s 3ms/step - loss: 0.0165 - val_loss: 0.0100
Epoch 2/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0094 - val_loss: 0.0089
Epoch 3/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0083 - val_loss: 0.0081
Epoch 4/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0078 - val_loss: 0.0077
Epoch 5/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0076 - val_loss: 0.0075
Epoch 6/10
1875/1875 [==============================] - 5s 2ms/step - loss: 0.0074 - val_loss: 0.0074
Epoch 7/10
1875/1875 [==============================] - 5s 2ms/step - loss: 0.0073 - val_loss: 0.0073
Epoch 8/10
1875/1875 [==============================] - 5s 2ms/step - loss: 0.0072 - val_loss: 0.0073
Epoch 9/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0071 - val_loss: 0.0072
Epoch 10/10
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0071 - val_loss: 0.0071
<tensorflow.python.keras.callbacks.History at 0x7ff99ee2a810>

Kodlayıcının bir özetine bir göz atalım. Görüntülerin 28x28'den 7x7'ye nasıl altörneklendiğine dikkat edin.

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
_________________________________________________________________

Kod çözücü, görüntüleri 7x7'den 28x28'e yükseltir.

autoencoder.decoder.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_transpose (Conv2DTran (None, 14, 14, 8)         584       
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 28, 28, 16)        1168      
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 28, 28, 1)         145       
=================================================================
Total params: 1,897
Trainable params: 1,897
Non-trainable params: 0
_________________________________________________________________

Otomatik kodlayıcı tarafından üretilen hem gürültülü görüntülerin hem de gürültü giderilmiş görüntülerin çizilmesi.

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()

png

Üçüncü örnek: Anormallik algılama

genel bakış

Bu örnekte, ilgili anormallikleri tespit etmek için autoencoder eğitim verecek ECG5000 veri kümesi . Bu veri seti 5000 içeren elektrokardiyogram , 140 veri noktası ile, her. Her örnek, ya etiketlenmiş veri kümesi, basitleştirilmiş bir versiyonu kullanır 0 (anormal ritmin karşılık gelir), ya da 1 (normal ritme karşılık gelir). Anormal ritimleri tanımlamakla ilgileniyorsunuz.

Bir otomatik kodlayıcı kullanarak anormallikleri nasıl tespit edeceksiniz? Bir otomatik kodlayıcının yeniden yapılandırma hatasını en aza indirmek için eğitildiğini hatırlayın. Bir otomatik kodlayıcıyı yalnızca normal ritimler üzerinde eğitecek, ardından tüm verileri yeniden oluşturmak için kullanacaksınız. Hipotezimiz, anormal ritimlerin daha yüksek yeniden yapılandırma hatasına sahip olacağıdır. Daha sonra, yeniden oluşturma hatası sabit bir eşiği aşarsa, bir ritmi anormallik olarak sınıflandırırsınız.

EKG verilerini yükle

Kullanacağınız veri kümesi dan biri dayanmaktadır 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
)

İçin verilerin normalleştirilmesi [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)

Sadece bu veri kümesindeki etiketli, normal ritimler kullanılarak autoencoder eğitecek 1 . Normal ritimleri anormal ritimlerden ayırın.

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]

Normal bir EKG çizin.

plt.grid()
plt.plot(np.arange(140), normal_train_data[0])
plt.title("A Normal ECG")
plt.show()

png

Anormal bir EKG çizin.

plt.grid()
plt.plot(np.arange(140), anomalous_train_data[0])
plt.title("An Anomalous ECG")
plt.show()

png

Modeli oluşturun

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')

Otomatik kodlayıcının yalnızca normal EKG'ler kullanılarak eğitildiğine, ancak tam test seti kullanılarak değerlendirildiğine dikkat edin.

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 [==============================] - 0s 25ms/step - loss: 0.0611 - val_loss: 0.0545
Epoch 2/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0568 - val_loss: 0.0523
Epoch 3/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0547 - val_loss: 0.0508
Epoch 4/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0524 - val_loss: 0.0490
Epoch 5/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0495 - val_loss: 0.0472
Epoch 6/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0460 - val_loss: 0.0461
Epoch 7/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0428 - val_loss: 0.0451
Epoch 8/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0397 - val_loss: 0.0432
Epoch 9/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0364 - val_loss: 0.0414
Epoch 10/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0337 - val_loss: 0.0403
Epoch 11/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0315 - val_loss: 0.0394
Epoch 12/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0297 - val_loss: 0.0385
Epoch 13/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0282 - val_loss: 0.0378
Epoch 14/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0270 - val_loss: 0.0372
Epoch 15/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0261 - val_loss: 0.0366
Epoch 16/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0252 - val_loss: 0.0361
Epoch 17/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0245 - val_loss: 0.0355
Epoch 18/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0238 - val_loss: 0.0350
Epoch 19/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0232 - val_loss: 0.0347
Epoch 20/20
5/5 [==============================] - 0s 6ms/step - loss: 0.0227 - val_loss: 0.0342
plt.plot(history.history["loss"], label="Training Loss")
plt.plot(history.history["val_loss"], label="Validation Loss")
plt.legend()
<matplotlib.legend.Legend at 0x7ff99f02ea10>

png

Yeniden yapılandırma hatası normal eğitim örneklerinden bir standart sapmadan büyükse, yakında bir EKG'yi anormal olarak sınıflandıracaksınız. İlk olarak, eğitim setinden normal bir EKG çizelim, otomatik kodlayıcı tarafından kodlanıp kodu çözüldükten sonra yeniden yapılandırma ve yeniden oluşturma hatası.

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()

png

Bu sefer anormal bir test örneği için benzer bir arsa oluşturun.

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()

png

Anormallikleri tespit edin

Yeniden yapılandırma kaybının sabit bir eşikten büyük olup olmadığını hesaplayarak anormallikleri tespit edin. Bu öğreticide, eğitim setinden normal örnekler için ortalama hatayı hesaplayacak, ardından yeniden oluşturma hatası eğitim setinden bir standart sapmadan yüksekse gelecekteki örnekleri anormal olarak sınıflandıracaksınız.

Eğitim setinden normal EKG'lerde yeniden yapılandırma hatasını çizin

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()

png

Ortalamanın bir standart sapma üzerinde olan bir eşik değeri seçin.

threshold = np.mean(train_loss) + np.std(train_loss)
print("Threshold: ", threshold)
Threshold:  0.034232758

Test setindeki anormal örnekler için yeniden oluşturma hatasını incelerseniz, çoğunun eşikten daha büyük yeniden yapılandırma hatası olduğunu fark edeceksiniz. Eşiği varing ederek, ayarlayabilirsiniz hassasiyet ve hatırlama Sınıflandırıcınıza arasında.

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()

png

Yeniden yapılandırma hatası eşikten büyükse bir EKG'yi anomali olarak sınıflandırın.

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.943
Precision = 0.9921722113502935
Recall = 0.9053571428571429

Sonraki adımlar

Bu mükemmel göz atın autoencoders ile anomali tespiti hakkında daha fazla bilgi edinmek için etkileşimli örnek Victor Dibia tarafından TensorFlow.js ile inşa. Bir gerçek dünya kullanım durumunda için, öğrenebilirsiniz ISS Telemetri Veri Airbus algılar Anomaliler TensorFlow kullanarak. Temelleri hakkında daha fazla bilgi edinmek için bu okuma düşünün blog yazısı François CHOLLET tarafından. Daha fazla ayrıntı için gelen bölüm 14 kontrol Derin Öğrenme Ian Goodfellow, Yoshua Bengio ve Aaron Courville.