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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
```python
import argparse
import cv2
import matplotlib.pyplot as plt
from keras.models import Model
import keras.applications.resnet50 as resnet
from keras.layers import UpSampling2D, Conv2D
# Set an appropriate image file
parser = argparse.ArgumentParser(description='Class activation maps with Keras.')
parser.add_argument('input_image', metavar='base', type=str,
help='Path to the image to use.')
args = parser.parse_args()
input_image = args.input_image
################################################################
# The following parameters can be changed to other models
# that use global average pooling.
# e.g.) InceptionResnetV2 / NASNetLarge
NETWORK_INPUT_SIZE = 224
MODEL_CLASS = resnet.ResNet50
PREPROCESS_FN = resnet.preprocess_input
LAST_CONV_LAYER = 'activation_49'
PRED_LAYER = 'fc1000'
################################################################
# number of imagenet classes
N_CLASSES = 1000
def load_img(fname, input_size, preprocess_fn):
original_img = cv2.imread(fname)[:, :, ::-1]
original_size = (original_img.shape[1], original_img.shape[0])
img = cv2.resize(original_img, (input_size, input_size))
imgs = np.expand_dims(preprocess_fn(img), axis=0)
return imgs, original_img, original_size
def get_cam_model(model_class,
input_size=224,
last_conv_layer='activation_49',
pred_layer='fc1000'):
model = model_class(input_shape=(input_size, input_size, 3))
final_params = model.get_layer(pred_layer).get_weights()
final_params = (final_params[0].reshape(
1, 1, -1, N_CLASSES), final_params[1])
last_conv_output = model.get_layer(last_conv_layer).output
x = UpSampling2D(size=(32, 32), interpolation='bilinear')(
last_conv_output)
x = Conv2D(filters=N_CLASSES, kernel_size=(
1, 1), name='predictions_2')(x)
cam_model = Model(inputs=model.input,
outputs=[model.output, x])
cam_model.get_layer('predictions_2').set_weights(final_params)
return cam_model
def postprocess(preds, cams, top_k=1):
idxes = np.argsort(preds[0])[-top_k:]
class_activation_map = np.zeros_like(cams[0, :, :, 0])
for i in idxes:
class_activation_map += cams[0, :, :, i]
return class_activation_map
# 1. load image
imgs, original_img, original_size = load_img(input_image,
input_size=NETWORK_INPUT_SIZE,
preprocess_fn=resnet.preprocess_input)
# 2. prediction
model = get_cam_model(resnet.ResNet50,
NETWORK_INPUT_SIZE,
LAST_CONV_LAYER,
PRED_LAYER)
preds, cams = model.predict(imgs)
# 4. post processing
class_activation_map = postprocess(preds, cams)
# 5. plot image+cam to original size
plt.imshow(original_img, alpha=0.5)
plt.imshow(cv2.resize(class_activation_map,
original_size), cmap='jet', alpha=0.5)
plt.show()
```
|