Я занимаюсь картированием активации классов (CAM). Во-первых, я уже обучил свой набор данных с помощью обучения переносу на InceptionResnetV2 и добавил еще несколько слоев (точная настройка). После обучения я модифицирую CAM, следуя инструкции на https://nbviewer.jupyter.org/github/fchollet/deep-learning-with-python-notebooks/blob/master/5.4-visualizing-what-convnets-learn.ipynb [1], и проблема возникает, когда я вычисляю градиент с помощью функции K.gradients
, он возвращает 'NoneType' None
Я проверяю тему в K.gradients (loss, input_img) [0] возвращает "None". (Визуализация Keras CNN с бэкэндом тензорного потока) но проблема не может быть решена, ниже приведен мой код.
num_classes = 21
img_width = 128
img_height = 128
def get_model():
base_model = keras.applications.inception_resnet_v2.InceptionResNetV2(include_top=False, weights='imagenet', input_tensor=None, input_shape=(img_width, img_height, 3), pooling='avg', classes=num_classes)
model = models.Sequential()
model.add(base_model)
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dense(num_classes, activation='softmax'))
model.summary()
model.compile(optimizer=keras.optimizers.SGD(lr=0.0001, momentum=0.9),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
def load_model_weights(model, weights_path):
print ('Loading model.')
model.load_weights( weights_path)
for layer in model.layers:
layer.trainable = False
print('Model loaded.')
return model
model = get_model()
model = load_model_weights(model=model, weights_path = 'inceptionresnet50_1.h5')
last_conv_layer = model.layers[0].get_layer('conv_7b')
img_path = 'abc.jpg'
img = image.load_img(img_path, target_size=(img_height, img_width))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x /= 255.0
preds = model.predict(x)
pred_rec = np.argmax(preds[0])
african_elephant_output = model.output[:, pred_rec]
grads = K.gradients(african_elephant_output, last_conv_layer.input)[0]
pooled_grads = K.mean(grads, axis=(0, 1, 2))
Объяснение
last_conv_layer = model.layers[0].get_layer('conv_7b')
: поскольку я использую функцию add
для функции get_model()
, исходный InceptionResnet будет показан на model.layers[0]
, поэтому я использую model.layers[0].get_layer('conv_7b')
, чтобы получить выходные данные слоя 'conv_7b'
на оригинальная модель.
Я ожидаю, что на выходе grads = K.gradients
должен быть тензор, чтобы я мог выполнять функцию pooled_grads
.
Если я не использую свои сохраненные веса и заменил
model = get_model()
model = load_model_weights(model=model, weights_path = 'inceptionresnet50_1.h5')
last_conv_layer = model.layers[0].get_layer('conv_7b')
от
model = VGG16(weights='imagenet')
last_conv_layer = model.get_layer('block5_conv3')
как показано на [1], это работает!