CNN学習済みネットワークの可視化
※本記事は研究室内向けに記述しております
著作物のため本コードはフルコードの記載は控えております
柏尾研究室では、CNNモデルの認識性能の確認のため学習済みモデルの特徴マップの可視化を行っています。
特徴マップに関しては、本サイトをご参照ください。
↑僕が記述するより、わかりやすいと思います。
①実際のコード説明
24行目:
認識性能の確認を行いたい画像データの取得を行います。
30~34行目:
本プログラムで認識性能の確認を行いたい学習済みモデルの参照を行います。学習済みモデルの保存・参照には、h5形式のファイルを用いています。そのため、学習の際には必ずh5ファイルでの保存を行ってください。
[1]画像を数値データに変換処理
40~48行目:
いつも通り画像ファイルを"0-1"スケールの数値データに変換する処理を行います。
41行目:ファイルパスによって参照した各画像データを、
42行目:ピクセル単位のRGB(255,255,255)のデータに
43行目:画像サイズを224,224のサイズに変更
48行目:ピクセル単位の値を0-1スケールにする(機械学習で用いやすい)
image = Image.open(original_fig)
image = image.convert("RGB")
image = image.resize((224, 224))
data = np.asarray(image)
X.append(data)
X = np.array(X)
X = X.astype('float32')
X = X / 255.0
ここからが特徴マップ可視化の為に、重要な作業。
[2]認識性能を確認する層の指定
CNNの認識性能を確認したい層を下記のコードで指定します。
本研究室では、主に第一層目のConvolutional層を指定することが多いと思います。
51~56行目:
51行目:学習済みモデルのInput層と7層以降を除去した第一層~第六層を指定
52~54行目:指定したモデルのみで、新たなモデル(activation_model)を構築
summaryを用いてモデルの構成を出力
layers = model.layers[1:6]
layer_outputs = [layer.output for layer in layers]
activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
activation_model.summary()
activations = activation_model.predict(X)
61行目~67行目:
学習済みモデルの層の大きさを層毎に出力する。
後に、Convolutional層のみに出力層を絞って、再度層の大きさを出力する。
for i, activation in enumerate(activations):
print("%2d: %s" % (i, str(activation.shape)))
#出力を"Convolutional層"のみに絞る
activations = [activation for layer, activation in zip(layers, activations) if isinstance(layer, Conv2D)]
print("%2d: %s" % (i, str(activation.shape)))
次に、画像Noごとに可視化画像を保存するためのファイルを作成する。
[3]画像の可視化プログラム
本プログラムの可視化には本サイトを参照しています。
コードの詳細に関しては上記サイトを参考にしてください。
この中から、特徴強度の高い特徴マップを本研究室での認識性能の指標としています。
for i, activation in enumerate(activations):
num_of_image = activation.shape[3]
max = np.max(activation[0])
for j in range(0, num_of_image):
plt.figure()
sns.heatmap(activation[0, :, :, j], vmin=0, vmax=max, xticklabels=False, yticklabels=False, square=False,cmap='hot')
save_image_name="Conv2D_第%d層_%dチャネル_画像No%d.png" % (i+1,j+1,No+1)
plt.savefig(save_image_name)
plt.show() #可視化の様子が見たいとき
plt.close()
shutil.move(save_image_name , model_file + "\\" + file_name)