├── .DS_Store
├── anogan.pyc
├── assets
├── generator
├── anoGAN.png
├── anoGAN2.png
├── overall.png
├── residual.png
├── test_img.png
├── discriminator
├── output_2_0.png
├── output_3_0.png
├── output_3_2.png
├── output_4_0.png
├── output_4_2.png
├── output_5_1.png
├── output_5_3.png
├── residual_img.png
└── discrimination.png
├── .gitattributes
├── anogan.py
├── README.md
├── anoGAN_MNIST.ipynb
└── .ipynb_checkpoints
└── anoGAN_MNIST-checkpoint.ipynb
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/.DS_Store
--------------------------------------------------------------------------------
/anogan.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/anogan.pyc
--------------------------------------------------------------------------------
/assets/generator:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/generator
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/assets/anoGAN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/anoGAN.png
--------------------------------------------------------------------------------
/assets/anoGAN2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/anoGAN2.png
--------------------------------------------------------------------------------
/assets/overall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/overall.png
--------------------------------------------------------------------------------
/assets/residual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/residual.png
--------------------------------------------------------------------------------
/assets/test_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/test_img.png
--------------------------------------------------------------------------------
/assets/discriminator:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/discriminator
--------------------------------------------------------------------------------
/assets/output_2_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_2_0.png
--------------------------------------------------------------------------------
/assets/output_3_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_3_0.png
--------------------------------------------------------------------------------
/assets/output_3_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_3_2.png
--------------------------------------------------------------------------------
/assets/output_4_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_4_0.png
--------------------------------------------------------------------------------
/assets/output_4_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_4_2.png
--------------------------------------------------------------------------------
/assets/output_5_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_5_1.png
--------------------------------------------------------------------------------
/assets/output_5_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/output_5_3.png
--------------------------------------------------------------------------------
/assets/residual_img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/residual_img.png
--------------------------------------------------------------------------------
/assets/discrimination.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjucho1/anoGAN/HEAD/assets/discrimination.png
--------------------------------------------------------------------------------
/anogan.py:
--------------------------------------------------------------------------------
1 | from keras.models import Sequential, Model
2 | from keras.layers import Input, Reshape, Dense, Dropout, UpSampling2D, Conv2D, Flatten
3 | from keras.layers.advanced_activations import LeakyReLU
4 | from keras.optimizers import Adam
5 | from keras import backend as K
6 | from keras import initializers
7 | import tensorflow as tf
8 | import numpy as np
9 | from tqdm import tqdm
10 |
11 | def generator_model():
12 | generator = Sequential()
13 | generator.add(Dense(128*7*7, input_dim=100, kernel_initializer=initializers.RandomNormal(stddev=0.02)))
14 | generator.add(LeakyReLU(0.2))
15 | generator.add(Reshape((7, 7, 128)))
16 | generator.add(UpSampling2D(size=(2, 2)))
17 | generator.add(Conv2D(64, kernel_size=(5, 5), padding='same'))
18 | generator.add(LeakyReLU(0.2))
19 | generator.add(UpSampling2D(size=(2, 2)))
20 | generator.add(Conv2D(1, kernel_size=(5, 5), padding='same', activation='tanh'))
21 | generator.compile(loss='binary_crossentropy', optimizer='adam')
22 | return generator
23 |
24 |
25 | def discriminator_model():
26 | discriminator = Sequential()
27 | discriminator.add(Conv2D(64, kernel_size=(5, 5), strides=(2, 2), padding='same', input_shape=(28,28, 1), kernel_initializer=initializers.RandomNormal(stddev=0.02)))
28 | discriminator.add(LeakyReLU(0.2))
29 | discriminator.add(Dropout(0.3))
30 | discriminator.add(Conv2D(128, kernel_size=(5, 5), strides=(2, 2), padding='same'))
31 | discriminator.add(LeakyReLU(0.2))
32 | discriminator.add(Dropout(0.3))
33 | discriminator.add(Flatten())
34 | discriminator.add(Dense(1, activation='sigmoid'))
35 | discriminator.compile(loss='binary_crossentropy', optimizer='adam')
36 | return discriminator
37 |
38 |
39 | def generator_containing_discriminator(g, d):
40 | d.trainable = False
41 | ganInput = Input(shape=(100,))
42 | x = g(ganInput)
43 | ganOutput = d(x)
44 | gan = Model(inputs=ganInput, outputs=ganOutput)
45 | gan.compile(loss='binary_crossentropy', optimizer='adam')
46 | return gan
47 |
48 | def train(BATCH_SIZE, X_train):
49 | d = discriminator_model()
50 | print("#### discriminator ######")
51 | d.summary()
52 | g = generator_model()
53 | print("#### generator ######")
54 | g.summary()
55 | d_on_g = generator_containing_discriminator(g, d)
56 | d.trainable = True
57 | for epoch in tqdm(range(200)):
58 | for index in range(int(X_train.shape[0]/BATCH_SIZE)):
59 | noise = np.random.uniform(0, 1, size=(BATCH_SIZE, 100))
60 | image_batch = X_train[index*BATCH_SIZE:(index+1)*BATCH_SIZE]
61 | generated_images = g.predict(noise, verbose=0)
62 | X = np.concatenate((image_batch, generated_images))
63 | y = np.array([1] * BATCH_SIZE + [0] * BATCH_SIZE)
64 | d_loss = d.train_on_batch(X, y)
65 | noise = np.random.uniform(0, 1, (BATCH_SIZE, 100))
66 | d.trainable = False
67 | g_loss = d_on_g.train_on_batch(noise, np.array([1] * BATCH_SIZE))
68 | d.trainable = True
69 | g.save_weights('assets/generator', True)
70 | d.save_weights('assets/discriminator', True)
71 | return d, g
72 |
73 |
74 | def generate(BATCH_SIZE):
75 | g = generator_model()
76 | g.load_weights('assets/generator')
77 | noise = np.random.uniform(0, 1, (BATCH_SIZE, 100))
78 | generated_images = g.predict(noise)
79 | return generated_images
80 |
81 | def sum_of_residual(y_true, y_pred):
82 | return tf.reduce_sum(abs(y_true - y_pred))
83 |
84 | def feature_extractor():
85 | d = discriminator_model()
86 | d.load_weights('assets/discriminator')
87 | intermidiate_model = Model(inputs=d.layers[0].input, outputs=d.layers[-5].output)
88 | intermidiate_model.compile(loss='binary_crossentropy', optimizer='adam')
89 | return intermidiate_model
90 |
91 | def anomaly_detector():
92 | g = generator_model()
93 | g.load_weights('assets/generator')
94 | g.trainable = False
95 | intermidiate_model = feature_extractor()
96 | intermidiate_model.trainable = False
97 |
98 | aInput = Input(shape=(100,))
99 | gInput = Dense((100))(aInput)
100 | G_out = g(gInput)
101 | D_out= intermidiate_model(G_out)
102 | model = Model(inputs=aInput, outputs=[G_out, D_out])
103 | model.compile(loss=sum_of_residual, loss_weights= [0.9, 0.1], optimizer='adam')
104 | return model
105 |
106 | def compute_anomaly_score(model, x):
107 | z = np.random.uniform(0, 1, size=(1, 100))
108 | intermidiate_model = feature_extractor()
109 | d_x = intermidiate_model.predict(x)
110 | loss = model.fit(z, [x, d_x], epochs=500, verbose=0)
111 | similar_data, _ = model.predict(z)
112 | return loss.history['loss'][-1], similar_data
113 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Keras implementation of AnoGAN
3 |
4 | https://arxiv.org/abs/1703.05921
5 |
6 | Abstract
7 |
8 | 질병의 예후를 모니터링하기 위해 이미지 마커를 잡아내는 모델을 얻는 것은 매우 어려운 일이다. 보통의 모델은 자동 감지를 위해 알려진 마커의 주석이 달린 예제를 사용하여 많은 양의 데이터를 기반으로 한다. 주석처리(라벨링) 작업과 이미 알려진 것들에 대해서만 탐지 가능하다는 점은 그런 방식의 단점을 작용한다 이 논문은 이미지에서 어노말리를 찾기 위해 비지도학습 이용하다. 우리가 제안한 anoGAN은 정상적인 변동성의 다양함(정상 데이텅의 분포)를 학습한 DCGAN과 이미지 공간에서 잠재공간으로의 매핑방식을 기반으로 어노말리 스코어를 계산한다. 새로운 데이터에 적용했을때 모델은 어노말리와 어노말리 스코어를 계산한다. 이 방식을 망막의 광학 단층 촬영 영상에 적용한 결과, 망막 유체 또는 반사성 초점을 포함하는 이미지와 같은 변칙적인 영상(어노말리)을 정확하게 식별함을 확인하였다.
9 |
10 |
11 | 
12 |
13 | 1.train DCGAN with normal image
14 | * Radford, A., Metz, L., Chintala, S.: Unsupervised representation learning with deep convolutional generative adversarial networks. arXiv:1511.06434 (2015)
15 |
16 | 2.Mapping new Images to the Latent Space
17 | * 신규데이터(a query image x)가 들어오면 우리는 신규이미지 x와 시각적으로 가장 유사한 이미지 G(z)에 대응하는 z를 찾는 것이 목적이다.
18 | * best z를 찾기위해 처음에는 랜덤하게 뽑은 z1를 학습된 generator에 입력값으로 넣어 G(z1)를 얻는다.
19 | * G(z1)를 기준으로 loss를 계산한다. 이때 loss는 latent space에서 z1이 z2로 이동을 의미하는 z1의 coefficient를 업데이트할 그래디언트 역할을 한다. (z2 = c * z1, c는 backpropagation을 통해 결정)
20 | * 신규데이터와 가장 유사한 G(z)를 찾기 위해, latent space에서 z의 위치는 역전파를 통한 반복적인 계산을 통해 최적화된다. (500 backpropagation steps)
21 |
22 | 2.1 loss
23 | - z를 최적화기위해 사용한 loss는 2가지로 구성된다.
24 | - residual loss : G(z)와 x와의 차이값
25 | 
26 | - discrimination loss : discriminator의 중간레이어 결과값의 차이
27 | 
28 | f(·) : output of an intermediate layer of the discriminator
29 | - overall loss : residual loss와 discrimination loss의 가중합 (논문에서 사용한 람다=0.1)
30 | 
31 |
32 | 3.anomaly score
33 | * 2의 맵핑과정을 통해 최종적으로 얻은 loss값을 사용한다
34 | * 또한 신규이미지에서 anomaly의 영역을 규명하기위해 가장 유사한 이미지와 신규이미지와의 차이 이미지(residual image)를 사용하였다.
35 | 
36 |
37 |
38 | 
39 |
40 |
41 |
42 |
43 |
44 | ```python
45 | import numpy as np
46 | import matplotlib.pyplot as plt
47 | from keras.datasets import mnist
48 | from tqdm import tqdm
49 | import anogan
50 |
51 | (X_train, y_train), (X_test, y_test) = mnist.load_data()
52 | X_train = X_train.astype(np.float32)/255.
53 | X_train = X_train.reshape(60000, 28, 28, 1)
54 |
55 |
56 | Model_d, Model_g = anogan.train(32, X_train)
57 | ```
58 |
59 | #### discriminator ######
60 | _________________________________________________________________
61 | Layer (type) Output Shape Param #
62 | =================================================================
63 | conv2d_53 (Conv2D) (None, 14, 14, 64) 1664
64 | _________________________________________________________________
65 | leaky_re_lu_53 (LeakyReLU) (None, 14, 14, 64) 0
66 | _________________________________________________________________
67 | dropout_43 (Dropout) (None, 14, 14, 64) 0
68 | _________________________________________________________________
69 | conv2d_54 (Conv2D) (None, 7, 7, 128) 204928
70 | _________________________________________________________________
71 | leaky_re_lu_54 (LeakyReLU) (None, 7, 7, 128) 0
72 | _________________________________________________________________
73 | dropout_44 (Dropout) (None, 7, 7, 128) 0
74 | _________________________________________________________________
75 | flatten_22 (Flatten) (None, 6272) 0
76 | _________________________________________________________________
77 | dense_31 (Dense) (None, 1) 6273
78 | =================================================================
79 | Total params: 212,865
80 | Trainable params: 212,865
81 | Non-trainable params: 0
82 | _________________________________________________________________
83 | #### generator ######
84 | _________________________________________________________________
85 | Layer (type) Output Shape Param #
86 | =================================================================
87 | dense_32 (Dense) (None, 6272) 633472
88 | _________________________________________________________________
89 | leaky_re_lu_55 (LeakyReLU) (None, 6272) 0
90 | _________________________________________________________________
91 | reshape_6 (Reshape) (None, 7, 7, 128) 0
92 | _________________________________________________________________
93 | up_sampling2d_11 (UpSampling (None, 14, 14, 128) 0
94 | _________________________________________________________________
95 | conv2d_55 (Conv2D) (None, 14, 14, 64) 204864
96 | _________________________________________________________________
97 | leaky_re_lu_56 (LeakyReLU) (None, 14, 14, 64) 0
98 | _________________________________________________________________
99 | up_sampling2d_12 (UpSampling (None, 28, 28, 64) 0
100 | _________________________________________________________________
101 | conv2d_56 (Conv2D) (None, 28, 28, 1) 1601
102 | =================================================================
103 | Total params: 839,937
104 | Trainable params: 839,937
105 | Non-trainable params: 0
106 | _________________________________________________________________
107 |
108 |
109 | 0%| | 0/200 [00:00, ?it/s]
110 |
111 |
112 | ```python
113 | ## generate random image
114 |
115 | generated_img = anogan.generate(3)
116 | plt.figure(figsize=(2, 2))
117 | plt.imshow(generated_img[0].reshape(28, 28),cmap=plt.cm.gray)
118 | plt.show()
119 | ```
120 |
121 |
122 | 
123 |
124 |
125 |
126 | ```python
127 | ## compute anomaly score - sample from test set
128 |
129 | X_test = X_test.astype(np.float32)/255.
130 | X_test = X_test.reshape(-1, 28, 28, 1)
131 | test_img = X_test[0]
132 |
133 | model = anogan.anomaly_detector()
134 | ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))
135 |
136 | plt.figure(figsize=(2, 2))
137 | plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)
138 | plt.show()
139 | print("anomaly score : " + str(ano_score))
140 | plt.figure(figsize=(2, 2))
141 | plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)
142 | residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)
143 | plt.imshow(residual, cmap='jet', alpha=.5)
144 | plt.show()
145 | ```
146 |
147 |
148 | 
149 |
150 |
151 | anomaly score : 29.612060546875
152 |
153 |
154 |
155 | 
156 |
157 |
158 |
159 | ```python
160 | ## compute anomaly score - sample from strange image
161 |
162 | test_img = plt.imread('assets/test_img.png')
163 | test_img = test_img[:,:,0]
164 |
165 | model = anogan.anomaly_detector()
166 | ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))
167 |
168 | plt.figure(figsize=(2, 2))
169 | plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)
170 | plt.show()
171 | print("anomaly score : " + str(ano_score))
172 | plt.figure(figsize=(2, 2))
173 | plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)
174 | residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)
175 | plt.imshow(residual, cmap='jet', alpha=.5)
176 | plt.show()
177 |
178 | ```
179 |
180 |
181 | 
182 |
183 |
184 | anomaly score : 446.46844482421875
185 |
186 |
187 |
188 | 
189 |
190 |
191 |
192 | ```python
193 | from sklearn.manifold import TSNE
194 |
195 | ## t-SNE embedding
196 |
197 | # generating anomaly image for test (radom noise image)
198 |
199 | random_image = np.random.uniform(0,1, (100, 28,28, 1))
200 | print("a sample from generated anomaly images(random noise image)")
201 | plt.figure(figsize=(2, 2))
202 | plt.imshow(random_image[0].reshape(28,28), cmap=plt.cm.gray)
203 | plt.show()
204 |
205 | # intermidieate output of discriminator
206 | model = anogan.feature_extractor()
207 | feature_map_of_random = model.predict(random_image, verbose=1)
208 | feature_map_of_minist = model.predict(X_test[:300], verbose=1)
209 |
210 | # t-SNE for visulization
211 | output = np.concatenate((feature_map_of_random, feature_map_of_minist))
212 | output = output.reshape(output.shape[0], -1)
213 | anomaly_flag = np.array([1]*100+ [0]*300)
214 |
215 | X_embedded = TSNE(n_components=2).fit_transform(output)
216 | plt.title("t-SNE embedding on the feature representation")
217 | plt.scatter(X_embedded[:100,0], X_embedded[:100,1], label='random noise(anomaly)')
218 | plt.scatter(X_embedded[100:,0], X_embedded[100:,1], label='minist(normal)')
219 | plt.legend()
220 | plt.show()
221 | ```
222 |
223 | a sample from generated anomaly images(random noise image)
224 |
225 |
226 |
227 | 
228 |
229 |
230 | 100/100 [==============================] - 0s 4ms/step
231 | 300/300 [==============================] - 0s 322us/step
232 |
233 |
234 |
235 | 
236 |
237 |
--------------------------------------------------------------------------------
/anoGAN_MNIST.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Keras implementation of AnoGAN \n",
8 | "\n",
9 | "https://arxiv.org/abs/1703.05921\n",
10 | "\n",
11 | " Abstract \n",
12 | "\n",
13 | "질병의 예후를 모니터링하기 위해 이미지 마커를 잡아내는 모델을 얻는 것은 매우 어려운 일이다. 보통의 모델은 자동 감지를 위해 알려진 마커의 주석이 달린 예제를 사용하여 많은 양의 데이터를 기반으로 한다. 주석처리(라벨링) 작업과 이미 알려진 것들에 대해서만 탐지 가능하다는 점은 그런 방식의 단점을 작용한다 이 논문은 이미지에서 어노말리를 찾기 위해 비지도학습 이용하다. 우리가 제안한 anoGAN은 정상적인 변동성의 다양함(정상 데이텅의 분포)를 학습한 DCGAN과 이미지 공간에서 잠재공간으로의 매핑방식을 기반으로 어노말리 스코어를 계산한다. 새로운 데이터에 적용했을때 모델은 어노말리와 어노말리 스코어를 계산한다. 이 방식을 망막의 광학 단층 촬영 영상에 적용한 결과, 망막 유체 또는 반사성 초점을 포함하는 이미지와 같은 변칙적인 영상(어노말리)을 정확하게 식별함을 확인하였다.\n",
14 | "\n",
15 | "\n",
16 | "\n",
17 | "\n",
18 | " 1.train DCGAN with normal image \n",
19 | "* Radford, A., Metz, L., Chintala, S.: Unsupervised representation learning with deep convolutional generative adversarial networks. arXiv:1511.06434 (2015)\n",
20 | "\n",
21 | " 2.Mapping new Images to the Latent Space \n",
22 | "* 신규데이터(a query image x)가 들어오면 우리는 신규이미지 x와 시각적으로 가장 유사한 이미지 G(z)에 대응하는 z를 찾는 것이 목적이다. \n",
23 | "* best z를 찾기위해 처음에는 랜덤하게 뽑은 z1를 학습된 generator에 입력값으로 넣어 G(z1)를 얻는다.\n",
24 | "* G(z1)를 기준으로 loss를 계산한다. 이때 loss는 latent space에서 z1이 z2로 이동을 의미하는 z1의 coefficient를 업데이트할 그래디언트 역할을 한다. (z2 = c * z1, c는 backpropagation을 통해 결정)\n",
25 | "* 신규데이터와 가장 유사한 G(z)를 찾기 위해, latent space에서 z의 위치는 역전파를 통한 반복적인 계산을 통해 최적화된다. (500 backpropagation steps)\n",
26 | "\n",
27 | " 2.1 loss \n",
28 | " - z를 최적화기위해 사용한 loss는 2가지로 구성된다. \n",
29 | " - residual loss : G(z)와 x와의 차이값 \n",
30 | " \n",
31 | " - discrimination loss : discriminator의 중간레이어 결과값의 차이\n",
32 | " \n",
33 | " f(·) : output of an intermediate layer of the discriminator \n",
34 | " - overall loss : residual loss와 discrimination loss의 가중합 (논문에서 사용한 람다=0.1)\n",
35 | " \n",
36 | "\n",
37 | " 3.anomaly score \n",
38 | "* 2의 맵핑과정을 통해 최종적으로 얻은 loss값을 사용한다\n",
39 | "* 또한 신규이미지에서 anomaly의 영역을 규명하기위해 가장 유사한 이미지와 신규이미지와의 차이 이미지(residual image)를 사용하였다. \n",
40 | "\n",
41 | "\n",
42 | "\n",
43 | "\n",
44 | "\n",
45 | "\n"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {
52 | "scrolled": false
53 | },
54 | "outputs": [
55 | {
56 | "name": "stdout",
57 | "output_type": "stream",
58 | "text": [
59 | "#### discriminator ######\n",
60 | "_________________________________________________________________\n",
61 | "Layer (type) Output Shape Param # \n",
62 | "=================================================================\n",
63 | "conv2d_53 (Conv2D) (None, 14, 14, 64) 1664 \n",
64 | "_________________________________________________________________\n",
65 | "leaky_re_lu_53 (LeakyReLU) (None, 14, 14, 64) 0 \n",
66 | "_________________________________________________________________\n",
67 | "dropout_43 (Dropout) (None, 14, 14, 64) 0 \n",
68 | "_________________________________________________________________\n",
69 | "conv2d_54 (Conv2D) (None, 7, 7, 128) 204928 \n",
70 | "_________________________________________________________________\n",
71 | "leaky_re_lu_54 (LeakyReLU) (None, 7, 7, 128) 0 \n",
72 | "_________________________________________________________________\n",
73 | "dropout_44 (Dropout) (None, 7, 7, 128) 0 \n",
74 | "_________________________________________________________________\n",
75 | "flatten_22 (Flatten) (None, 6272) 0 \n",
76 | "_________________________________________________________________\n",
77 | "dense_31 (Dense) (None, 1) 6273 \n",
78 | "=================================================================\n",
79 | "Total params: 212,865\n",
80 | "Trainable params: 212,865\n",
81 | "Non-trainable params: 0\n",
82 | "_________________________________________________________________\n",
83 | "#### generator ######\n",
84 | "_________________________________________________________________\n",
85 | "Layer (type) Output Shape Param # \n",
86 | "=================================================================\n",
87 | "dense_32 (Dense) (None, 6272) 633472 \n",
88 | "_________________________________________________________________\n",
89 | "leaky_re_lu_55 (LeakyReLU) (None, 6272) 0 \n",
90 | "_________________________________________________________________\n",
91 | "reshape_6 (Reshape) (None, 7, 7, 128) 0 \n",
92 | "_________________________________________________________________\n",
93 | "up_sampling2d_11 (UpSampling (None, 14, 14, 128) 0 \n",
94 | "_________________________________________________________________\n",
95 | "conv2d_55 (Conv2D) (None, 14, 14, 64) 204864 \n",
96 | "_________________________________________________________________\n",
97 | "leaky_re_lu_56 (LeakyReLU) (None, 14, 14, 64) 0 \n",
98 | "_________________________________________________________________\n",
99 | "up_sampling2d_12 (UpSampling (None, 28, 28, 64) 0 \n",
100 | "_________________________________________________________________\n",
101 | "conv2d_56 (Conv2D) (None, 28, 28, 1) 1601 \n",
102 | "=================================================================\n",
103 | "Total params: 839,937\n",
104 | "Trainable params: 839,937\n",
105 | "Non-trainable params: 0\n",
106 | "_________________________________________________________________\n"
107 | ]
108 | },
109 | {
110 | "name": "stderr",
111 | "output_type": "stream",
112 | "text": [
113 | "\r",
114 | " 0%| | 0/200 [00:00, ?it/s]"
115 | ]
116 | }
117 | ],
118 | "source": [
119 | "import numpy as np\n",
120 | "import matplotlib.pyplot as plt\n",
121 | "from keras.datasets import mnist\n",
122 | "from tqdm import tqdm\n",
123 | "import anogan\n",
124 | "\n",
125 | "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
126 | "X_train = X_train.astype(np.float32)/255.\n",
127 | "X_train = X_train.reshape(60000, 28, 28, 1)\n",
128 | "\n",
129 | "\n",
130 | "Model_d, Model_g = anogan.train(32, X_train)"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": 2,
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "data": {
140 | "image/png": "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\n",
141 | "text/plain": [
142 | ""
143 | ]
144 | },
145 | "metadata": {},
146 | "output_type": "display_data"
147 | }
148 | ],
149 | "source": [
150 | "## generate random image \n",
151 | "\n",
152 | "generated_img = anogan.generate(3)\n",
153 | "plt.figure(figsize=(2, 2))\n",
154 | "plt.imshow(generated_img[0].reshape(28, 28),cmap=plt.cm.gray)\n",
155 | "plt.show()"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": 5,
161 | "metadata": {},
162 | "outputs": [
163 | {
164 | "data": {
165 | "image/png": "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\n",
166 | "text/plain": [
167 | ""
168 | ]
169 | },
170 | "metadata": {},
171 | "output_type": "display_data"
172 | },
173 | {
174 | "name": "stdout",
175 | "output_type": "stream",
176 | "text": [
177 | "anomaly score : 29.612060546875\n"
178 | ]
179 | },
180 | {
181 | "data": {
182 | "image/png": "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\n",
183 | "text/plain": [
184 | ""
185 | ]
186 | },
187 | "metadata": {},
188 | "output_type": "display_data"
189 | }
190 | ],
191 | "source": [
192 | "## compute anomaly score - sample from test set\n",
193 | "\n",
194 | "X_test = X_test.astype(np.float32)/255.\n",
195 | "X_test = X_test.reshape(-1, 28, 28, 1)\n",
196 | "test_img = X_test[0]\n",
197 | "\n",
198 | "model = anogan.anomaly_detector()\n",
199 | "ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))\n",
200 | "\n",
201 | "plt.figure(figsize=(2, 2))\n",
202 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
203 | "plt.show()\n",
204 | "print(\"anomaly score : \" + str(ano_score))\n",
205 | "plt.figure(figsize=(2, 2))\n",
206 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
207 | "residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)\n",
208 | "plt.imshow(residual, cmap='jet', alpha=.5)\n",
209 | "plt.show()"
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": 6,
215 | "metadata": {},
216 | "outputs": [
217 | {
218 | "data": {
219 | "image/png": "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\n",
220 | "text/plain": [
221 | ""
222 | ]
223 | },
224 | "metadata": {},
225 | "output_type": "display_data"
226 | },
227 | {
228 | "name": "stdout",
229 | "output_type": "stream",
230 | "text": [
231 | "anomaly score : 446.46844482421875\n"
232 | ]
233 | },
234 | {
235 | "data": {
236 | "image/png": "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\n",
237 | "text/plain": [
238 | ""
239 | ]
240 | },
241 | "metadata": {},
242 | "output_type": "display_data"
243 | }
244 | ],
245 | "source": [
246 | "## compute anomaly score - sample from strange image\n",
247 | "\n",
248 | "test_img = plt.imread('assets/test_img.png')\n",
249 | "test_img = test_img[:,:,0]\n",
250 | "\n",
251 | "model = anogan.anomaly_detector()\n",
252 | "ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))\n",
253 | "\n",
254 | "plt.figure(figsize=(2, 2))\n",
255 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
256 | "plt.show()\n",
257 | "print(\"anomaly score : \" + str(ano_score))\n",
258 | "plt.figure(figsize=(2, 2))\n",
259 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
260 | "residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)\n",
261 | "plt.imshow(residual, cmap='jet', alpha=.5)\n",
262 | "plt.show()\n"
263 | ]
264 | },
265 | {
266 | "cell_type": "code",
267 | "execution_count": 25,
268 | "metadata": {},
269 | "outputs": [
270 | {
271 | "name": "stdout",
272 | "output_type": "stream",
273 | "text": [
274 | "a sample from generated anomaly images(random noise image)\n"
275 | ]
276 | },
277 | {
278 | "data": {
279 | "image/png": "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\n",
280 | "text/plain": [
281 | ""
282 | ]
283 | },
284 | "metadata": {},
285 | "output_type": "display_data"
286 | },
287 | {
288 | "name": "stdout",
289 | "output_type": "stream",
290 | "text": [
291 | "100/100 [==============================] - 0s 4ms/step\n",
292 | "300/300 [==============================] - 0s 322us/step\n"
293 | ]
294 | },
295 | {
296 | "data": {
297 | "image/png": "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FCvc9/rrr3PppZeyevVqDj74YG6++WaWLVtGY2Mjf/rTn2hsbGw79oADDuCll17ikksuaQsv3HDDDXzuc59j9erVTJ8+nXfffRewDvW+++7jhRde4Pnnn+fee+9lxYoVAKxbt44rrriCNWvWsGbNGh588EGeffZZbrvtNn74w+wyvZaVK1eyYMECXnnlFRYsWMD69evZtGkTs2fP5qmnnmLlypUsXbqUJUsyKzj+93//NwMGDODll19m1apVnHzyyTQ3N/Otb32Lhx9+mOXLl3P++edzzTXXAPDcc88xfvz4tvO/+c1vsnTpUlatWkVTUxOPPfZY2759+/bx4osvcscdd3DDDTcAcOeddyIivPLKKzz00EOce+65bessVq1axaJFi1i6dCnXXHMNvXr1YsWKFXz2s5/l/vvvB2DGjBksXbqUl19+mSOOOIKf/SxzKdKhhx5KXV0dK1euBOC+++7jvPPOA6CmpobPfOYzvPzyy7H//nGoeocfNinrMm3cQJ676gvcfuZYAL6zYGWHUVmckbvfk4FSfcT5zuXCwQcfzDHHHNP2fuHChRx11FGMGzeO1atX89e//rVt34wZMwAYP348b7/9NgDPPPMMX/mKLUl76qmn0rdvXwCeffZZpk+fTu/evdlvv/2YMWNG2yh46NChjBo1ipqaGkaMGMGkSZMQEUaNGtXWbjaTJk2irq6Onj17cuSRR/LOO++wdOlSTjzxRPr370+3bt0455xzOsTeR40axe9//3tmz57Nn//8Z+rq6li7di2rVq3iS1/6EmPHjuWmm25iw4YNAGzevBmvPtfTTz/NxIkTGTVqFE899RSrV68OvR/PPvts2/04/PDDOfjgg3nttdcA+PznP0+fPn3o378/dXV1nH766W02uuevWrWK4447jlGjRvHAAw9kXM/l61//Ovfddx8tLS0sWLCAs88+u23fJz/5STZt2uR7D3OlYrN04mbIxJ2U9UvPvHzBSuY8upo5U0YwoD7NRp+2akVoNSbQBs3kqT5yTQSIonfv3m2v33rrLW677TaWLl1K3759mTVrVsYq4B49bN3w2travMIGbjtgR6Xu+5qamsB2veckuf5hhx3GSy+9xG9/+1uuvfZaJk2axPTp0xkxYgR/+ctfOhyfTqfbPvOePXu49NJLWbZsGYMHD2bOnDl53Y84n3vWrFksWbKE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\n",
298 | "text/plain": [
299 | ""
300 | ]
301 | },
302 | "metadata": {},
303 | "output_type": "display_data"
304 | }
305 | ],
306 | "source": [
307 | "from sklearn.manifold import TSNE\n",
308 | "\n",
309 | "## t-SNE embedding \n",
310 | "\n",
311 | "# generating anomaly image for test (radom noise image)\n",
312 | "\n",
313 | "random_image = np.random.uniform(0,1, (100, 28,28, 1))\n",
314 | "print(\"a sample from generated anomaly images(random noise image)\")\n",
315 | "plt.figure(figsize=(2, 2))\n",
316 | "plt.imshow(random_image[0].reshape(28,28), cmap=plt.cm.gray)\n",
317 | "plt.show()\n",
318 | "\n",
319 | "# intermidieate output of discriminator\n",
320 | "model = anogan.feature_extractor()\n",
321 | "feature_map_of_random = model.predict(random_image, verbose=1)\n",
322 | "feature_map_of_minist = model.predict(X_test[:300], verbose=1)\n",
323 | "\n",
324 | "# t-SNE for visulization\n",
325 | "output = np.concatenate((feature_map_of_random, feature_map_of_minist))\n",
326 | "output = output.reshape(output.shape[0], -1)\n",
327 | "anomaly_flag = np.array([1]*100+ [0]*300)\n",
328 | "\n",
329 | "X_embedded = TSNE(n_components=2).fit_transform(output)\n",
330 | "plt.title(\"t-SNE embedding on the feature representation\")\n",
331 | "plt.scatter(X_embedded[:100,0], X_embedded[:100,1], label='random noise(anomaly)')\n",
332 | "plt.scatter(X_embedded[100:,0], X_embedded[100:,1], label='minist(normal)')\n",
333 | "plt.legend()\n",
334 | "plt.show()"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {},
341 | "outputs": [],
342 | "source": []
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {},
348 | "outputs": [],
349 | "source": []
350 | }
351 | ],
352 | "metadata": {
353 | "kernelspec": {
354 | "display_name": "Python 2",
355 | "language": "python",
356 | "name": "python2"
357 | },
358 | "language_info": {
359 | "codemirror_mode": {
360 | "name": "ipython",
361 | "version": 2
362 | },
363 | "file_extension": ".py",
364 | "mimetype": "text/x-python",
365 | "name": "python",
366 | "nbconvert_exporter": "python",
367 | "pygments_lexer": "ipython2",
368 | "version": "2.7.14"
369 | }
370 | },
371 | "nbformat": 4,
372 | "nbformat_minor": 2
373 | }
374 |
--------------------------------------------------------------------------------
/.ipynb_checkpoints/anoGAN_MNIST-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Keras implementation of AnoGAN \n",
8 | "\n",
9 | "https://arxiv.org/abs/1703.05921\n",
10 | "\n",
11 | " Abstract \n",
12 | "\n",
13 | "질병의 예후를 모니터링하기 위해 이미지 마커를 잡아내는 모델을 얻는 것은 매우 어려운 일이다. 보통의 모델은 자동 감지를 위해 알려진 마커의 주석이 달린 예제를 사용하여 많은 양의 데이터를 기반으로 한다. 주석처리(라벨링) 작업과 이미 알려진 것들에 대해서만 탐지 가능하다는 점은 그런 방식의 단점을 작용한다 이 논문은 이미지에서 어노말리를 찾기 위해 비지도학습 이용하다. 우리가 제안한 anoGAN은 정상적인 변동성의 다양함(정상 데이텅의 분포)를 학습한 DCGAN과 이미지 공간에서 잠재공간으로의 매핑방식을 기반으로 어노말리 스코어를 계산한다. 새로운 데이터에 적용했을때 모델은 어노말리와 어노말리 스코어를 계산한다. 이 방식을 망막의 광학 단층 촬영 영상에 적용한 결과, 망막 유체 또는 반사성 초점을 포함하는 이미지와 같은 변칙적인 영상(어노말리)을 정확하게 식별함을 확인하였다.\n",
14 | "\n",
15 | "\n",
16 | "\n",
17 | "\n",
18 | " 1.train DCGAN with normal image \n",
19 | "* Radford, A., Metz, L., Chintala, S.: Unsupervised representation learning with deep convolutional generative adversarial networks. arXiv:1511.06434 (2015)\n",
20 | "\n",
21 | " 2.Mapping new Images to the Latent Space \n",
22 | "* 신규데이터(a query image x)가 들어오면 우리는 신규이미지 x와 시각적으로 가장 유사한 이미지 G(z)에 대응하는 z를 찾는 것이 목적이다. \n",
23 | "* best z를 찾기위해 처음에는 랜덤하게 뽑은 z1를 학습된 generator에 입력값으로 넣어 G(z1)를 얻는다.\n",
24 | "* G(z1)를 기준으로 loss를 계산한다. 이때 loss는 latent space에서 z1이 z2로 이동을 의미하는 z1의 coefficient를 업데이트할 그래디언트 역할을 한다. (z2 = c * z1, c는 backpropagation을 통해 결정)\n",
25 | "* 신규데이터와 가장 유사한 G(z)를 찾기 위해, latent space에서 z의 위치는 역전파를 통한 반복적인 계산을 통해 최적화된다. (500 backpropagation steps)\n",
26 | "\n",
27 | " 2.1 loss \n",
28 | " - z를 최적화기위해 사용한 loss는 2가지로 구성된다. \n",
29 | " - residual loss : G(z)와 x와의 차이값 \n",
30 | " \n",
31 | " - discrimination loss : discriminator의 중간레이어 결과값의 차이\n",
32 | " \n",
33 | " f(·) : output of an intermediate layer of the discriminator \n",
34 | " - overall loss : residual loss와 discrimination loss의 가중합 (논문에서 사용한 람다=0.1)\n",
35 | " \n",
36 | "\n",
37 | " 3.anomaly score \n",
38 | "* 2의 맵핑과정을 통해 최종적으로 얻은 loss값을 사용한다\n",
39 | "* 또한 신규이미지에서 anomaly의 영역을 규명하기위해 가장 유사한 이미지와 신규이미지와의 차이 이미지(residual image)를 사용하였다. \n",
40 | "\n",
41 | "\n",
42 | "\n",
43 | "\n",
44 | "\n",
45 | "\n"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {
52 | "scrolled": false
53 | },
54 | "outputs": [
55 | {
56 | "name": "stdout",
57 | "output_type": "stream",
58 | "text": [
59 | "#### discriminator ######\n",
60 | "_________________________________________________________________\n",
61 | "Layer (type) Output Shape Param # \n",
62 | "=================================================================\n",
63 | "conv2d_53 (Conv2D) (None, 14, 14, 64) 1664 \n",
64 | "_________________________________________________________________\n",
65 | "leaky_re_lu_53 (LeakyReLU) (None, 14, 14, 64) 0 \n",
66 | "_________________________________________________________________\n",
67 | "dropout_43 (Dropout) (None, 14, 14, 64) 0 \n",
68 | "_________________________________________________________________\n",
69 | "conv2d_54 (Conv2D) (None, 7, 7, 128) 204928 \n",
70 | "_________________________________________________________________\n",
71 | "leaky_re_lu_54 (LeakyReLU) (None, 7, 7, 128) 0 \n",
72 | "_________________________________________________________________\n",
73 | "dropout_44 (Dropout) (None, 7, 7, 128) 0 \n",
74 | "_________________________________________________________________\n",
75 | "flatten_22 (Flatten) (None, 6272) 0 \n",
76 | "_________________________________________________________________\n",
77 | "dense_31 (Dense) (None, 1) 6273 \n",
78 | "=================================================================\n",
79 | "Total params: 212,865\n",
80 | "Trainable params: 212,865\n",
81 | "Non-trainable params: 0\n",
82 | "_________________________________________________________________\n",
83 | "#### generator ######\n",
84 | "_________________________________________________________________\n",
85 | "Layer (type) Output Shape Param # \n",
86 | "=================================================================\n",
87 | "dense_32 (Dense) (None, 6272) 633472 \n",
88 | "_________________________________________________________________\n",
89 | "leaky_re_lu_55 (LeakyReLU) (None, 6272) 0 \n",
90 | "_________________________________________________________________\n",
91 | "reshape_6 (Reshape) (None, 7, 7, 128) 0 \n",
92 | "_________________________________________________________________\n",
93 | "up_sampling2d_11 (UpSampling (None, 14, 14, 128) 0 \n",
94 | "_________________________________________________________________\n",
95 | "conv2d_55 (Conv2D) (None, 14, 14, 64) 204864 \n",
96 | "_________________________________________________________________\n",
97 | "leaky_re_lu_56 (LeakyReLU) (None, 14, 14, 64) 0 \n",
98 | "_________________________________________________________________\n",
99 | "up_sampling2d_12 (UpSampling (None, 28, 28, 64) 0 \n",
100 | "_________________________________________________________________\n",
101 | "conv2d_56 (Conv2D) (None, 28, 28, 1) 1601 \n",
102 | "=================================================================\n",
103 | "Total params: 839,937\n",
104 | "Trainable params: 839,937\n",
105 | "Non-trainable params: 0\n",
106 | "_________________________________________________________________\n"
107 | ]
108 | },
109 | {
110 | "name": "stderr",
111 | "output_type": "stream",
112 | "text": [
113 | "\r",
114 | " 0%| | 0/200 [00:00, ?it/s]"
115 | ]
116 | }
117 | ],
118 | "source": [
119 | "import numpy as np\n",
120 | "import matplotlib.pyplot as plt\n",
121 | "from keras.datasets import mnist\n",
122 | "from tqdm import tqdm\n",
123 | "import anogan\n",
124 | "\n",
125 | "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
126 | "X_train = X_train.astype(np.float32)/255.\n",
127 | "X_train = X_train.reshape(60000, 28, 28, 1)\n",
128 | "\n",
129 | "\n",
130 | "Model_d, Model_g = anogan.train(32, X_train)"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": 2,
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "data": {
140 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJIAAACPCAYAAAARM4LLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAADYdJREFUeJztnd+PVdUVx79r+KEoovwSEQggIkriQw3WNu1DEzChvvDWqEnTB5O+tEmb9KHa/gN96oNJX0xq7END04Qm+kBiKKFpME0jJqZFyfCjCgwODPgTfzPD7sNcb9b+zNxzDne2594Z1ych3HXPvefuc1ic/d1rr722pZQUBHNlZNANCBYG4UhBEcKRgiKEIwVFCEcKihCOFBQhHCkoQjhSUIQ5OZKZ7TWzUTM7bWZPl2pUMP+wfiPbZrZI0klJj0oak/SqpCdSSm/2+s6yZcvSihUruvb169ez419++WVms21m1n09MpL/H1i0aFHPz/Zo/w19fvHixZXHq+B1sq3Xrl2rbAuP877w/P541T2UpCVLllS2bWJi4kpKaa1q6P/uSN+WdDql9L9OA/8iaZ+kno60YsUKPfnkk137k08+yY6PjY1l9ueff57ZN998c/f1TTfdlB27/fbbM5vHCW8YP88bvmrVqsz2/3h0Mv7Dfvrpp5l9xx13ZDav21+nJF28eDGzv/jii0rb/4ekE7Kt69evz+zbbrsts5999tmzasBcurYNks47e6zzXoaZ/dTMjpnZsc8++2wOPxcMM1+72E4pPZdS2pVS2rVs2bKv++eCATGXru2CpE3O3th5ryfXr1/X1atXu/bly5ez4+zKqJk81EgffvhhZrOr4ufZ/axcuTKzP/7448y+5ZZberaV3SA/+9FHH2U2dQm7n+XLl2c2r6WuK/Xt8fd7tt/mdfbLXJ5Ir0rabmZbzWyppMclvVSkVcG8o+8nUkpp0sx+LullSYskPZ9SeqNYy4J5xVy6NqWUDko6WKgtwTxmTo50o0xOTuq9997r2v71bExNTWW21wLUBRwiU/NwxMhhLofkDE1cuXKl5/mWLl2aHaPWo4bicJ3fZ1upoSYmJirb6s9HHUr43dWrV1d+vhcxRRIUIRwpKEI4UlCEVjXS1NRUFreYnJzMjjNgSR3kv0sdQjgFQs20bdu2zN6xY0dmnz9/PrM5leBjXHVxHWocxscYN+K1UStSD547dy6z77zzzu5raiCeizbjbU2JJ1JQhHCkoAjhSEERWtVIIyMjWYyD2oLxk6pcGuopaqA1a9ZkNuer7rrrrsymbuGcFHWIb/utt96aHaMmor7i3Bv1GWM/TDOhrqEO8jqHbeN3eV/6nViPJ1JQhHCkoAitdm1S3j1xiF6X0uAzB/kI3rAhz6ljt8iuil1ZXSoHuwR/Pk63cPi+bt26ynPXTecwnMCpJXZtFy70zuZhpienb3wq9I0QT6SgCOFIQRHCkYIitKqRFi9enA3LGY5nqgZ1jddFTPu45557Mpsa6NKlS5nNlRrUNdQ9u3btymyfCrJ9+/bsGNM8GObgcP7w4cOZfeLEicw+fvx4ZjMUwVUqXs9RKzKFhZqI/wZNiSdSUIRwpKAI4UhBEVrVSCmlLHWE/XdVrEbK+3PqDvb9nIZgzIoaqm6Z9FtvvZXZH3zwQff1+Ph4doxTHFwFzDQQnpv3pWpZljTzPvlpKJ6L2pIaiXGmpsQTKShCOFJQhHCkoAitaySvZerSZblMx89JsW9/++23M7tOlzCG9cgjj2Q2NdemTZsy+/333+/R6plzYWzru+++m9lcVu3112zn433jXJyH6cxMIWa8jDGppsQTKShCOFJQhHCkoAitayQfn2Gspq4UoNcOjI9wfouahumu999/f2bfd999mV2nW/zvMX/o5MmTmc20XsJrqSsFSH3H7/s5SeZ4VekpaWYsrynxRAqKUOtIZva8mU2Y2XH33iozO2Rmpzp/r6w6R7DwafJEekHSXrz3tKTDKaXtkg537OAbTK1GSin908y24O19kn7Qef0nSf+Q9Ou6c7GsDWMWjBsxt9nPE9Ut7+YynHvvvbfy3Jxj4lwe41J+Po35RO+8805mM4bll1RLM2M5dW05depUZjOu9PDDD3dfv/baa9kxzsuxjA2PN6VfjbQupfTVTOVFSeuqPhwsfOYsttP0kKFn1XdfHpmjkWDh0K8jXTKz9ZLU+Xui1wd9eeR+H5vB8NNvHOklST+R9LvO3y82+dLIyEimbRgnYllh6pKqbR44N3b33XdnNmMt1B1sC+fSGIfyGmv37t3ZMeZc80lMvcYYVd06NsI4ltdk1E+ce6Ndt5VGL5oM//dL+pekHWY2ZmZPadqBHjWzU5L2dOzgG0yTUdsTPQ7t7vF+8A0kIttBEQa69r9umwfmWVfNtdWVpaFmYiyHxxmHYtzKr6M7eDAvNV61zmy2tlF/sSQPt8egHuRa/507d3Zf1+Wuc06SMS2uqetFPJGCIoQjBUUIRwqK0KpGMrPKLT15jDENr1uor2g/8MADmU1NVbfDJPOR1q7Nd+P02oK5TayHdPr06czeuHFjZlND8beo586cOZPZzDnytQEYR+I95nVSQzUlnkhBEcKRgiK0XtbGp0jwkc5QP4f0Pr2V0yd1FXK3bt2a2Rz2MoWFQ3Qu49m/f3/3NcvUMG133759mc3hPpdScaqIw38eZ6jCd3W8Lpbz4bk2b96sfognUlCEcKSgCOFIQRFar/zv+2T23xyKVu26zVQLDls5ROb0C22m3lKXUJN5+5VXXsmOUY8x1MC2Mt2VaSecEuF0DdvmwwcsmUPdSbsuZaUX8UQKihCOFBQhHCkoQutTJL5/Z99el0bipzkYO+EWEtQ8jJ8whsU40YEDBzL77NmzmX3kyJHua2ocLifilAevmxqI+o/f57VQD1btRs77wmkoasOmxBMpKEI4UlCEcKSgCK2n2nqogRhHomaqWsrEc3H+ihqI6axclsOlzrR9vIVbSDDOw7ZRt3CbLNqMK7GUIHWO11ycg+R18jg1VFPiiRQUIRwpKEI4UlCE1uNIXi9QO3DpDOfifK4MNc62bdsy+9ixY5l96NChzKbG4pKeurk8r9/27NmTHeOWXLwO/jbjRNRADz30UGZziTfxcSbeJ6YcM+bFGFVT4okUFCEcKShCOFJQhIGWR2ZMo04j+W0y+VnOd3HZNDUPtQG3KmXbqJF8/IWaiMue+V3mkzN+Rh3Da6XNOJK/dsbiqL8Y8wqNFAyUJvWRNpnZETN708zeMLNfdN6PEslBlyZPpElJv0op7ZT0HUk/M7OdihLJgaNJoa1xSeOd11fN7ISkDeqzRLLvs6t0Bz8r5bqGuuLo0aOZzbk1lijmVlfUGcyzZg6RXxfnt/+SZmocLqnmOjjqEn6e22PwWth2fx+pHWlzXRv1XVNuSCN16m1/S9K/FSWSA0djRzKz5ZIOSPplSikbNlSVSPblkTlaCRYOjRzJzJZo2on+nFL6W+ftRiWSfXlkDjWDhUOtRrLpDviPkk6klH7vDvVVItnnSjNOVLem3W8hwTgP55+YB121pflsv019Rs3k5/2YP1RXhpBtZwyrLm5Ul9Ptr4V1BrjlV7/bapEmAcnvSfqxpP+a2eud936jaQf6a6dc8llJPyrSomBe0mTUdlRSryreUSI5kBSR7aAQrc61TU1NZfGfurVmxOdJc406NQ91CDUQdQvL9T344IOVx30JYq6pYxyI8TLqLT+HKM3UTNSK/H7VlmC8L5xr89uFSTPn3poST6SgCOFIQRHCkYIitJ6z7eMzzBliX08N5fOPmU9EuE0W4W/z84xLUVP5+a/x8fHsGGNYnAtjnInzhpwBqJsR4H3zuojasK78cVX56iriiRQUIRwpKELrS7b9o7OuC+A0hR8m1+3yw+r67CZZvoVdpR/eSzN3T/LpGHVLsut2N2K3yq6O52OqB7svn9bCtjHEUrejZFPiiRQUIRwpKEI4UlCEgW4hwb6fQ08O0f0wm9MEXJpM3cAUU8J0C79DpDQzndZrLpZxpubh8TrdwmkNaiqWuana7ZJpv9RAPM7fako8kYIihCMFRQhHCoow0C0kmLKwZcuWzGYKq+/PGXPiVgl1pZYZV6JeGx0dzWzqEq/R6srWUCNR09SVPGSM60Z2vyylgeqIJ1JQhHCkoAjhSEERWk+15dIaD7VAVZlh9vV1ZX+pgahrqIGocxjT8tqDv1W3WzjPTU3E43XLyan//L2gRmLMivcl5tqCgRKOFBQhHCkogrEP/Vp/zOyyplflrpF0pebjg2JY2zaodm1OKa2t+1CrjtT9UbNjKaVd9Z9sn2Ft27C26yuiawuKEI4UFGFQjvTcgH63CcPatmFtl6QBaaRg4RFdW1CEVh3JzPaa2aiZnTazgZZTNrPnzWzCzI6794aidvh8rG3emiOZ2SJJf5D0Q0k7JT3Rqdc9KF6QtBfvDUvt8PlX2zyl1MofSd+V9LKzn5H0TFu/36NNWyQdd/aopPWd1+sljQ6yfa5dL0p6dFjbl1JqtWvbIMlXUR/rvDdMDF3t8PlS2zzEdg/S9H/7gQ5p+61tPgjadKQLkvwC/Y2d94aJRrXD22Autc0HQZuO9Kqk7Wa21cyWSnpc07W6h4mvaodLN1A7vDQNaptLA2zfrLQsGh+TdFLSGUm/HbCA3a/pzXquaVqvPSVptaZHQ6ck/V3SqgG17fua7rb+I+n1zp/HhqV9s/2JyHZQhBDbQRHCkYIihCMFRQhHCooQjhQUIRwpKEI4UlCEcKSgCP8H/jLLUHqvsdkAAAAASUVORK5CYII=\n",
141 | "text/plain": [
142 | ""
143 | ]
144 | },
145 | "metadata": {},
146 | "output_type": "display_data"
147 | }
148 | ],
149 | "source": [
150 | "## generate random image \n",
151 | "\n",
152 | "generated_img = anogan.generate(3)\n",
153 | "plt.figure(figsize=(2, 2))\n",
154 | "plt.imshow(generated_img[0].reshape(28, 28),cmap=plt.cm.gray)\n",
155 | "plt.show()"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": 5,
161 | "metadata": {},
162 | "outputs": [
163 | {
164 | "data": {
165 | "image/png": "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\n",
166 | "text/plain": [
167 | ""
168 | ]
169 | },
170 | "metadata": {},
171 | "output_type": "display_data"
172 | },
173 | {
174 | "name": "stdout",
175 | "output_type": "stream",
176 | "text": [
177 | "anomaly score : 29.612060546875\n"
178 | ]
179 | },
180 | {
181 | "data": {
182 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJIAAACPCAYAAAARM4LLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAEpVJREFUeJztnWtwVdd1x/9b916Jq+eVEOiFLAkhHkIKxhIvG9clLi7YcWjsxjWZsZ2Om06n9YwzTTtNmo4/ZKaPadp+SqYdZ0qTtrEdx3HqR+IYvzAmYAwYA8I8BEiAACGBQLp6IK6k3Q8SOue/ZME12j4SeP1mGM7/7ss5W5elvddde+21jbUWijJRUia7A8rNgRqS4gQ1JMUJakiKE9SQFCeoISlOUENSnKCGpDhhQoZkjFljjDlkjDlijPm2q04pNx7meiPbxpgQgMMAVgNoAbADwHpr7cfj/Zv0qLGxLE/3hyPUnmoTpK0xpPswbfQ6An7vJV8bAKRgiPQ0XCIdTnD7pUjaeN0GAAwiRLprMGf0Oha6QG0D4r1D4vc1DZe5b4l+fhh3DRgQuo9lf37q2A5feVY/P2sgjfsWRyb3RXxOF8/0n7PWzhj3ASOEr/WGq7AUwBFr7TEAMMY8B2AdgHENKZYFfONBTzfNLKD20kQL6UsR/oAOYP7odRFOU9tBXxsApKOX9HwcJJ13Ok764+JbSBvwL1gnYqQ3dq4ZvV6V8wtq60Au6V6kky5HM+kFp46QFv+XwDmhG1geebwI4zGn8Tjp9qos0u/hd0jPxSHSL37vEN9gHCYytZUAOOnTLSOvEcaYPzXG7DTG7Oztk63KzcJn7mxba5+21tZba+vTo5/105TJYiJT2ykApT49a+S18TEAfMZ0FoXUXBA5e9V/Pt03xqeB/YpqMaNuxe2kL4rp5p4ZG0kPio+itu0A6faZPLVF0r35Jyz8tVNiYI4IJ+f/En9AeqDkV6SNcJJmVLaTLpjWQfoV3E96DX7jCZ5Vx0zZx1BBupQmmeSZyIi0A0CVMabCGJMK4GEAL0/gfsoNzHWPSNbaAWPMEwBeBxACsMFau99Zz5QbiolMbbDW/hrArx31RbmBmZAhfWq6AWzxZN09O6l5IMQxjh7wV9UueLGbk+SeAYVoJd0L9uwL0EY6fJ67llvIfgeaWO6cWU86JcXzY/LA//ZBy+GAtGb2eU5UsG8YxiDpXeBn7cUXSD9U/XPSlwc5TNIS8j6bUyXsr4XEsxZhL+npY2INyaFLJIoT1JAUJ6ghKU4I1kdKAeBb0joYWvCp/vmtm721gbObuK3gj1iXz20m3WiqSHcWcoDlMsR6VTXLtW1vkp4x04vtyHW4/WYh6T0Vi0jnoIv0fHDM6r7+10innOC+9FXx827DbtILfDG1t7GK2r4K9q+OYg7p2X3Bx5EUZRQ1JMUJakiKE4L1kVJBq3OzwJP/+1hB+qJI3aiNeL5EwR/yrV+Yt460zPmZCV7H2wv2W+7s2sY37BSydPxUkJ/jq9QmU1ikjuEi6eqLjaS7Y5wb1VrFcSfpk8VFvC0BL8+rHruoLdrFcaTSbOETcWpV0uiIpDhBDUlxQrBT2xAo+y+3p4ea52Vwdl5U5pT6VyJ4hEYPMkhngTMg28DZmLsbl5CuqDpG+lI2p+62ipSX5Ynto9exCE9VM8BpH1XgqUtObVtiy0jLJRdJdRffb14T971zkTcNn0YxtQ2JjGL5ueWk8DScLDoiKU5QQ1KcoIakOCFQH6knGsWOWm+3x2aspPao2D7xCP6Hb+DLWO1/l5se2/cMv/AV8XB2mZBZxS/Mios0X3ZjkFrKqb3W9yu4DNupTW6NehEPkF6Hl0jLNJFVeIf0gh+JXSYPsoTwe/xbtcpFPkwKb9RBeyXvNCoW/l2y6IikOEENSXGCGpLihEB9pDAGkO+bgx/Df1P7eUwnnXWKfabEl7zrn617mNoereb3FtZ9mXR+fA/pL51gv2P7udmkG7t52eGDjnLS96e8MnpdOsjLDPtCtaQfxAuk5danCpnXK/kay6aMWaQTeXy/U/Da88E5xZmV8XHfCwDZhZziMrzv9droiKQ4QQ1JcYIakuKEQH2ktP4EKo765lwOt+BiCaeNnCnJJx3z5Tg8Gn+O2r7Z9CS/dw0X0eiu5LWyrlvnki7D35Eu6Odt2AvbeTf6Qnh+kNyiXQrud4nwM/aBfajU/dyXBQt5i9Ca135CesuG35J+dnsz6VXzffo+MCI9pqGY+yK3wieLjkiKE9SQFCeoISlOCNRH6k+LoKnSywuSZeZkzo/E374kawe1vfwGF0IpmM75R+2tvBU5sYT3G+0q4i3gt5XnkK6bxduVMjq9LeHTcmZS2zxRxiYmto9XDXGKcUMO+yXhLL5f9Rru69Ya/tnu2vAD0v6wVHcGL8RlpvCzoiINWP6fJIuOSIoTrmlIxpgNxpg2Y0yD77U8Y8wbxpjGkb9zr3YP5eYnmRHpxwDWiNe+DeAta20VgLdGtPI55po+krV2szGmXLy8DsDvjlz/BMAmAH9zrXuFMIRMdI/qGbs56adI+DGicg3O1uSNXncgj9q2reQ85+YWHiQzxBYebBPVW3t4O1JlPt8vVsgl8kpOvzp6nV3C63ZHUUn6y6KQ3dPdj5Be2cMxrH95gkv5IYfLROftYf9wa4kok1PiJbTLEjnhqChBLcYSWfYmWa7XRyqw1p4ZuW4FRGa98rljws62Ha74Pm7Vd3955L5eWYlcuVm4XkM6a4wpAoCRv9vGe6O/PHI0Xb8k3qxcbxzpZQCPAfinkb9fuvrbh7EQxylwsX4kOHUZu0I8v/vn7wKcoTb/NmVg7LZmudfsGZHkk57B8ZSavvdIv/Q8z94Nt3nby7OPcQ5PCOwzbRblk5uOc19WruXq+9um3Uv6fBf/rD/bv5V0VPiLCxNeWZt7wq9T23HDJxw0iHxxmRMGJLfPLZmv/88C2AZgnjGmxRjzOIYNaLUxphHA741o5XNMMt/a1o/TdLfjvig3MOq0KE4IdK0tgQjO+Pait0XZ77gFnEOUIzaXzRn0fI/eEJeZGQLHWuQJRAU9HBf6RsaPSP8H/oy09LGE24P+Nu94qoL7uHGBOM5C+me3VvPP+cR9d5DuSOGSPLvefYX0xt9w+Z+8u3hPXnmkefT6LHjdrmKwmfSsEOdZpe9ify5ZdERSnKCGpDhBDUlxQqA+0jT00wmF6X1iPuZUZfQuYx8p8rZ3nVPH8Y038rgMcBPKSFdlsB9zu+VYjHCxxvg5ry4XxQR8XZPljftFMrrM0Y7lfp30tgzON0rv49Mxq59/lfRT9Rz/7Rab/zOPezlH8TKuMdUd4npIY/KPxj/V9KroiKQ4QQ1JcUKgU9tlpKIZXoi+J8onPM9Zdpi0PPA4/4ve0Ury1AB5ILEcst/b/UXWQ6zxK66T8/3K73I7zzbI+msvnCCr78pt0DW3cNpu9UNLSSdEX//+7g9J163mn61QbBkKyWO48732DF/aDgAcFydGbsadpB+ofZHv9curn+p5BR2RFCeoISlOUENSnBDs1/9EP6pPe6V9dxQvvur7VzVt4Rd8033tbP7KLU/FPl7BZYEfWPxL0pmH2M/43vqnSM+q4lIz7YNcIs9/ytA2caL3gTj7b0Upv08ar/H2pMy650mfnM9bvB8S6zPhQU6HjXCkAv7VndxGLkGde7SB3/qXfK9ZB5PziSQ6IilOUENSnKCGpDgh2CMkLgPwZS0sEScfjgnPy7nfnz0h9xGIEsFjYztceiZ7HqfHloKPYcgE+xZVIfZT/Gm/00V5vbI89jOqxCmNg/v42f+wh+NAQ//Ffsz3F3FMq3Qd97Wqlo+UWGK97UppPeKDEunNu8UpUfnzZXnk5E7d1hFJcYIakuIENSTFCcH6SNMAzPPkjuzFopnXnGoXc2zIv+NoQJQNDIsjHxZ1CQdL7Ko5XFhOWpYRlnSL46iKejzf4UIGbxf62h3sE50NFZE+8hb7W4lKLuWHCnH6OFcSHHM0lvTRThnPH8xdwinGsjRz83kuO3hhOp84qT6SEihqSIoT1JAUJwR/FKlvvawjm/Ns2sHrWSeLua7NvRc3jl6Hd4p7ZwodE5rDQpjb08z6IGu0in8v8pH8VQrv+hY//E+WcT7SU028rvdu7ybSs8UREj2P8P1kqZkUEURrEfV/Vse9Y7oOZLG/tmAr+2d/dfs/kk5/RrcjKZOIGpLiBDUkxQmB+kg2DCR8u7RlTCNDODL9YvHto1jN6HVNPa9HDYb5d0KWbzmXxf5XvthGPaOOde5p4VTx7dC3zPtBVq9dR22boneRbtzDa2EtDZxv1F3L25Hi+7hMTUbtBdLy6FNZBvFclpcjvgt13HFOncL7WE76j9f9L7/hX5EUOiIpTkimPlKpMeYdY8zHxpj9xpgnR17XEsnKKMmMSAMAvmWtrQawHMBfGGOqoSWSFR/JFNo6AwzX2bPWxo0xBwCU4DpKJPeaKPaEvLWdTmRTew32k5Z71XLhrRudjnBJ4OIEB37m7m1mPZf1zizOw5l7lNvlElNKJe/pfrLK84viuXyMaXsHn2W1+eT7fDN2SzAHR0nHajlIthi8zy26jeNKDSvmke7yfa4xURronIjVyZjUuQzegzfmXK5x+FQ+0ki97cUAtkNLJCs+kjYkY0wmgF8A+Ka1llL8rlYi2V8e+XLvwCe9RbkJSMqQjDERDBvRT621V/b0JlUi2V8eOTU92BUZJTiu+T9rjDEA/hPAAWvtv/maPnWJ5EGEKJc6D5wrI+NGcu1tLrzaALKM76UIJyjNqWkm/WEa+0Sy1Ezt7H2kN1dyLGjVdI79FNd7OUbbxcLeB6//lHRvL5ffQx77IbI8n/wc3hF1X+9csZn0b8GlA6t9ZXbuxpvUFo2zfzWUxb5fLJGcTyRJZoi4A8AjAPYZYz4aee1vMWxAz4+USz4O4KHr6oFyU5DMt7YtGFOGahQtkawA0Mi24ohAvd8UWMrLljna9bv3sL7A2p8D1FXNMahcES/Zm1ZDun6LuPdH4t6PsVxUyutbf/6oKP3nc2P+fSPHgZ5r4Pygy5u4lLOMUV1az/7d/Qku9dca4chK1hb+3B5ftoH0yYiXDxVtZZ+oozCL9B6xr+1YhGNigFh7GwcdkRQnqCEpTlBDUpwQqI8UxgDtwZL1DYc4LQcn07jGUZmvbLDc2y/9rTngHCBZK6DzCfZbLomSxkvrbiMdz2GfCz2eX/RhM+/lXxr5gHTJao5BNaOctDxi4nKEjwyT9ZdWrXybdEQc41Vxzvc8ThcfE5srFsnoBSKufBLJoSOS4gQ1JMUJgU5tgwihc8w+IY/WNB525TBcdsEbhpf1cWrF6Tx+b0L8aP138vAvSy/X3cJT3VeW8Vf4/WJJ5mKG93OkiDSPVDGfdIGXRIbE7+95sSd7q5jKZAryEVSRrgEv77Tke+GCw/mcYiKXpeRnLJ+VLDoiKU5QQ1KcoIakOCHgBCGLsO+rqjxFKC6+o4fFVuXuYq++X+Yp9kPk1/cT4nSkMtNMWvol5WXsA8XE996+Svah9nV4urWTy8wcGuS0jltCJ0ingU+IjIqaO2XgcEGh2D9+DLyMsRmc8vJhn1cuaOgS10Rcl/sC6WpRX3E+DpLegeTQEUlxghqS4gQ1JMUJgfpIIQwi27e9JQ+cqiFPtpYxDX/7xyUcS5GxmmLhZ2QhTlpuhao4xE5R/G5Or8ht3UT68g/+2bsOf53avhDi5Zm1HZzuCj7YemxZaM70QG8xL5nIz+mijFN1eH5RTgnnrMTFzdvE5h/pMyWLjkiKE9SQFCeoISlOCHitLYwLvhIsMk4UFukQsuyN3zfoBcd1ZNqITK2wYv/CAhEvee8tLpPzchsfb5GVYH/NX3pw6QqOtlSI4yjO5HHMKjOP02cGhM8jU2LSm/hnWVjBW9uzwWks0RLvZG0Zs1qe4JI4DRFOj4kNijrTSaIjkuIENSTFCWpIihPMcP2HgB5mTDuGd+XmI9mzCYJnqvZtsvpVZq2dca03BWpIow81Zqe1tj7wByfBVO3bVO3XFXRqU5yghqQ4YbIM6elJem4yTNW+TdV+AZgkH0m5+dCpTXFCoIZkjFljjDlkjDlijJnUcsrGmA3GmDZjTIPvtSlRO/xGrG0emCEZY0IAfghgLYBqAOtH6nVPFj8GsEa8NlVqh994tc2ttYH8AbACwOs+/R0A3wnq+eP0qRxAg08fAlA0cl0E4NBk9s/Xr5cArJ6q/bPWBjq1lYBrErSMvDaVmHK1w2+U2ubqbI+DHf61n9SvtNdb23wyCNKQTgF0ZuYsjM1enmySqh0eBBOpbT4ZBGlIOwBUGWMqjDGpAB7GcK3uqcSV2uFAkrXDPwuSqG0OTGL/PpGAncZ7ARwGcBTAdyfZgX0Ww4f1JDDsrz0OYDqGvw01AngTQN4k9W0lhqetvQA+Gvlz71Tp3yf90ci24gR1thUnqCEpTlBDUpyghqQ4QQ1JcYIakuIENSTFCWpIihP+H8IwEO2dyv+tAAAAAElFTkSuQmCC\n",
183 | "text/plain": [
184 | ""
185 | ]
186 | },
187 | "metadata": {},
188 | "output_type": "display_data"
189 | }
190 | ],
191 | "source": [
192 | "## compute anomaly score - sample from test set\n",
193 | "\n",
194 | "X_test = X_test.astype(np.float32)/255.\n",
195 | "X_test = X_test.reshape(-1, 28, 28, 1)\n",
196 | "test_img = X_test[0]\n",
197 | "\n",
198 | "model = anogan.anomaly_detector()\n",
199 | "ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))\n",
200 | "\n",
201 | "plt.figure(figsize=(2, 2))\n",
202 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
203 | "plt.show()\n",
204 | "print(\"anomaly score : \" + str(ano_score))\n",
205 | "plt.figure(figsize=(2, 2))\n",
206 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
207 | "residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)\n",
208 | "plt.imshow(residual, cmap='jet', alpha=.5)\n",
209 | "plt.show()"
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": 6,
215 | "metadata": {},
216 | "outputs": [
217 | {
218 | "data": {
219 | "image/png": "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\n",
220 | "text/plain": [
221 | ""
222 | ]
223 | },
224 | "metadata": {},
225 | "output_type": "display_data"
226 | },
227 | {
228 | "name": "stdout",
229 | "output_type": "stream",
230 | "text": [
231 | "anomaly score : 446.46844482421875\n"
232 | ]
233 | },
234 | {
235 | "data": {
236 | "image/png": "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\n",
237 | "text/plain": [
238 | ""
239 | ]
240 | },
241 | "metadata": {},
242 | "output_type": "display_data"
243 | }
244 | ],
245 | "source": [
246 | "## compute anomaly score - sample from strange image\n",
247 | "\n",
248 | "test_img = plt.imread('assets/test_img.png')\n",
249 | "test_img = test_img[:,:,0]\n",
250 | "\n",
251 | "model = anogan.anomaly_detector()\n",
252 | "ano_score, similar_img = anogan.compute_anomaly_score(model, test_img.reshape(1, 28, 28, 1))\n",
253 | "\n",
254 | "plt.figure(figsize=(2, 2))\n",
255 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
256 | "plt.show()\n",
257 | "print(\"anomaly score : \" + str(ano_score))\n",
258 | "plt.figure(figsize=(2, 2))\n",
259 | "plt.imshow(test_img.reshape(28,28), cmap=plt.cm.gray)\n",
260 | "residual = test_img.reshape(28,28) - similar_img.reshape(28, 28)\n",
261 | "plt.imshow(residual, cmap='jet', alpha=.5)\n",
262 | "plt.show()\n"
263 | ]
264 | },
265 | {
266 | "cell_type": "code",
267 | "execution_count": 25,
268 | "metadata": {},
269 | "outputs": [
270 | {
271 | "name": "stdout",
272 | "output_type": "stream",
273 | "text": [
274 | "a sample from generated anomaly images(random noise image)\n"
275 | ]
276 | },
277 | {
278 | "data": {
279 | "image/png": "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\n",
280 | "text/plain": [
281 | ""
282 | ]
283 | },
284 | "metadata": {},
285 | "output_type": "display_data"
286 | },
287 | {
288 | "name": "stdout",
289 | "output_type": "stream",
290 | "text": [
291 | "100/100 [==============================] - 0s 4ms/step\n",
292 | "300/300 [==============================] - 0s 322us/step\n"
293 | ]
294 | },
295 | {
296 | "data": {
297 | "image/png": "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FCvc9/rrr3PppZeyevVqDj74YG6++WaWLVtGY2Mjf/rTn2hsbGw79oADDuCll17ikksuaQsv3HDDDXzuc59j9erVTJ8+nXfffRewDvW+++7jhRde4Pnnn+fee+9lxYoVAKxbt44rrriCNWvWsGbNGh588EGeffZZbrvtNn74w+wyvZaVK1eyYMECXnnlFRYsWMD69evZtGkTs2fP5qmnnmLlypUsXbqUJUsyKzj+93//NwMGDODll19m1apVnHzyyTQ3N/Otb32Lhx9+mOXLl3P++edzzTXXAPDcc88xfvz4tvO/+c1vsnTpUlatWkVTUxOPPfZY2759+/bx4osvcscdd3DDDTcAcOeddyIivPLKKzz00EOce+65bessVq1axaJFi1i6dCnXXHMNvXr1YsWKFXz2s5/l/vvvB2DGjBksXbqUl19+mSOOOIKf/SxzKdKhhx5KXV0dK1euBOC+++7jvPPOA6CmpobPfOYzvPzyy7H//nGoeocfNinrMm3cQJ676gvcfuZYAL6zYGWHUVmckbvfk4FSfcT5zuXCwQcfzDHHHNP2fuHChRx11FGMGzeO1atX89e//rVt34wZMwAYP348b7/9NgDPPPMMX/mKLUl76qmn0rdvXwCeffZZpk+fTu/evdlvv/2YMWNG2yh46NChjBo1ipqaGkaMGMGkSZMQEUaNGtXWbjaTJk2irq6Onj17cuSRR/LOO++wdOlSTjzxRPr370+3bt0455xzOsTeR40axe9//3tmz57Nn//8Z+rq6li7di2rVq3iS1/6EmPHjuWmm25iw4YNAGzevBmvPtfTTz/NxIkTGTVqFE899RSrV68OvR/PPvts2/04/PDDOfjgg3nttdcA+PznP0+fPn3o378/dXV1nH766W02uuevWrWK4447jlGjRvHAAw9kXM/l61//Ovfddx8tLS0sWLCAs88+u23fJz/5STZt2uR7D3OlYrN04mbIxJ2U9UvPvHzBSuY8upo5U0YwoD7NRp+2akVoNSbQBs3kqT5yTQSIonfv3m2v33rrLW677TaWLl1K3759mTVrVsYq4B49bN3w2travMIGbjtgR6Xu+5qamsB2veckuf5hhx3GSy+9xG9/+1uuvfZaJk2axPTp0xkxYgR/+ctfOhyfTqfbPvOePXu49NJLWbZsGYMHD2bOnDl53Y84n3vWrFksWbKE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\n",
298 | "text/plain": [
299 | ""
300 | ]
301 | },
302 | "metadata": {},
303 | "output_type": "display_data"
304 | }
305 | ],
306 | "source": [
307 | "from sklearn.manifold import TSNE\n",
308 | "\n",
309 | "## t-SNE embedding \n",
310 | "\n",
311 | "# generating anomaly image for test (radom noise image)\n",
312 | "\n",
313 | "random_image = np.random.uniform(0,1, (100, 28,28, 1))\n",
314 | "print(\"a sample from generated anomaly images(random noise image)\")\n",
315 | "plt.figure(figsize=(2, 2))\n",
316 | "plt.imshow(random_image[0].reshape(28,28), cmap=plt.cm.gray)\n",
317 | "plt.show()\n",
318 | "\n",
319 | "# intermidieate output of discriminator\n",
320 | "model = anogan.feature_extractor()\n",
321 | "feature_map_of_random = model.predict(random_image, verbose=1)\n",
322 | "feature_map_of_minist = model.predict(X_test[:300], verbose=1)\n",
323 | "\n",
324 | "# t-SNE for visulization\n",
325 | "output = np.concatenate((feature_map_of_random, feature_map_of_minist))\n",
326 | "output = output.reshape(output.shape[0], -1)\n",
327 | "anomaly_flag = np.array([1]*100+ [0]*300)\n",
328 | "\n",
329 | "X_embedded = TSNE(n_components=2).fit_transform(output)\n",
330 | "plt.title(\"t-SNE embedding on the feature representation\")\n",
331 | "plt.scatter(X_embedded[:100,0], X_embedded[:100,1], label='random noise(anomaly)')\n",
332 | "plt.scatter(X_embedded[100:,0], X_embedded[100:,1], label='minist(normal)')\n",
333 | "plt.legend()\n",
334 | "plt.show()"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {},
341 | "outputs": [],
342 | "source": []
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {},
348 | "outputs": [],
349 | "source": []
350 | }
351 | ],
352 | "metadata": {
353 | "kernelspec": {
354 | "display_name": "Python 2",
355 | "language": "python",
356 | "name": "python2"
357 | },
358 | "language_info": {
359 | "codemirror_mode": {
360 | "name": "ipython",
361 | "version": 2
362 | },
363 | "file_extension": ".py",
364 | "mimetype": "text/x-python",
365 | "name": "python",
366 | "nbconvert_exporter": "python",
367 | "pygments_lexer": "ipython2",
368 | "version": "2.7.14"
369 | }
370 | },
371 | "nbformat": 4,
372 | "nbformat_minor": 2
373 | }
374 |
--------------------------------------------------------------------------------