简体   繁体   English

有没有办法分解 CNN model 以为人类提供预测见解?

[英]Is there a way to decompose a CNN model to provide prediction insights to humans?

I have a CNN that after a lot of work is now performing multiclass (8) classification at 99% accuracy.我有一个 CNN,经过大量工作,现在它以 99% 的准确率执行多类 (8) 分类。

While the classification itself has a lot of value, going to a prediction engine would be a game changer.虽然分类本身具有很大的价值,但使用预测引擎将改变游戏规则。

The catch is that the ability to predict is needed by a human in real life (IRL), not in being processed by a computer.问题在于,预测能力是人类在现实生活(IRL)中所需要的,而不是由计算机处理的。

In this case the CNN is able to classify things faster than the human.在这种情况下,CNN 能够比人类更快地对事物进行分类。 It would be significant if the model could provide insights into how it is classifying things如果 model 可以提供有关它如何对事物进行分类的见解,那将是非常重要的

Is there any way to decompose a Keras CNN model and/or it's weights to glean how it's arriving at it's decision?有没有办法分解 Keras CNN model 和/或它的权重来收集它是如何做出决定的? I don't believe so, but would hate not to ask and find out it's possible.我不相信,但不愿意不问并发现这是可能的。

It's not that I'm looking for it to be exact, but if I can find one or two things that heavily influence the prediction/classification that a human being could key on, that could be significant.这并不是说我在寻找它是准确的,但如果我能找到一两件严重影响人类可以关键的预测/分类的事情,那可能很重要。

Thoughts?想法?

Is there any way to decompose a Keras CNN model and/or it's weights to glean how it's arriving at it's decision?有没有办法分解 Keras CNN model 和/或它的权重来收集它是如何做出决定的?

You can look at the Grad-CAM algorithm to see where the neural network was looking at before taking its final decision.您可以查看Grad-CAM 算法,了解神经网络在做出最终决定之前查看的位置。 Here's an implementation in Keras using a pre-trained model.这是使用预训练的 model在 Keras 中的实现

import numpy as np
import tensorflow as tf
from tensorflow import keras
from IPython.display import Image, display
import matplotlib.pyplot as plt
import matplotlib.cm as cm

model_builder = keras.applications.xception.Xception
img_size = (299, 299)
preprocess_input = keras.applications.xception.preprocess_input
decode_predictions = keras.applications.xception.decode_predictions

last_conv_layer_name = "block14_sepconv2_act"
classifier_layer_names = [
    "avg_pool",
    "predictions",
]

img_path = keras.utils.get_file(
    "african_elephant.jpg", "https://i.imgur.com/Bvro0YD.png"
)

display(Image(img_path))


def get_img_array(img_path, size):
    img = keras.preprocessing.image.load_img(img_path, target_size=size)
    array = keras.preprocessing.image.img_to_array(img)
    array = np.expand_dims(array, axis=0)
    return array


def make_gradcam_heatmap(
    img_array, model, last_conv_layer_name, classifier_layer_names
):

    last_conv_layer = model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(model.inputs, last_conv_layer.output)

    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)

    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(img_array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = preds[:, top_pred_index]

    grads = tape.gradient(top_class_channel, last_conv_layer_output)

    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]

    heatmap = np.mean(last_conv_layer_output, axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap

img_array = preprocess_input(get_img_array(img_path, size=img_size))

model = model_builder(weights="imagenet")

preds = model.predict(img_array)
print("Predicted:", decode_predictions(preds, top=1)[0])

heatmap = make_gradcam_heatmap(
    img_array, model, last_conv_layer_name, classifier_layer_names
)

img = keras.preprocessing.image.load_img(img_path)
img = keras.preprocessing.image.img_to_array(img)

heatmap = np.uint8(255 * heatmap)

jet = cm.get_cmap("jet")

jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]

jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))
jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)

superimposed_img = jet_heatmap * 0.4 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)

save_path = "elephant_cam.jpg"
superimposed_img.save(save_path)

display(Image(save_path))

在此处输入图像描述 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM