본문 바로가기
Daily Review

Autoencoder를 활용한 이미지 이상 탐지

by data-analyst-luke 2022. 8. 31.
반응형

Deep Convolutional Autoencoder를 탐색하여 이미지의 이상을 식별합니다.

이 글은 MNIST 및 Fashion MNIST에서 이미지 이상 감지에 Deep Convolutional Autoencoder를 사용할 수 있는지 확인하기 위한 실험적 작업입니다.

 

Autoencoder 간단 요약

기능: Autoencoder는 중요한 잠재 기능 표현을 식별하기 위해 입력을 인코딩합니다..그런 다음 잠재 기능을 디코딩하여 입력 값과 동일한 출력 값을 재구성합니다.

목적: Autoencoder의 목적은 입력과 출력 사이의 재구성 오류를 최소화하는 것입니다. 이는 자동 인코더가 데이터에 있는 중요한 기능을 학습하는 데 도움이 됩니다.

아키텍처: Autoencoder는 Encoder 네트워크와 Decoder 네트워크로 구성됩니다. 인코더는 고차원 입력을 병목 계층이라고도 하는 저차원 잠재 표현으로 인코딩합니다. 디코더는 이 저차원 잠재 표현을 취하고 원래 입력을 재구성합니다.

 

사용법 : Autoencoder는 다음을 위해 사용됩니다.

  • 차원 축소
  • 특징 추출기
  • 노이즈 제거 이미지
  • 이미지 인식 및 의미론적 분할
  • 추천 엔진

여기서는 Tensorflow 2.3 및 Fashion MNIST 데이터 세트를 사용합니다.

이미지 이상을 식별하기 위해 아래 아키텍처를 사용합니다.

 

 

인코더는 입력 데이터를 잠재 표현으로 압축합니다. 디코더는 인코딩된 잠재 표현을 압축 해제하여 입력 데이터를 재구성합니다. 원래 입력과 재구성된 입력 사이의 손실은 SSIM 손실 함수를 사용하여 측정됩니다. 입력이 훈련된 데이터 세트의 이미지에 속하면 재구성 손실이 더 작고 이상이 있으면 재구성 손실이 높습니다.

SSIM은 두 이미지 간의 유사도를 측정하는 데 사용되는 Structuralsimilarity Index Measure입니다 . SSIM 값은 -1과 1 사이입니다.

 

두 이미지가 유사하면 SSIM 값이 더 큽니다.

 

이미지 이상에 대해서는 SSIM 손실 함수를 사용합니다. 유사한 이미지의 경우 SSIM 손실 함수가 더 작고 비정상 이미지의 경우 SSIM 손실 함수가 커집니다.

 

필요한 라이브러리 가져오기

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

 

Fashion MNIST 훈련 및 테스트 데이터 세트를 로드하고 (28, 28,1)로 정규화 및 변형합니다.

(x_train, _), (x_test, _) = fashion_mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))

 

인코더 및 디코더 생성

인코더에서 입력 데이터를 잠재적 표현으로 압축합니다. 디코더는 입력 데이터를 재생성하기 위해 잠재 표현을 압축 해제합니다.

# Create the Encoder and Decoder
#pass the gray scale input image of size(28,28,1)
inputs = tf.keras.Input(shape=(28, 28, 1), name='input_layer')
# Conv Block 1 -> BatchNorm->leaky Relu
encoded = tf.keras.layers.Conv2D(32, kernel_size=3, strides= 1, padding='same', name='conv_1')(inputs)
encoded = tf.keras.layers.BatchNormalization(name='batchnorm_1')(encoded)
encoded = tf.keras.layers.LeakyReLU(name='leaky_relu_1')(encoded)
# Conv Block 2 -> BatchNorm->leaky Relu
encoded = tf.keras.layers.Conv2D(64, kernel_size=3, strides= 2, padding='same', name='conv_2')(encoded)
encoded = tf.keras.layers.BatchNormalization(name='batchnorm_2')(encoded)
encoded = tf.keras.layers.LeakyReLU(name='leaky_relu_2')(encoded)
# Conv Block 3 -> BatchNorm->leaky Relu
encoded = tf.keras.layers.Conv2D(64, kernel_size=3, strides=2, padding='same', name='conv_3')(encoded)
encoded = tf.keras.layers.BatchNormalization(name='batchnorm_3')(encoded)
encoded = tf.keras.layers.LeakyReLU(name='leaky_relu_3')(encoded)
#Decoder
# DeConv Block 1-> BatchNorm->leaky Relu
decoded = tf.keras.layers.Conv2DTranspose(64, 3, strides= 1, padding='same',name='conv_transpose_1')(encoded)
decoded = tf.keras.layers.BatchNormalization(name='batchnorm_4')(decoded)
decoded = tf.keras.layers.LeakyReLU(name='leaky_relu_4')(decoded)
# DeConv Block 2-> BatchNorm->leaky Relu
decoded = tf.keras.layers.Conv2DTranspose(64, 3, strides= 2, padding='same', name='conv_transpose_2')(decoded)
decoded = tf.keras.layers.BatchNormalization(name='batchnorm_5')(decoded)
decoded = tf.keras.layers.LeakyReLU(name='leaky_relu_5')(decoded)
# DeConv Block 3-> BatchNorm->leaky Relu
decoded = tf.keras.layers.Conv2DTranspose(32, 3, 2, padding='same', name='conv_transpose_3')(decoded)
decoded = tf.keras.layers.BatchNormalization(name='batchnorm_6')(decoded)
decoded = tf.keras.layers.LeakyReLU(name='leaky_relu_6')(decoded)
# output
outputs = tf.keras.layers.Conv2DTranspose(1, 3, 1,padding='same', activation='sigmoid', name='conv_transpose_4')(decoded)

 

