前提・実現したい事
深層距離学習用に構築した学習モデルでgrad-camの実装を行いたいのですが、
エラーが発生し、調べても自己解決できていない状況です。
ご存じの方おりましたら、エラーの原因と対応の方法を教えて頂けますでしょうか。
参考にした記事は下記のとおりです。
学習モデルの構築
https://qiita.com/noritsugu_yamada/items/2e049cd7a8fd77eee0f5#_reference-848bd3284d2b1b43f22d
https://qiita.com/daisukelab/items/e0ff429bd58b2befbb1b
Grad-CAMの実装
https://qiita.com/Kensuke-N/items/cea3920f19bebc9e0d19
発生している問題・エラーメッセージ
下記コマンド実行時にエラーが発生しました。
cam = grad_cam(model, x, target_layer)
発生したエラーは以下の通りです。
AssertionError: Could not compute output Tensor("activation/Softmax_2:0", shape=(None, 2), dtype=float32)
コード
python
1import tensorflow as tf 2import keras 3import numpy as np 4import cv2 5from keras import backend as K 6# 画像用 7from keras.preprocessing.image import array_to_img, img_to_array, load_img 8# モデル読み込み用 9from keras.models import load_model 10# Grad−CAM計算用 11from tensorflow.keras import models 12import tensorflow as tf 13from keras.engine.topology import Layer
python
1class Arcfacelayer(Layer): 2 # s:softmaxの温度パラメータ, m:margin 3 def __init__(self, output_dim, s=30, m=0.50, easy_magin=False, **kwargs): 4 self.output_dim = output_dim 5 self.s = s 6 self.m = m 7 self.easy_magin = easy_magin 8 super(Arcfacelayer, self).__init__() 9 10########### モデルの保存用に追加 ########################## 11 def get_config(self): 12 config = { 13 "output_dim" : self.output_dim, 14 "s" : self.s, 15 "m" : self.m, 16 "easy_magin" : self.easy_magin, 17 } 18 base_config = super().get_config() 19 return dict(list(base_config.items()) + list(config.items())) 20########################################################## 21 22# 重みの作成 23 def build(self, input_shape): 24 # Create a trainable weight variable for this layer. 25 self.kernel = self.add_weight(name='kernel', 26 shape=(input_shape[0][1], self.output_dim), 27 initializer='uniform', 28 trainable=True) 29 super(Arcfacelayer, self).build(input_shape) 30 31# mainの処理 32 def call(self, x): 33 y = x[1] 34 x_normalize = tf.math.l2_normalize(x[0]) #|x = x'/ ||x'||2 35 k_normalize = tf.math.l2_normalize(self.kernel) # Wj = Wj' / ||Wj'||2 36 37 cos_m = K.cos(self.m) 38 sin_m = K.sin(self.m) 39 th = K.cos(np.pi - self.m) 40 mm = K.sin(np.pi - self.m) * self.m 41 42 cosine = K.dot(x_normalize, k_normalize) # W.Txの内積 43 44 sine = K.sqrt(1.0 - K.square(cosine)) 45 phi = cosine * cos_m - sine * sin_m 46 47 if self.easy_magin: 48 phi = tf.where(cosine > 0, phi, cosine) 49 50 else: 51 phi = tf.where(cosine > th, phi, cosine - mm) 52 53 # 正解クラス:cos(θ+m) 他のクラス:cosθ 54 output = (y * phi) + ((1.0 - y) * cosine) # true cos(θ+m), False cos(θ) 55 output *= self.s 56 57 return output 58 59 def compute_output_shape(self, input_shape): 60 61 return (input_shape[0][0], self.output_dim) 62 #return self.output_dim
python
1def grad_cam(input_model, x, layer_name): 2 """ 3 Args: 4 input_model(object): モデルオブジェクト 5 x(ndarray): 画像 6 layer_name(string): 畳み込み層の名前 7 Returns: 8 output_image(ndarray): 元の画像に色付けした画像 9 """ 10 11 # 画像の前処理 12 # 読み込む画像が1枚なため、次元を増やしておかないとmode.predictが出来ない 13 X = np.expand_dims(x, axis=0) 14 preprocessed_input = X.astype('float32') / 255.0 15 16 grad_model = models.Model([input_model.inputs], [input_model.get_layer(layer_name).output, input_model.output]) 17 18 with tf.GradientTape() as tape: 19 conv_outputs, predictions = grad_model(preprocessed_input) 20 class_idx = np.argmax(predictions[0]) 21 loss = predictions[:, class_idx] 22 23 # 勾配を計算 24 output = conv_outputs[0] 25 grads = tape.gradient(loss, conv_outputs)[0] 26 27 gate_f = tf.cast(output > 0, 'float32') 28 gate_r = tf.cast(grads > 0, 'float32') 29 30 guided_grads = gate_f * gate_r * grads 31 32 # 重みを平均化して、レイヤーの出力に乗じる 33 weights = np.mean(guided_grads, axis=(0, 1)) 34 cam = np.dot(output, weights) 35 36 # 画像を元画像と同じ大きさにスケーリング 37 cam = cv2.resize(cam, IMAGE_SIZE, cv2.INTER_LINEAR) 38 # ReLUの代わり 39 cam = np.maximum(cam, 0) 40 # ヒートマップを計算 41 heatmap = cam / cam.max() 42 43 # モノクロ画像に疑似的に色をつける 44 jet_cam = cv2.applyColorMap(np.uint8(255.0*heatmap), cv2.COLORMAP_JET) 45 # RGBに変換 46 rgb_cam = cv2.cvtColor(jet_cam, cv2.COLOR_BGR2RGB) 47 # もとの画像に合成 48 output_image = (np.float32(rgb_cam) + x / 2) 49 50 return output_image
python
1model_path = 'model_2/m02_fine157kara.hdf5' 2image_path = 'dataset/03_test/NG/10.tif' 3IMAGE_SIZE = (224,224) 4 5model = load_model(model_path, custom_objects = {"Arcfacelayer": Arcfacelayer}) 6model.summary() 7x = img_to_array(load_img(image_path, target_size=IMAGE_SIZE))
python
1target_layer = 'out_relu' 2cam = grad_cam(model, x, target_layer)
補足情報
python version: 3.7.0
tensorflow version: 2.3.1
keras version: 2.4.3



あなたの回答
tips
プレビュー