AIの「根拠」を可視化せよ!ブラックボックスをこじ開けるCAMの正体
こんにちは。ゆうせいです。
これまで、GAPやGMPといった「データのまとめ役」についてお話ししてきましたね。実はこれらの技術、ただAIをスリムにするだけではないんです。
AIの世界では長年「なぜその答えを出したのか、人間には分からない」というブラックボックス問題が弱点とされてきました。しかし、今回紹介する「CAM(Class Activation Map)」を使えば、AIが画像のどこを見て判断したのかを、まるでサーモグラフィーのように赤く光らせて見ることができるんです!
研修の受講生からも「これが一番感動した!」という声が多いこの技術、その魔法のタネ明かしをしていきましょう。
AIの「着眼点」をカンニングする
例えば、AIが写真を見て「これは猫です」と答えたとします。でも、もしかしたらAIは猫そのものではなく、横にある「キャットフード」を見て判断しているかもしれません。これでは、キャットフードがない場所では猫を認識できなくなってしまいますよね。
CAMは、AIが判断に使った「重要度」を画像の上にヒートマップとして重ね合わせる技術です。これを使えば、AIがちゃんと「猫の顔や体」を見て判断しているかどうかを一目でチェックできるのです。

CAMが成立する「3つの条件」
CAMを実現するには、実はこれまでに学んだ技術の組み合わせが必要になります。
- 畳み込み層:画像から「特徴(耳、毛なみなど)」の地図をたくさん作る。
- Global Average Pooling (GAP):各地図の「平均的な反応の強さ」を1つの数値にする。
- 重み(重み付き和):どの地図がそのクラス(例えば「猫」)にとって重要かを計算する。
仕組みを数式で覗いてみよう
ある地図 が「耳担当」だったとします。GAPによってその地図の平均値
が出されます。
最終的な「猫らしさ」のスコアは、すべての地図(map)の平均値(average)に、それぞれの重要度を掛け算して足したものになります。
CAMでは、この「重要度 」を、平均化する前の「元の地図」に直接掛け合わせます!
これにより、重要度が高い地図(例えば耳担当)が強く反応している場所が、最終的なヒートマップでも赤く光るというわけです。
CAMを利用するメリットとデメリット
AIの「思考」を見える化することには、計り知れない価値があります。
| 項目 | 内容 |
| メリット | AIの誤判定の原因(背景に騙されている等)を特定し、改善のヒントにできる。 |
| メリット | 医療診断AIなどで「なぜこの病気だと判断したか」を医師に説明する根拠になる。 |
| デメリット | ネットワークの最後にGAPが使われている必要があり、構造が制限される。 |
| デメリット | 最後に全結合層が何層も重なっている古いAIモデルにはそのまま適用できない。 |
CAMのサンプルコード
# 0. 画像をダウンロード
!wget -O cat.jpg https://saycon.co.jp/yuu/cat.jpg
import os
import numpy as np
import torch
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import models
from torchvision.models import ResNet50_Weights
from pytorch_grad_cam import GradCAM
from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
from pytorch_grad_cam.utils.image import show_cam_on_image
# 1. モデルの準備
weights = ResNet50_Weights.DEFAULT
model = models.resnet50(weights=weights)
model.eval()
target_layers = [model.layer4[-1]]
# 2. 画像の読み込みと前処理
input_path = "cat.jpg"
if not os.path.exists(input_path):
raise FileNotFoundError(f"エラー: {input_path} が見つかりません。")
rgb_img = Image.open(input_path).convert("RGB")
# weights付属の標準前処理(Resize 256 -> CenterCrop 224 を含む)
preprocess = weights.transforms()
# 推論用テンソル作成(アスペクト比を維持したまま 224x224 に切り出される)
input_tensor = preprocess(rgb_img).unsqueeze(0)
# 【修正ポイント】可視化用に正規化を解除(Denormalize)
# weights.transforms 内にある mean と std を直接使用して計算します
mean = torch.tensor(preprocess.mean).view(3, 1, 1)
std = torch.tensor(preprocess.std).view(3, 1, 1)
img_for_vis = (input_tensor[0] * std + mean).clamp(0, 1).permute(1, 2, 0).numpy()
# 3. 予測結果からトップのクラスを取得
with torch.no_grad():
outputs = model(input_tensor)
target_category = outputs.argmax(dim=1).item()
predicted_label = weights.meta["categories"][target_category]
print(f"AIの診断結果: {predicted_label} (Class ID: {target_category})")
# 4. Grad-CAMの実行
cam = GradCAM(model=model, target_layers=target_layers)
targets = [ClassifierOutputTarget(target_category)]
# cam() の戻り値は [batch, H, W] なので、最初の画像を取り出す
grayscale_cam = cam(input_tensor=input_tensor, targets=targets)[0, :]
# 5. 可視化
# img_for_vis (0-1 float) を背景にヒートマップを合成
visualization = show_cam_on_image(img_for_vis, grayscale_cam, use_rgb=True)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title(f"Original (Cropped): {predicted_label}")
plt.imshow(img_for_vis)
plt.axis("off")
plt.subplot(1, 2, 2)
plt.title(f"Grad-CAM Heatmap ({predicted_label})")
plt.imshow(visualization)
plt.axis("off")
plt.show()現場での活用:信頼されるAIへ
現在では、CAMをさらに進化させた「Grad-CAM」という手法が主流です。これはGAPを使っていないモデルでも、偏微分の考え方を応用して「どの場所が重要か」を計算できる優れものです。
AIに「信じてください」と言うのではなく、AIに「ここを見て判断しました」と言わせる。この透明性こそが、AIが社会の重要なインフラになるための絶対条件なんです。
これからの学習の指針
「見える化」の技術を知ると、AI開発の視座が一段階上がります。
- Pythonのライブラリ(PyTorchやTensorFlow)を使って、既存のモデルにGrad-CAMを適用してみる。
- AIがわざと間違えるような画像(猫の着ぐるみを着た人など)を読み込ませ、どこに注目しているか観察する。
- 「説明可能なAI(XAI)」というキーワードで、最新の信頼性向上技術を調べてみる。
AIはもう、何を考えているか分からない不気味な存在ではありません。私たちが正しく「レンズ」を当ててあげれば、彼らは饒舌にその根拠を語ってくれるのです。
さて、AIの「中身」を覗く準備は整いました。次は、AIが学習中に陥る最大の罠「過学習」を防ぐために、あえて一部の脳細胞を眠らせる「ドロップアウト」という奇策についてお話ししましょうか?
セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。
投稿者プロフィール



