Keras上的K.gradients返回{NoneType}无

时间:2019-03-26 10:44:26

标签: keras nonetype gradients transfer-learning

我正在练习类激活映射(CAM)。首先,我已经在InceptionResnetV2上使用转移学习对我的数据集进行了训练,并添加了更多层(微调)。经过培训后,我按照https://nbviewer.jupyter.org/github/fchollet/deep-learning-with-python-notebooks/blob/master/5.4-visualizing-what-convnets-learn.ipynb [1]的教程修改了CAM,问题出在我使用函数K.gradients计算梯度时,它返回了'NoneType' None

我在K.gradients(loss, input_img)[0] return "None". (Keras CNN visualization with tensorflow backend)处检查了该主题,但问题无法解决,下面是我的代码。

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]所示,可以正常工作!

0 个答案:

没有答案