AnoGAN 구현

오늘은 저번 포스팅에서 구현 했던 DCGAN 을 통해 Anomaly Detection 을 하는 포스팅을 하려고 합니다. DCGAN 을 이용해서 이상치를 탐색하는 부분이 코드 이해하는데 힘들긴 했는데 흥미로운 파트였던 것 같습니다. 아무래도 현장에서는 라벨링이 힘든 환경에 있을 때가 많을 것 같은데, 이럴 때 이상치 탐지를 하기에 좋은 모델인 것 같습니다. 제가 구현한 대상 데이터는 MNIST 이지만 향후 여러 데이터를 통해 구현 해보고 싶다는 생각을 했습니다. 또 여러 파라미터를 바꿔가면서 구현해야 할 필요성을 느꼈습니다. 지금 제가 구현한 것은 간단하게 구현 되어 있지만, 다른 옵티마이저나 loss function 을 사용해서도 성능이 잘 나오는지 구현해봐야겠습니다 ㅎㅎ

anomaly detection 코드는
https://github.com/mullue/anogan-mnist/blob/master/dcgan%2Banogan.ipynb
를 참고 했습니다.

제가 구현해본 전체 코드는
https://github.com/soomin9106/Deep-Learning/blob/main/AnoGAN/DCGAN_AnoGAN.ipynb => 이거 입니다!!

설명을 시작해보도록 하겠습니다!

일단 DCGAN 의 모델을 돌리면서 weights 를 ckpt 파일로 저장을 해놔야 합니다. 이상치 탐지는 DCGAN 을 통해 최적의 파라미터를 찾았다고 가정하고 진행을 하게 됩니다.

이후에 discriminator 모델을 만들어주는 함수를 하나 만들어줍니다. DCGAN 에서 찾았던 최적의 가중치를 로딩하여 모델을 만들어줍니다.

#Discriminator 로부터 feature 를 도출하는 함수
from tensorflow.keras.models import Model

def feature_extractor(img_shape=(28,28,1)):
    d = make_discriminator_model()
    d.load_weights('/content/d-50.ckpt') #discriminator model weigth 저장된 파일
    intermidiate_model = Model(inputs=d.layers[0].input, outputs=d.layers[-6].output)
    intermidiate_model.compile(loss='binary_crossentropy', optimizer='adam')
    return intermidiate_model

다음으로는 임의의 크기가 100인 z 에 대해 latent vector 을 생성하고 이 백터를 앞서 훈련시켰던 generator 가중치를 로딩한 모델에 넣어주고, 이렇게 생성된 이미지를 바로 위에 있는 intermidiate_model 에 넣어줍니다. 그렇게 되면 loss 가 적은 최적의 z 값을 학습할 수 있을 것입니다.

#임의의 z로부터 latent vector를 생성하고 Generator와 앞서 feature_extractor를 호출합니다.
from tensorflow.keras.layers import Layer, Input, Dense, Flatten

def gne_anogan(loss, latent_dim = 100, channels = 1, img_shape=(28,28,1)):
  g = make_generator_model()
  g.load_weights('/content/g-50.ckpt')
  g.trainable = False
  intermidiate_model = feature_extractor(img_shape)
  intermidiate_model.trainable = False

  z = Input(shape=(100,))
  gInput = Dense((100))(z)
  G_out = g(gInput)
  D_out = intermidiate_model(G_out)    
  model = Model(inputs=z, outputs=[G_out, D_out])
  model.compile(loss=sum_of_residual, loss_weights= [0.9, 0.1], optimizer='adam')

  return model

이 모델들을 바탕으로 정상 데이터와 비정상 데이터를 테스트 해보면 다음과 같은 결과가 나옵니다.
<정상 데이터>

<비정상 데이터>

이 전 시간에 DCGAN 이 학습 했던 데이터들은 숫자 데이터 였습니다. 즉, 모델 입장에서는 숫자 데이터가 정상 데이터고 숫자 데이터가 아닌 것들은 정상 데이터가 아닙니다. 다음 사진에서 정상 데이터, 즉 숫자 0 으로 테스트 해보고 residual 을 시각화 했을 때가 비정상 데이터, 여기서는 알파벳으로 테스트 해보고 시각화 했을 때보다 residual 이 더 작다고 나오게 됩니다. (사진이 어두울 수록 residual 값이 큼)

마지막으로 100개의 데이터에 대한 검증을 해보고 loss 를 플롯으로 나타냈을 때는 아래 사진과 같습니다

비정상일 경우가 loss 값이 더 높게 책정되는 것을 보실 수 있습니다.

좋은 웹페이지 즐겨찾기