Я следую этому учебнику , чтобы получить карты активации классов, чтобы я мог знать, по какому принципу классифицируется CNN.
Моя модель:
conv_base = VGG16(weights='imagenet', include_top = False, input_shape=(imgShape[0], imgShape[1], imgShape[2]))
# CNN VGG16
model = models.Sequential()
for layer in conv_base.layers:
model.add(layer)
model.add(Flatten())
# classificateur modele 2 Seringue
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(nbrClass, activation='softmax'))
model.compile(optimizer=RMSprop(lr=1e-6), loss='categorical_crossentropy', metrics=['accuracy'])
И после выполнения подгонки я использую эту функцию:
from keras.applications.vgg16 import preprocess_input as vgg_preprocess_input
def visualize_class_activation_map(model, img_path, output_path):
original_img = cv2.imread(img_path, 1)
width, height, _ = original_img.shape
img = image.load_img(img_path, target_size=(224, 224))
img = image.img_to_array(img)
img = np.expand_dims(img , axis=0)
img = vgg_preprocess_input(img)
#Get the 512 input weights to the softmax.
class_weights = model1.get_layer('vgg16').get_layer(index=17).get_weights()[0]
final_conv_layer = model.get_layer(index=17)
g=model.get_layer('vgg16').get_layer(index=0)
get_output = K.function([g.input], [final_conv_layer.output, model.layers[-1].output])
[conv_outputs, predictions] = get_output(img)
conv_outputs = conv_outputs[0, :, :, :]
#Create the class activation map.
cam = np.zeros(dtype = np.float32, shape = conv_outputs.shape[1:3])
for i, w in enumerate(class_weights[:, 1]):
cam += w * conv_outputs[i, :, :]
print ("predictions", predictions)
cam /= np.max(cam)
cam = cv2.resize(cam, (height, width))
heatmap = cv2.applyColorMap(np.uint8(255*cam), cv2.COLORMAP_JET)
heatmap[np.where(cam < 0.2)] = 0
img = heatmap*0.5 + original_img
cv2.imwrite(output_path, img)
model1.summary()
img_path=r'C:\Users\admin\Downloads\1.jpg'
output_path= r'C:\Users\admin\Downloads\2.jpg'
visualize_class_activation_map(model, img_path, output_path)
Но я получил эту ошибку:
InvalidArgumentError: Вы должны передать значение для тензора-заполнителя 'vgg16_input_4' с помощью dtype float
и shape [?, 224,224,3]
[[{{node vgg16_input_4}}]]
Любое решение?