プログラミ内で計算される224×224の行列式を3Dグラフ化したい
現在、Grad-CAMというものが画像を生成する時に変え合わせる数値を確認していたのですがこれを3Dグラフ化して確認したいと考えています。数値の出力はうまくいったのですが、その値(行列式)を用いてグラフ化する方法が調べてもよくわかりません。
下記コードの”heatmap”という関数をグラフ化し、x軸、z軸を1から224、y軸を計算される値にしたいです。
参考にしているコードの説明
コードDLリンク
grad-cam_5category.pyというプログラムです。
3Dマップで出したいのは下記のコードのheatmap部分です
一番下に全体のコードを載せておきます。
printした際、普通にheatmapを出力した時は1列224行でしか出なかったのでfor文で224回繰り返すことで224列分出力しています。
この224行224列の行列式を3Dプロットしたいです。
###該当コード
python
1def grad_cam(input_model, image, category_index, layer_name): 2 nb_classes = 1000 3 target_layer = lambda x: target_category_loss(x, category_index, nb_classes) 4 x = Lambda(target_layer, output_shape = target_category_loss_output_shape)(input_model.output) 5 model = Model(inputs=input_model.input, outputs=x) 6 #model.summary() 7 loss = K.sum(model.output) 8 conv_output = [l for l in model.layers if l.name == layer_name][0].output #is 9 grads = normalize(_compute_gradients(loss, [conv_output])[0]) 10 gradient_function = K.function([model.input], [conv_output, grads]) 11 12 output, grads_val = gradient_function([image]) 13 output, grads_val = output[0, :], grads_val[0, :, :, :] 14 15 weights = np.mean(grads_val, axis = (0, 1)) 16 cam = np.ones(output.shape[0 : 2], dtype = np.float32) 17 18 for i, w in enumerate(weights): 19 cam += w * output[:, :, i] 20 21 cam = cv2.resize(cam, (224,224)) #299,299)) #224, 224)) 22 cam = np.maximum(cam, 0) 23 heatmap = cam / np.max(cam) 24 for x in range(224): 25 print (heatmap[x]) #3マップで出力したい部分 26 27 #Return to BGR [0..255] from the preprocessed image 28 image = image[0, :] 29 image -= np.min(image) 30 image = np.minimum(image, 255) 31 32 cam = cv2.applyColorMap(np.uint8(255*heatmap), cv2.COLORMAP_JET) 33 cam = np.float32(cam) + np.float32(image) 34 cam = 255 * cam / np.max(cam) 35 return np.uint8(cam), heatmap
###全体のコード
python
1from keras.applications.vgg16 import (VGG16, preprocess_input, decode_predictions) 2from keras.models import Model 3from keras.preprocessing import image 4from keras.layers.core import Lambda 5from keras.models import Sequential 6from tensorflow.python.framework import ops 7import keras.backend as K 8import tensorflow as tf 9import numpy as np 10import keras 11import sys 12import cv2 13#from keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions 14#from keras.applications.vgg19 import VGG19, preprocess_input, decode_predictions 15#from keras.applications.inception_v3 import InceptionV3, preprocess_input, decode_predictions 16 17def target_category_loss(x, category_index, nb_classes): 18 return tf.multiply(x, K.one_hot([category_index], nb_classes)) 19 20def target_category_loss_output_shape(input_shape): 21 return input_shape 22 23def normalize(x): 24 # utility function to normalize a tensor by its L2 norm 25 return x / (K.sqrt(K.mean(K.square(x))) + 1e-5) 26 27def load_image(path): 28 img_path = sys.argv[1] 29 img = image.load_img(img_path, target_size=(224,224)) #299,299)) #224, 224)) 30 x = image.img_to_array(img) 31 x = np.expand_dims(x, axis=0) 32 x = preprocess_input(x) 33 return x 34 35def register_gradient(): 36 if "GuidedBackProp" not in ops._gradient_registry._registry: 37 @ops.RegisterGradient("GuidedBackProp") 38 def _GuidedBackProp(op, grad): 39 dtype = op.inputs[0].dtype 40 return grad * tf.cast(grad > 0., dtype) * \ 41 tf.cast(op.inputs[0] > 0., dtype) 42 43def compile_saliency_function(model, activation_layer='block5_conv3'): #mixed10 'activation_49' add_16 add_32 activation_98 44 input_img = model.input 45 layer_dict = dict([(layer.name, layer) for layer in model.layers[1:]]) 46 #print(layer_dict) 47 layer_output = layer_dict[activation_layer].output 48 max_output = K.max(layer_output, axis=3) 49 saliency = K.gradients(K.sum(max_output), input_img)[0] 50 return K.function([input_img, K.learning_phase()], [saliency]) 51 52def modify_backprop(model, name): 53 g = tf.get_default_graph() 54 with g.gradient_override_map({'Relu': name}): 55 56 # get layers that have an activation 57 layer_dict = [layer for layer in model.layers[1:] 58 if hasattr(layer, 'activation')] 59 60 # replace relu activation 61 for layer in layer_dict: 62 if layer.activation == keras.activations.relu: 63 layer.activation = tf.nn.relu 64 65 # re-instanciate a new model 66 new_model = VGG16(weights='imagenet') 67 #new_model = ResNet50(weights='imagenet') 68 new_model.summary() 69 return new_model 70 71def deprocess_image(x): 72 ''' 73 Same normalization as in: 74 https://github.com/fchollet/keras/blob/master/examples/conv_filter_visualization.py 75 ''' 76 if np.ndim(x) > 3: 77 x = np.squeeze(x) 78 # normalize tensor: center on 0., ensure std is 0.1 79 x -= x.mean() 80 x /= (x.std() + 1e-5) 81 x *= 0.1 82 83 # clip to [0, 1] 84 x += 0.5 85 x = np.clip(x, 0, 1) 86 87 # convert to RGB array 88 x *= 255 89 if K.image_dim_ordering() == 'th': 90 x = x.transpose((1, 2, 0)) 91 x = np.clip(x, 0, 255).astype('uint8') 92 return x 93 94def _compute_gradients(tensor, var_list): 95 grads = tf.gradients(tensor, var_list) 96 return [grad if grad is not None else tf.zeros_like(var) for var, grad in zip(var_list, grads)] 97 98def grad_cam(input_model, image, category_index, layer_name): 99 nb_classes = 1000 100 target_layer = lambda x: target_category_loss(x, category_index, nb_classes) 101 x = Lambda(target_layer, output_shape = target_category_loss_output_shape)(input_model.output) 102 model = Model(inputs=input_model.input, outputs=x) 103 #model.summary() 104 loss = K.sum(model.output) 105 conv_output = [l for l in model.layers if l.name == layer_name][0].output #is 106 grads = normalize(_compute_gradients(loss, [conv_output])[0]) 107 gradient_function = K.function([model.input], [conv_output, grads]) 108 109 output, grads_val = gradient_function([image]) 110 output, grads_val = output[0, :], grads_val[0, :, :, :] 111 112 weights = np.mean(grads_val, axis = (0, 1)) 113 cam = np.ones(output.shape[0 : 2], dtype = np.float32) 114 115 for i, w in enumerate(weights): 116 cam += w * output[:, :, i] 117 118 cam = cv2.resize(cam, (224,224)) #299,299)) #224, 224)) 119 cam = np.maximum(cam, 0) 120 heatmap = cam / np.max(cam) 121 for x in range(224): 122 print (heatmap[x]) 123 124 #Return to BGR [0..255] from the preprocessed image 125 image = image[0, :] 126 image -= np.min(image) 127 image = np.minimum(image, 255) 128 129 cam = cv2.applyColorMap(np.uint8(255*heatmap), cv2.COLORMAP_JET) 130 cam = np.float32(cam) + np.float32(image) 131 cam = 255 * cam / np.max(cam) 132 return np.uint8(cam), heatmap 133 134preprocessed_input = load_image(sys.argv[1]) 135model = VGG16(weights='imagenet') 136#model = VGG19(weights='imagenet') 137#model = InceptionV3(weights='imagenet') 138#model = ResNet50(weights = 'imagenet') 139#model.summary() 140target_layer = 'block5_conv3' #'activation_49' add_16 "block5_conv3" 141 142predictions = model.predict(preprocessed_input) 143register_gradient() 144guided_model = modify_backprop(model, 'GuidedBackProp') 145guided_model.summary() 146for i in range(5): 147 top_1 = decode_predictions(predictions)[0][i] 148 print(predictions.argsort()[0][::-1][i]) 149 print('Predicted class:') 150 print('%s (%s) with probability %.2f' % (top_1[1], top_1[0], top_1[2])) 151 predicted_class = predictions.argsort()[0][::-1][i] #np.argmax(predictions) 152 cam, heatmap = grad_cam(model, preprocessed_input, predicted_class, target_layer) 153 cv2.imwrite("gradcam"+str(top_1[1])+".jpg", cam) 154 saliency_fn = compile_saliency_function(guided_model) 155 saliency = saliency_fn([preprocessed_input, 0]) 156 gradcam = saliency[0] * heatmap[..., np.newaxis] 157 cv2.imwrite("guided_gradcam"+str(top_1[1])+".jpg", deprocess_image(gradcam))
回答2件
あなたの回答
tips
プレビュー