Я использую Keras с бэкэндом тензорного потока и настроил последний слой Conv и уровень FC моей сети на основе весов VGG. Теперь я использую технику CAM, чтобы визуализировать, какие части моего изображения вызвали предсказание, и я получаю все нули для средней интенсивности градиента по каналу карты конкретных объектов.
У меня есть 4 класса, для моего тестового образца это прогноз:
preds_sample = model.predict(x)
output>> array([[1., 0., 0., 0.]], dtype=float32)
# This is the "sample image" entry in the prediction vector
image_0 = model.output[:, 0]
last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(toilet_w, last_conv_layer.output)[0]
grads.shape
output>> TensorShape([Dimension(None), Dimension(512), Dimension(14), Dimension(14)])
Так как я использую упорядочение изображений aano - когда я вычисляю среднее значение града, моя ось равна (0,2,3)
from keras import backend as K
K.set_image_dim_ordering('th')
pooled_grads = K.mean(grads, axis=(0,2,3))
pooled_grads.shape
output>> TensorShape([Dimension(512)])
iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])
pooled_grads_value.shape, conv_layer_output_value.shape
output>> ((512,), (512, 14, 14))
pooled_grads_value - все ноль
Ссылка: https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.4-visualizing-what-convnets-learn.ipynb
Я протестировал алгоритм с большим количеством изображений и обнаружил, что он работает для некоторых изображений. Затем я заметил, что у меня есть слой выпадения после моего последнего слоя конвоя. Я провел дополнительные исследования https://github.com/jacobgil/keras-grad-cam/issues/2 и изменил код следующим образом:
last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(sample_output, last_conv_layer.output)[0]
# normalization trick: we normalize the gradient
#grads = normalize_grad(grads)
pooled_grads = K.mean(grads, axis=(0, 2, 3))
iterate = K.function([model.input, K.learning_phase()], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x, 0])
Но все же для некоторых изображений все pooled_grads являются нулями.