如何在不使用visualize_cam的情况下实现CAM?

我想制作类激活映射(Class Activation Map),所以我编写了以下代码

from keras.datasets import mnistfrom keras.layers import Conv2D, Dense, GlobalAveragePooling2Dfrom keras.models import Model, Inputfrom keras.utils import to_categorical(x_train, y_train), (x_test, y_test) = mnist.load_data()x_train_resized = x_train.reshape((60000, 28, 28, 1))x_test_resized = x_test.reshape((10000, 28, 28, 1))y_train_hot_encoded = to_categorical(y_train)y_test_hot_encoded = to_categorical(y_test)inputs = Input(shape=(28,28, 1))x = Conv2D(64, (3,3), activation='relu')(inputs)x = Conv2D(64, (3,3), activation='relu')(x)x = GlobalAveragePooling2D()(x)predictions = Dense(10, activation='softmax')(x)model = Model(inputs=inputs, outputs=predictions)model.compile(optimizer='rmsprop',              loss='categorical_crossentropy',              metrics=['accuracy'])model.fit(x_train_resized, y_train_hot_encoded, epochs=30, batch_size=256, shuffle=True, validation_split=0.3)

代码运行正常,所以我引入了visualize_cam模块

from vis.visualization import visualize_camimport matplotlib.pyplot as pltimport numpy as npfor i in range(10):    ind = np.where(y_test == i)[0][0]    plt.subplot(141)    plt.imshow(x_test_resized[ind].reshape((28,28)))    for j,modifier in enumerate([None, 'guided', 'relu']):        heat_map = visualize_cam(model, 4, y_test[ind], x_test_resized[ind], backprop_modifier=modifier)        plt.subplot(1,4,j+2)        plt.imshow(heat_map)    plt.show()

但visualize_cam的效果并不好

我尝试了很多次修复这个模块,但效果不佳(它依赖于scipy,版本低于1.3)

所以我必须在不使用该模块的情况下实现CAM

有没有什么方法可以替代visualize_cam来实现CAM?


回答:

这是一个不依赖scipy库的实现方法。

from keras.datasets import mnistfrom keras.layers import Conv2D, Dense, GlobalAveragePooling2Dfrom keras.models import Model, Inputfrom keras.utils import to_categorical(x_train, y_train), (x_test, y_test) = mnist.load_data()x_train_resized = x_train.reshape((60000, 28, 28, 1))x_test_resized = x_test.reshape((10000, 28, 28, 1))y_train_hot_encoded = to_categorical(y_train)y_test_hot_encoded = to_categorical(y_test)inputs = Input(shape=(28,28, 1))x = Conv2D(64, (3,3), activation='relu')(inputs)x = Conv2D(64, (3,3), activation='relu', name='final_conv')(x)x = GlobalAveragePooling2D()(x)predictions = Dense(10, activation='softmax')(x)model = Model(inputs=inputs, outputs=predictions)model.compile(optimizer='rmsprop',              loss='categorical_crossentropy',              metrics=['accuracy'])model.fit(x_train_resized, y_train_hot_encoded, epochs=1, batch_size=256, shuffle=True, validation_split=0.3)
import numpy as npimport cv2import ioimport requestsfrom PIL import Imageimport matplotlib.pyplot as plt# 使用tensorflow中的Keras实现from tensorflow.python.keras import applicationsfrom tensorflow.python.keras.preprocessing.image import load_img, img_to_array from tensorflow.python.keras import backend as K# 获取最后一个卷积层的层fianlconv = model.get_layer('final_conv')# 获取最后一层的权重矩阵weight_softmax = model.layers[-1].get_weights()[0]# 生成类激活映射的函数HEIGHT = 28WIDTH = 28def returnCAM(feature_conv, weight_softmax, class_idx):    size_upsample = (WIDTH, HEIGHT)    # Keras默认是通道在最后,所以nc在最后    bz, h, w, nc = feature_conv.shape    output_cam = []    for idx in class_idx:        cam = np.dot(weight_softmax[:, idx], np.transpose(feature_conv.reshape(h*w, nc)))        cam = cam.reshape(h, w)        cam = cam - np.min(cam)        cam_img = cam / np.max(cam)        cam_img = np.uint8(255 * cam_img)        output_cam.append(cv2.resize(cam_img, size_upsample))    return output_camx = x_test_resized[0,:,:,0]plt.imshow(x)plt.show()classes = {1:'1', 2: '2', 3: '3', 4:'4', 5:'5', 6:'6', 7:'7', 8:'8', 9:'9', 0:'0'}probs_extractor = K.function([model.input], [model.output])features_conv_extractor = K.function([model.input], [fianlconv.output])probs = probs_extractor([np.expand_dims(x, 0).reshape(1,28,28,1)])[0]features_blob = features_conv_extractor([np.expand_dims(x, 0).reshape(1,28,28,1)])[0]features_blobs = []features_blobs.append(features_blob)idx = np.argsort(probs)probs = np.sort(probs)for i in range(-1, -6, -1):    print('{:.3f} -> {}'.format(probs[0, i], classes[idx[0, i]]))CAMs = returnCAM(features_blobs[0], weight_softmax, [idx[0, -1]])heatmap = cv2.applyColorMap(cv2.resize(CAMs[0], (28, 28)), cv2.COLORMAP_JET)result = heatmap[:,:,0] * 0.3 + x * 0.5print(result.shape)plt.imshow(result)plt.show()

注意:我绘制的是归一化图像,所以结果不是很好,我只训练了一个epoch。为了获得更好的结果,你可以尝试多训练几次,改用合适的颜色空间。

enter image description here

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注