在本教程中,我们将 Keras 与 Tensorflow 和 ResNet50 结合使用。
因为 ResNet50 有一个全局平均池化 (GAP) 层(稍后会解释),所以它适合我们的演示。这很完美。
来自CNN的热图,又名类激活映射(CAM)。这个想法是我们收集卷积层的每个输出(作为图像),并将其组合在一个镜头中。(我们稍后会逐步展示代码)
因此,以下是全局平均池化 (GAP) 或全局最大池化的工作方式(取决于您使用哪个,但它们是相同的想法)。
在一些特征提取后的模型中,我们使用与神经网络的扁平层(完全连接)来预测结果。但这一步就像丢弃图像维度和一些信息。
相比之下,使用全局平均池 (GAP) 或全局最大池 (GMP) 在这里起作用。它保留图像维度信息,并使神经网络决定哪个CNN通道(特征图像)对于预测结果更为关键。
让我们从Keras中的ResNet50开始。
from tensorflow.keras.applications import ResNet50
res_model = ResNet50()
res_model.summary()
如您所见(上图):
并导入库和图像供以后使用。
import cv2
import matplotlib.pyplot as plt
from scipy.ndimage import zoom
from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions
img = cv2.imread('./test_cat.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
X = np.expand_dims(img, axis=0).astype(np.float32)
X = preprocess_input(X)
我们使用“from scipy.ndimage import zoom”。为了调整由于CNN而调整热图的大小,特征提取图像的形状小于原始图像。
现在提取我们将使用的图层。
P.S:你可以从头开始训练你的模型,但需要很长时间,特征提取可能也需要大量的调优。
from tensorflow.keras.models import Model
conv_output = res_model.get_layer("conv5_block3_out").output
pred_ouptut = res_model.get_layer("predictions").output
model = Model(res_model.input, outputs=[conv_ouptut, pred_layer])
这里我们有两个输出(如上所述,图中的红色部分)。
并做预测
conv, pred = model.predict(X)
decode_predictions(pred)
结果如下所示。还不错
[[('n02123159', 'tiger_cat', 0.7185241),
('n02123045', 'tabby', 0.1784818),
('n02124075', 'Egyptian_cat', 0.034279127),
('n03958227', 'plastic_bag', 0.006443105),
('n03793489', 'mouse', 0.004671723)]]
现在,让我们看看一些CNN输出。
scale = 224 / 7
plt.figure(figsize=(16, 16))
for i in range(36):
plt.subplot(6, 6, i + 1)
plt.imshow(img)
plt.imshow(zoom(conv[0, :,:,i], zoom=(scale, scale)), cmap='jet', alpha=0.3)
CNN 输出
我们首先显示地面图像( plt.imshow(img) ),因此我们可以将其与地面图像进行比较。
(如果你不这样做,会得到这样的结果)
这是关键的。我们使用预测结果指数(目标)来获取权重。并乘以每个特征图与权重(点积)
target = np.argmax(pred, axis=1).squeeze()
w, b = model.get_layer("predictions").weights
weights = w[:, target].numpy()
heatmap = conv.squeeze() @ weights
然后显示带有地面图像的热图。
scale = 224 / 7
plt.figure(figsize=(12, 12))
plt.imshow(img)
plt.imshow(zoom(heatmap, zoom=(scale, scale)), cmap='jet', alpha=0.5)
这就是我们想要的结果。
海沌