Python ValueError:无法将大小为0的数组重塑为形状(224512)-绘制热图以定位图像中的异常

Python ValueError:无法将大小为0的数组重塑为形状(224512)-绘制热图以定位图像中的异常,python,arrays,numpy,tensorflow,keras,Python,Arrays,Numpy,Tensorflow,Keras,我一直在使用VGG16创建一个模型,可以将图像分为两类,效果非常好。现在我想创建一个函数,通过热图定位异常,如下所示: 不幸的是,这对我不起作用,包含我的测试图像的数组要么大小错误(ValueError:Error when check input:expected input_1有4个维度,但得到的数组具有形状(1,1,224,224,3)或ValueError:检查输入时出错:预期输入\u 1有4个维度,但得到了具有形状(224,224,3))的数组,或者它告诉我ValueError:无法将

我一直在使用VGG16创建一个模型,可以将图像分为两类,效果非常好。现在我想创建一个函数,通过热图定位异常,如下所示:

不幸的是,这对我不起作用,包含我的测试图像的数组要么大小错误(
ValueError:Error when check input:expected input_1有4个维度,但得到的数组具有形状(1,1,224,224,3)
ValueError:检查输入时出错:预期输入\u 1有4个维度,但得到了具有形状(224,224,3)
)的数组,或者它告诉我
ValueError:无法将大小为0的数组重塑为形状(224512)
。在这里您可以看到一个代码片段:

[...]
test_image_generator = ImageDataGenerator(preprocessing_function=preprocess_input)
test_data_gen = test_image_generator.flow_from_directory(batch_size=batch_size,
                                                         directory=test_dir,
                                                         shuffle=False,
                                                         target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                         class_mode='binary')
# create the model/ import vgg16

vgg_conv = vgg16.VGG16(weights='imagenet', include_top=False, input_shape = (224, 224, 3))

# Freeze the layers except the last 4 layers
for layer in vgg_conv.layers[:-8]:
    layer.trainable = False

# Check the trainable status of the individual layers
for layer in vgg_conv.layers:
    print(layer, layer.trainable)

# modify vgg structure

x = vgg_conv.output
x = GlobalAveragePooling2D()(x)
x = Dense(1, activation="sigmoid")(x)

model = Model(vgg_conv.input, x)
model.compile(loss = "binary_crossentropy", optimizer = optimizers.SGD(lr=0.00001, momentum=0.9), metrics=["accuracy"])

model.summary()

[...]

### CREATE FUNCTION TO DRAW ANOMALIES ###

def plot_activation(img):
    pred = model.predict(img[:,:,:,:])
    pred_class = np.argmax(pred)
    weights = model.layers[-1].get_weights()[0]  # weights last classification layer
    class_weights = weights[:, pred_class]

    intermediate = Model(model.input, model.get_layer("block5_conv3").output)
    conv_output = intermediate.predict(img)
    conv_output = np.squeeze(conv_output)

    h = int(img.shape[0] / conv_output.shape[0])
    w = int(img.shape[1] / conv_output.shape[1])

    activation_maps = sp.ndimage.zoom(conv_output, (h, w, 1), order=1)
    out = np.dot(activation_maps.reshape((img.shape[0] * img.shape[1], 512)), class_weights).reshape(img.shape[0],
                                                                                                     img.shape[1])

    plt.imshow(img.astype('float32').reshape(img.shape[0], img.shape[1], 3))
    plt.imshow(out, cmap='jet', alpha=0.35)
    plt.title('Crack' if pred_class == 1 else 'No Crack')

    # return out, pred_class

img_width, img_height = 224, 224
img = image.load_img('/Volumes/test_image.jpg', target_size = (img_width, img_height))
img = image.img_to_array(img)
img = np.expand_dims(img, axis = 0)

plot_activation(img)
使用该代码,我得到以下错误消息:

Traceback (most recent call last):
  File "test.py", line 285, in <module>
    plot_activation(img)
  File "test.py", line 251, in plot_activation
    out = np.dot(activation_maps.reshape((img.shape[0] * img.shape[1], 512)), class_weights).reshape(img.shape[0],
ValueError: cannot reshape array of size 0 into shape (224,512)

原始代码有效(我仔细检查)。第一个错误是因为您没有向模型传递形状的图像(1224224,3)。您还需要重复相同的预处理步骤。
activation\u maps=sp.ndimage.zoom(conv\u output,(h,w,1),order=1)
生成了一个
size 0
数组-一个没有任何内容的数组。我会看一下
激活\u maps.shape
及其
dtype
。如果需要,可以通过
conv_output
img
追溯它。显然,我在将测试图像传递给函数时犯了几个错误。我已经调整了代码,现在工作正常(请参见编辑)。剩下的唯一问题是,热图的颜色太浓了,你基本上看不到实际图像中留下的任何东西,这对实际检测模型发现的异常情况没有多大帮助。我怎样才能改变它呢?原来的代码是有效的(我反复检查)。第一个错误是因为您没有向模型传递形状的图像(1224224,3)。您还需要重复相同的预处理步骤。
activation\u maps=sp.ndimage.zoom(conv\u output,(h,w,1),order=1)
生成了一个
size 0
数组-一个没有任何内容的数组。我会看一下
激活\u maps.shape
及其
dtype
。如果需要,可以通过
conv_output
img
追溯它。显然,我在将测试图像传递给函数时犯了几个错误。我已经调整了代码,现在工作正常(请参见编辑)。剩下的唯一问题是,热图的颜色太浓了,你基本上看不到实际图像中留下的任何东西,这对实际检测模型发现的异常情况没有多大帮助。我怎样才能改变这一点?
### CREATE FUNCTION TO DRAW ANOMALIES ###

def plot_activation(img):
    pred = model.predict(img[np.newaxis,:,:,:])
    # pred_class = np.argmax(pred)
    pred_class = np.argmax(pred, axis=-1)
    weights = model.layers[-1].get_weights()[0]  # weights last classification layer
    class_weights = weights[:, pred_class]

    intermediate = Model(model.input, model.get_layer("block5_conv3").output)
    conv_output = intermediate.predict(img[np.newaxis,:,:,:])
    conv_output = np.squeeze(conv_output)


    h = int(img.shape[0] / conv_output.shape[0])
    w = int(img.shape[1] / conv_output.shape[1])

    activation_maps = sp.ndimage.zoom(conv_output, (h, w, 1), order=1)
    out = np.dot(activation_maps.reshape((img.shape[0] * img.shape[1], 512)), class_weights).reshape(img.shape[0],
                                                                                                     img.shape[1])

    plt.imshow(img.astype('float32').reshape(img.shape[0], img.shape[1], 3))
    plt.imshow(out, cmap='jet', alpha=0.35)
    plt.title('Crack' if pred_class == 1 else 'No Crack')
    plt.show()

    # return out, pred_class

test_images = test_data_gen[0][0][0]

plot_activation(test_images)