Skip to content

Commit

Permalink
problem 5
Browse files Browse the repository at this point in the history
  • Loading branch information
orbxball committed May 1, 2017
1 parent 31ecf17 commit 9ef73b4
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
103 changes: 103 additions & 0 deletions hw3/activate_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python

import sys, os
import argparse
import matplotlib.pyplot as plt
from keras.models import load_model
from keras import backend as K
import numpy as np

# util function to convert a tensor into a valid image
def deprocess_image(x):
# normalize tensor: center on 0., ensure std is 0.1
x -= x.mean()
x /= (x.std() + 1e-5)
x *= 0.1

# clip to [0, 1]
x += 0.5
x = np.clip(x, 0, 1)

# convert to array
x *= 255
x = np.clip(x, 0, 255).astype('uint8')
# print(x.shape)
return x

def normalize(x):
# utility function to normalize a tensor by its L2 norm
return x / (K.sqrt(K.mean(K.square(x))) + 1e-7)

def grad_ascent(num_step,input_image_data,iter_func):
"""
Implement this function!
"""
filter_images = []
step = 1e-2
for i in range(num_step):
loss_value, grads_value = iter_func([input_image_data, 0])
input_image_data += grads_value * step
if i % RECORD_FREQ == 0:
filter_images.append((input_image_data, loss_value))
print('#{}, loss rate: {}'.format(i, loss_value))
return filter_images

def main():
emotion_classifier = load_model(model_name)
layer_dict = dict([layer.name, layer] for layer in emotion_classifier.layers)
input_img = emotion_classifier.input

name_ls = [name for name in layer_dict.keys() if 'leaky' in name]
collect_layers = [ layer_dict[name].output for name in name_ls ]

for cnt, c in enumerate(collect_layers):
filter_imgs = []
for filter_idx in range(nb_filter):
input_img_data = np.random.random((1, 48, 48, 1)) # random noise
target = K.mean(c[:, :, :, filter_idx])
grads = normalize(K.gradients(target, input_img)[0])
iterate = K.function([input_img, K.learning_phase()], [target, grads])

###
"You need to implement it."
print('==={}==='.format(filter_idx))
filter_imgs.append(grad_ascent(num_step, input_img_data, iterate))
###
print('Finish gradient')

for it in range(NUM_STEPS//RECORD_FREQ):
print('In the #{}'.format(it))
fig = plt.figure(figsize=(14, 8))
for i in range(nb_filter):
ax = fig.add_subplot(nb_filter/8, 8, i+1)
raw_img = filter_imgs[i][it][0].squeeze()
ax.imshow(deprocess_image(raw_img), cmap='Blues')
plt.xticks(np.array([]))
plt.yticks(np.array([]))
plt.xlabel('{:.3f}'.format(filter_imgs[i][it][1]))
plt.tight_layout()
# fig.suptitle('Filters of layer {} (# Ascent Epoch {} )'.format(name_ls[cnt], it*RECORD_FREQ))
img_path = os.path.join(filter_dir, '{}-{}'.format(store_path, name_ls[cnt]))
if not os.path.exists(img_path):
os.mkdir(img_path)
fig.savefig(os.path.join(img_path,'e{}'.format(it*RECORD_FREQ)))

if __name__ == "__main__":
parser = argparse.ArgumentParser(prog='activate_filters.py',
description='ML-Assignment3 activate filters.')
parser.add_argument('--model', type=str, metavar='<#model>', required=True)

args = parser.parse_args()
model_name = args.model

num_step = NUM_STEPS = 100
RECORD_FREQ = 10
nb_filter = 32

base_dir = './'
filter_dir = os.path.join(base_dir, 'filter_vis')
if not os.path.exists(filter_dir):
os.mkdir(filter_dir)
store_path = ''

main()
84 changes: 84 additions & 0 deletions hw3/filters_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python

import sys, os
import argparse
import matplotlib.pyplot as plt
from keras.models import load_model
from keras import backend as K
import numpy as np

def read_data(filename, height=48, width=48):
try:
print('Loading X.npy & Y.npy')
X = np.load('X.npy')
Y = np.load('Y.npy')
except:
with open(filename, "r+") as f:
line = f.read().strip().replace(',', ' ').split('\n')[1:]
raw_data = ' '.join(line)
length = width*height+1 #1 is for label
data = np.array(raw_data.split()).astype('float').reshape(-1, length)
X = data[:, 1:]
Y = data[:, 0]
# Change data into CNN format
X = X.reshape(-1, height, width, 1)
Y = Y.reshape(-1, 1)
print('Saving X.npy & Y.npy')
np.save('X.npy', X) # (-1, height, width, 1)
np.save('Y.npy', Y) # (-1, 1)
return X, Y

def main():
emotion_classifier = load_model(model_path)
layer_dict = dict([layer.name, layer] for layer in emotion_classifier.layers)
# print(layer_dict.keys())

input_img = emotion_classifier.input
name_ls = [name for name in layer_dict.keys() if 'leaky' in name]
print(name_ls)
collect_layers = [ K.function([input_img, K.learning_phase()], [layer_dict[name].output]) for name in name_ls ]

X, Y = read_data(data_path)

choose_id = 26000
photo = X[choose_id].reshape(-1, height, width, 1)
# print(photo.shape)

for cnt, fn in enumerate(collect_layers):
print('In the conv{}'.format(cnt))
im = fn([photo, 0]) #get the output of that layer
fig = plt.figure(figsize=(14, 8))
nb_filter = min(im[0].shape[3], 32)
for i in range(nb_filter):
ax = fig.add_subplot(nb_filter/8, 8, i+1)
print('imshow size:{}'.format(im[0][0, :, :, i].shape))
ax.imshow(im[0][0, :, :, i], cmap='Blues')
plt.xticks(np.array([]))
plt.yticks(np.array([]))
plt.tight_layout()
fig.suptitle('Output of layer{} (Given image{})'.format(cnt, choose_id))
img_path = os.path.join(vis_dir, store_path)
if not os.path.isdir(img_path):
os.mkdir(img_path)
fig.savefig(os.path.join(img_path,'layer{}'.format(cnt)))

if __name__ == "__main__":
parser = argparse.ArgumentParser(prog='filters_output.py',
description='ML-Assignment3 draw filters output.')
parser.add_argument('--model', type=str, metavar='<#model>', required=True)
parser.add_argument('--data', type=str, metavar='<#data>', required=True)

args = parser.parse_args()
model_path = args.model
data_path = args.data

height = width = 48

base_dir = './'
vis_dir = os.path.join(base_dir, 'output_vis')
if not os.path.exists(vis_dir):
os.makedirs(vis_dir)
store_path = ''


main()

0 comments on commit 9ef73b4

Please sign in to comment.