Auto-encoder

seongyong·2021년 6월 25일
0

컴퓨터 비전

목록 보기
2/3

학습내용

Autoencoder(AE)

인코더, Latent representation, 디코더를 갖는 형태이며 인코더에 데이터가 입력되면 Latent representation에 특징들이 추출되고 디코더에서 Latent representation이 잘 추출되었는지 확인하는 과정을 거친다.

입력데이터 자체를 레이블로 활용하는 학습방식으로 비지도학습에 속한다.

인코더를 통해 입력데이터에서 중요한 의미를 갖는 신호 외의 '노이즈'를 제거하도록 훈련되고, 여기서 코딩된 코드영역을 Latent representation이라고 부르게 된다.

AE의 Latent representation은 데이터의 정보량이 담기기 때문에, AE를 생성 모델적 접근 방식에서도 중요한 부분으로 다뤄진다.

Stacked AE

Stacked AE는 AE와 다르게 layer마다 input, output을 비교하여 학습하는 방식이다.

AE는 encoder, latend representation, decoder의 학습이 동시에 이뤄지지만 층이 깊어지면 동작이 제대로 안될 수 있다는 단점이있다. 이를 보완하고자 Stacked AE를 사용한다.

실습

1. 기본 오토인코더

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
(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)
# Code영역의 벡터(= Latent vector)의 수 정의
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
  
# decoded된 데이터를 output으로 설정함
autoencoder = Autoencoder(latent_dim)

2. 노이즈 제거 오토인코더(CNN, conv Transpose 사용)

# CNN의 형태를 갖는 autoencoder 코드
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()

3. 정상 데이터 학습 후 이상현상 발견 용 오토인코더

# 데이터셋을 불러옵니다. 
dataframe = pd.read_csv('http://storage.googleapis.com/download.tensorflow.org/data/ecg.csv', header=None)
raw_data = dataframe.values
dataframe.head()
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)
#train loss의 분포파악
reconstructions = autoencoder.predict(normal_train_data)
train_loss = tf.keras.losses.mae(reconstructions, normal_train_data)

plt.hist(train_loss, bins=50)
plt.xlabel("Train loss")
plt.ylabel("No of examples")
plt.show()
#평균으로부터 표준편차만큼 떨어진 곳을 threshold로 설정
threshold = np.mean(train_loss) + np.std(train_loss)
print("Threshold: ", threshold)
#Threshold를 통해 performance 확인 함수 정의
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, preds)))
  print("Precision = {}".format(precision_score(labels, preds)))
  print("Recall = {}".format(recall_score(labels, preds)))
#확인
preds = predict(autoencoder, test_data, threshold)
print_stats(preds, test_labels)

0개의 댓글