출력 레이어는 그레이스케일 입력 이미지에 대해 동일한 정규화된 입력 범위가 될 범위[0,1]에 있도록 출력을 평평하게 하기 때문에 시그모이드 활성화 함수를 사용합니다.

 

SSIM 손실 함수 정의

SSIM은 휘도, 대비 및 구조 측면에서 두 이미지 간의 구조적 유사성을 측정 합니다. SSIM의 값이 1이면 동일한 이미지를 나타냅니다. 좋은 이미지에 대해 자동 인코더를 훈련할 때 SSIM 손실 함수가 최소가 되기를 원합니다.

def SSIMLoss(y_true, y_pred):
  return 1 - tf.reduce_mean(tf.image.ssim(y_true, y_pred,1.0))

 

AutoEncoder 만들기

autoencoder = tf.keras.Model(inputs, outputs)
optimizer = tf.keras.optimizers.Adam(lr = 0.0005)
autoencoder.compile(optimizer=optimizer, loss=SSIMLoss)

 

AutoEncoder 훈련

hist=autoencoder.fit(x_train, x_train,
                epochs=10,
                batch_size=128,
                shuffle=True,
                validation_data=(x_test, x_test)
                )

 

테스트 데이터에 대한 Fashion MNIST 이미지 재구성 및 시각화

테스트 데이터 세트를 자동 인코더에 전달하고 재구성된 데이터를 예측합니다. 원본 및 재구성된 이미지 시각화

decoded_imgs = autoencoder.predict(x_test)
n = 10
plt.figure(figsize=(20, 4))
for i in range(1, n + 1):
    # Display original
    ax = plt.subplot(2, n, i)
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    plt.title("Original")
    ax.get_yaxis().set_visible(False)
    # Display reconstruction
    ax = plt.subplot(2, n, i + n)
    plt.title("Reconstructed")
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

 

마지막으로 autoencoder가 학습된 원본 데이터와 학습된 데이터의 재구성된 이미지를 비교하고 autoencoder를 사용하여 비정상적인 이미지에 대한 예측을 수행합니다.

n = 6  # how many encoded and decoded images we will display
decoded_imgs= autoencoder.predict(x_test)
decoded_mnistimgs= autoencoder.predict(x_mnisttest)
plt.figure(figsize=(20, 14), dpi=100)
plt.subplots_adjust( wspace=0.1, hspace=0.07)
plt_a=1
for i in range(n):
    # Original training dataset vs Original training
    ax = plt.subplot(3, n, plt_a   )
    plt.imshow(x_test[i].reshape(28,28))
    ax.get_xaxis().set_visible(True)
    ax.get_yaxis().set_visible(False)
    value_a = SSIMLoss(x_test[i], x_test[i])
    ax.set_title("Original Image")
    label = 'SSIM Loss value: {:.3f}'
    ax.set_xlabel(label.format(value_a) )
    
    # Reconstructed good data  vs Original training data
    ax = plt.subplot(3, n, plt_a + n )
    plt.imshow(decoded_imgs[i].reshape(28,28))
    ax.get_xaxis().set_visible(True)
    ax.get_yaxis().set_visible(False)    
    value_a = SSIMLoss(decoded_imgs[i], x_test[i])
    ax.set_title("Reconstructed Image")
    label = 'SSIM Loss value: {:.3f}'
    ax.set_xlabel(label.format(value_a) )
    
    # Reconstructed anomalous data  vs Original training data
    ax = plt.subplot(3, n, plt_a + 2*n)
    plt.imshow(decoded_mnistimgs[i].reshape(28,28))
    ax.get_xaxis().set_visible(True)
    ax.get_yaxis().set_visible(False)
    value = SSIMLoss(decoded_mnistimgs[i], decoded_imgs[i])
    label = 'SSIM Loss value: {:.3f}'
    ax.set_title("Anamolus Image " )
    ax.set_xlabel(label.format(value) )
    plt_a+=1
plt.show()

 

위의 이미지에서 SSIM 손실은 훈련된 데이터 세트의 재구성에 대해 최소화되지만 오토인코더가 훈련되지 않은 데이터 세트의 경우 SSIM 손실이 더 높다는 것을 알 수 있습니다.

 

결론:

Autoencoder는 회색조 MNIST 및 Fashion MNIST로 이상을 식별하는 데 적합합니다.

 

 

반응형

댓글