일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- LTV예측
- 오토인코더
- google.oauth2
- LTV
- anomaly
- 유저이탈
- 게임분석
- 사례
- 게임 데이터분석
- 게임 이탈 분석
- anomaly detection
- 게임
- self-similarity
- google.cloud
- Detection
- 이상탐지
- 데이터 분석
- 봇탐지
- 통계학
- 기초통계학
- Kaggle
- AutoEncoder
- AE
- PYTHON
- 대회
- dacon
- 자료의요약
- 데이터분석
- 자기유사도
- 딥러닝
- Today
- Total
사쿠의 데이터 블로그
Anomaly Detection with AE (2) 본문
★★ 이상점 탐지 ★★
0. Auto Encoder 개념 -링크
1. Anomaly Detection with AE (1) - 링크
이번 포스팅에서는 오토 인코더를 이용해 Mnist 데이터와 노이즈를 구분해 보겠습니다.
그전에, Auto Encoder는 만능이 아닙니다.
다른 알고리즘과 비교 후 더 나은 알고리즘을 택했으면 좋겠습니다.
[대표적인 방법]
백 분위 점수와 상위 [1%, 0.1%, 0.01%] 점수를 비교
--> 이 방법은 상위 데이터에 이상점이 있을 경우 훨씬 저렴하게 탐지할 수 있습니다.

AE로 이상점을 탐지하는 방법
항상 그렇듯, 가설을 세우고 문제를 해결해야 합니다.
이번에 세울 가설은 "AE는 비 정상 데이터가 들어오면 Error를 높게 배출한다" 입니다.
딥러닝이 마법도 아닌데 어떻게 이런 일이 가능할까?

잘 학습된 AE는 정상 데이터가 들어왔다면 낮은 MSE값을 출력할 것이다.
--> input과 output의 차이를 줄이도록 학습한 AE의 MSE는 당연히 낮을 것이다
이에 반해, AE는 비 정상 데이터를 제대로 복원하지 못한다는 가정이다.
--> 이에 대한 원인은 뒷부분에(다음 포스팅)에 설명하도록 하겠습니다.
AE는 특이하게 MSE를 Recontruction Error라고도 부른다.
정상과 비정상은 MSE에서 차이가 날 것이다.
= 정상 데이터는 Recontruction Error가 낮지만 비정상은 그렇지 못할 것이다.
어떻게 AE로 가능해!?!
이전 포스팅에서 AE는 input과 output을 동일하게 만든다고 했다.
그런데 생각해보면, 잘 학습된 AE는
- 정상 데이터를 Input으로 받고 정상 데이터를 Output으로 뱉을 것이다.
- 그렇다면 MSE는 (정상 - 정상)^2 = 0
- 비정상 데이터를 Input으로 받고 비정상 데이터를 Output 으로 나올 것이다.
- MSE = (비정상 - 비정상)^2 = 0
그럼 대체 어떻게 구분이 가능할까?
미리 힌트를 드리자면 Latent Space(=manifold)에 정답이 있습니다.
자세한 내용은 다음 포스팅을 참조 부탁드립니다.
코드를 보면서
데이터 불러오기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import os
import torch
from torch import nn
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import save_image
import numpy as np
# python - m visdom.server
import visdom
# 미리 만들어둔 모델 불러오기
from AE_model import encoder, decoder
# 데이터 불러오기
dataset = MNIST('./data', transform=img_transform)
dataloader = DataLoader(dataset, batch_size=batch_size , shuffle=True)
|
cs |
이전에 다운로드했던 mnist 데이터를 불러오고 Dataloader에 탑재(?)합니다.
혹시라도 다운로드 하지 못했다면 download = True 옵션을 추가하면 된다.
1
|
dataset = MNIST('./data', transform=img_transform, download=True)
|
cs |
visdom은 tensorflow의 tensor board와 같은 역할을 합니다. (시각화)
torchvision에서 제공하는 MNIST 데이터는 총 6만 장이 train으로 제공됩니다.
이번 실험에서는 6만 장의 0.1%인 60장의 노이즈 이미지를 탐지해보려 합니다.
노이즈 이미지 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def make_fake_img():
img_size = 28
n_fake_img = 60
fake_img = []
for i in range(n_fake_img):
fake_img.append( np.random.randn(img_size * img_size).reshape(1, img_size, img_size) )
fake_img = torch.FloatTensor(fake_img)
fake_img = fake_img.view(n_fake_img, img_size * img_size)
fake_img = Variable(fake_img).cuda()
return fake_img
fake_img = make_fake_img()
|
cs |
AE 학습

위 그림과 같이 학습을 진행했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
for epoch in range(num_epochs):
for data in dataloader:
img, _ = data # label 은 가져오지 않는다.
img = img.view(img.size(0), -1)
img = Variable(img).cuda()
# ===================forward=====================
latent_z = encoder(img)
output = decoder(latent_z )
# ===================backward====================
loss = criterion(output, img)
encoder_optimizer.zero_grad()
decoder_optimizer.zero_grad()
loss.backward()
encoder_optimizer.step()
decoder_optimizer.step()
# ===================log========================
print('epoch [{}/{}], loss:{:.4f}' .format(epoch + 1, num_epochs, float(loss.data) ))
vis.line(Y=[loss.data.cpu().numpy()], X=np.array([epoch]), win=normal, update='append')
if epoch % 10 == 0:
pic = to_img(output.cpu().data)
save_image(pic, './AE_img/output_image_{}.png'.format(epoch))
# ===================forward=====================
latent_z = encoder(fake_img)
output = decoder(latent_z )
# ===================backward====================
loss = criterion(output, fake_img)
encoder_optimizer.zero_grad()
decoder_optimizer.zero_grad()
loss.backward()
encoder_optimizer.step()
decoder_optimizer.step()
# ===================log========================
print('##### fake epoch [{}/{}], loss:{:.4f} #### '.format(epoch + 1, num_epochs, float(loss.data) ))
vis.line(Y=[loss.data.cpu().numpy()], X=np.array([epoch]), win=anomaly, update='append')
if epoch % 10 == 0:
pic = to_img(output.cpu().data)
save_image(pic, './AE_img/fake_image_{}.png'.format(epoch))
|
cs |
결과 확인

정상 데이터와 비정상 데이터간 Loss(=MSE)를 비교해 봤습니다.
비정상 데이터는 감소하지 않는 모습을 확인 할 수 있습니다.

정상과 비정상 데이터가 제대로 분리되는 모습을 확인 했습니다.
다음 포스트에서는 왜 작동이 되는지 확인 해보도록 하겠습니다.
(너무 길어서 다음으로 넘기겠습니다.)
요약.
1. 데이터 속 이상점(anomaly data)이 있는 걸 알지만 탐지 방법을 모른다.
2. 오토 인코더를 사용하면 정상과 비정상 데이터를 분리 할 수 있다.
위 예시에서 사용한 코드는 깃허브에서 확인 할 수 있습니다.
(링크)
'Python(데이터 분석, 딥러닝)' 카테고리의 다른 글
Python에서 Bigquery 연동하기 (0) | 2022.01.23 |
---|---|
변수 중요도 측정 - Permutation importance (0) | 2019.10.27 |
Anomaly Detection with AE (1) (1) | 2019.05.25 |
Auto Encoder(개념) (1) | 2019.05.25 |
Pytorch 설치 (0) | 2019.05.19 |