Проблема Grad-CAM с Keras на VGG16 с тонкой настройкой

В настоящее время я изучаю книгу Франсуа Шоле "Deep Learning with Python" и обучаю ConvNet тонкой настройке для классификации кошек и собак. И это нормально, все отлично работает.

А несколькими главами позже представлен алгоритм Grad-CAM для предварительного просмотра того, на что "смотрит" ConvNet. И снова мой код работает отлично, и результат отличный (с неизмененным набором данных VGG16).

Поэтому я решил попробовать алгоритм Grad-CAM в сети, которую я ранее обучал распознавать собак и кошек (тонко настроенный VGG16). И, увы, я не могу заставить это работать...

Вызов функции градиента всегда возвращает None,

Я пробовал разные входные изображения, и, поскольку проблема продолжала показывать, я решил перенастроить свою ConvNet, чтобы она была более идентичной исходному VGG16.

Я изменил свою конфигурацию ConvNet для вывода категориального результата (с 2 категориями вместо 1000) из softmax вместо уникального значения из сигмоида, и затем я попытался снова, но проблема остается той же, и градиент возвращается None не важно что.

Есть еще 2 различия между моей моделью и VGG16:

  • мой вход (150, 150), тогда как вход VGG (224, 224). Но я не понимаю, почему это может быть источником проблемы.
  • моя модель построена на VGG без верхних слоев, и, таким образом, первый "слой" моей модели также является моделью (последний сверточный слой должен быть доступен через model.get_layer('vgg16').get_layer('block5_conv3')) тогда как когда я использую VGG16, слои доступны напрямую (последний сверточный слой может быть доступен с помощью model.get_layer('block5_conv3')).

Вот мой код:

from keras import models, layers, optimizers
##model = VGG16(weights='imagenet') # it works with this one

model = models.load_model('DL_CONVNET_05.h5') # but not with my own model
model.compile(optimizer=optimizers.RMSprop(lr=1e-5), loss='categorical_crossentropy', metrics=['acc']) # also tried with a binary_crossentropy


# Preprocess an input image for VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input, decode_predictions
import numpy as np

img_path = 'datasets/test/dogs/dog.1700.jpg'
img = image.load_img(img_path, target_size=(150,150)) # (224,224) in the original VGG16 input but (150,150) in my own fined-tuned ConvNet

x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

preds = model.predict(x)
print("Predicted values:", preds)
print("Predicted class:", np.argmax(preds[0]))


# Setting up the Grad-CAM algorithm
import keras.backend as K

test_output = model.output[:,np.argmax(pred[0])] # test against the predicted class (can be changed to 0 for Cat or 1 for Dog)

# with the original Grad-CAM with the original VGG16,
# the following line directly get the 'block5_conv3' layer,
# but as my own model is built from a VGG16 without the top layers
# on which I added some tuned layer I can't access it directly
last_conv_layer = model.get_layer('vgg16').get_layer('block5_conv3')

ЗДЕСЬ ПРОБЛЕМА... грады возвращаются None

grads = K.gradients( test_output, last_conv_layer.output)[0]
print("grads:",grads)

pooled_grads = K.mean(grads, axis=(0,1,2))
iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])

for i in range(512): # 512 is the number of channels in block5_conv3
    conv_layer_output_value[:,:,i] *= pooled_grads_value[i]

heatmap = np.mean(conv_layer_output_value, axis=-1)


# etc. etc... but as the problem is here I guess the rest of the code is useless.

Я склонен думать, что это может быть потому, что я ловлю вывод, используя last_conv_layer = model.get_layer('vgg16').get_layer('block5_conv3') (который является вложенным слоем внутри модели vgg16, который, в свою очередь, находится внутри моей модели) вместо last_conv_layer = model.get_layer('block5_conv3') (когда vgg16 - непосредственно используемая модель), но я не уверен, и я не знаю, как это исправить.

Кроме того, это может быть связано с сообщенной проблемой тензорного потока ( https://github.com/tensorflow/tensorflow/issues/783), но я не уверен, и подтверждение от кого-то с более глубоким пониманием проблемы будет более чем приветствуется

У вас есть идея или предложение?

Спасибо за помощь.

0 ответов

Другие вопросы по тегам