質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

0回答

878閲覧

kerasでのGrad-CAMの実装でエラーが発生する。

mura_0705

総合スコア11

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2022/06/14 09:22

前提・実現したい事

深層距離学習用に構築した学習モデルで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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mura_0705

2022/06/14 09:38 編集

学習モデルの入力部と出力部は以下の通りです。 Model: "functional_1" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_1 (InputLayer) [(None, 224, 224, 3) 0 __________________________________________________________________________________________________ Conv1_pad (ZeroPadding2D) (None, 225, 225, 3) 0 input_1[0][0] __________________________________________________________________________________________________ Conv1 (Conv2D) (None, 112, 112, 32) 864 Conv1_pad[0][0] __________________________________________________________________________________________________ bn_Conv1 (BatchNormalization) (None, 112, 112, 32) 128 Conv1[0][0] __________________________________________________________________________________________________ Conv1_relu (ReLU) (None, 112, 112, 32) 0 bn_Conv1[0][0] ___________________________________________________________________________________ ・ ・ ・ ・ ・ __________________________________________________________________________________________________ block_16_project (Conv2D) (None, 7, 7, 320) 307200 block_16_depthwise_relu[0][0] __________________________________________________________________________________________________ block_16_project_BN (BatchNorma (None, 7, 7, 320) 1280 block_16_project[0][0] __________________________________________________________________________________________________ Conv_1 (Conv2D) (None, 7, 7, 1280) 409600 block_16_project_BN[0][0] __________________________________________________________________________________________________ Conv_1_bn (BatchNormalization) (None, 7, 7, 1280) 5120 Conv_1[0][0] __________________________________________________________________________________________________ out_relu (ReLU) (None, 7, 7, 1280) 0 Conv_1_bn[0][0] __________________________________________________________________________________________________ global_average_pooling2d (Globa (None, 1280) 0 out_relu[0][0] __________________________________________________________________________________________________ input_2 (InputLayer) [(None, 2)] 0 __________________________________________________________________________________________________ arcfacelayer (Arcfacelayer) (None, 2) 2560 global_average_pooling2d[0][0] input_2[0][0] __________________________________________________________________________________________________ activation (Activation) (None, 2) 0 arcfacelayer[0][0] ================================================================================================== Total params: 2,260,544 Trainable params: 2,226,432 Non-trainable params: 34,112 ________________________________________
mura_0705

2022/06/15 02:24

ご回答ありがとうございます。 記事のコードから変更した点は、学習時にモデル全体を保存する必要があった為、Arcfacelayerクラスにget_config関数を追加したことと Grad-CAM実装時のmodel = load_model()内に custom_objects = {"Arcfacelayer": Arcfacelayer}を追加したことになります。 参考URL確認しましたが、今ケースの修正箇所が分かりませんでした。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問