我在机器学习和深度学习方面是新手。我正在进行一个项目,旨在为一些测试图像创建显著性图。我已经加载了一些猫和狗的图像并对其进行了预处理。我已经创建了我的模型。在运行这段代码片段后,我遇到了这个错误:**层”sequential”的输入0与层不兼容:期望形状=(None, 300, 300, 3),找到形状=(300, 300, 3)**
def do_salience(image, model, label, prefix): ''' 生成给定图像的显著性图。 参数: image (file) -- 模型将分类的图片 model (keras Model) -- 你的猫和狗分类器 label (int) -- 图像的真实标签 prefix (string) -- 要添加到显著性图文件名的前缀 ''' # 读取图像并将通道顺序从BGR转换为RGB # 你的代码在这里 image = cv2.imread(image) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 将图像调整为300 x 300大小,并将像素值归一化到[0, 1]范围 # 你的代码在这里 image = cv2.resize(image,(300,300))/255.0 # 添加一个额外的维度(用于批处理),并将结果保存到一个新变量中 # 你的代码在这里 tensor_image = tf.expand_dims(image, axis=0) # 声明类别的数量 # 你的代码在这里 num_classes= 2 # 通过one-hot编码标签来定义预期的输出数组 # 数组的长度等于类别的数量 # 你的代码在这里 class_index= [0,1] expected_output = tf.one_hot([class_index] * tensor_image.shape[0], num_classes) # 在GradientTape块内: # 将图像转换为tf.float32类型 # 使用tape监视float32类型的图像 # 通过传入float32类型的图像获取模型的预测 # 计算预期输出和模型预测之间的适当损失。 # 你可能想打印预测结果以查看概率是否总和为1 # 你的代码在这里 with tf.GradientTape() as tape: inputs = tf.cast(image,tf.float32) tape.watch(inputs) predictions = model(inputs) loss = tf.keras.losses.CategoricalCrossentropy(expected_output, predictions) print(predictions) # 获取损失相对于模型输入图像的梯度 # 你的代码在这里 gradients = tape.gradients(loss, inputs) # 生成灰度张量 # 你的代码在这里 grayscale_tensor = tf.reduce_sum(tf.abs(gradients), axis=-1) # 将像素值归一化到[0, 255]范围。 # 灰度张量中的最大值将被推到255。 # 最小值将被推到0。 # 使用公式:255 * (x - min) / (max - min) # 使用tf.reduce_max, tf.reduce_min # 将张量转换为tf.uint8类型 # 你的代码在这里 normalized_tensor = tf.cast(255*(grayscale_tensor-tf.reduce_min(grayscale_tensor)) /(tf.reduce_max(grayscale_tensor)-tf.reduce_min(grayscale_tensor)),tf.unit8, ) # 移除大小为1的维度 # 你的代码在这里 normalized_tensor = tf.squeeze(normalized_tensor) # 绘制归一化张量 # 将图形大小设置为8x8 # 不显示坐标轴 # 使用'gray'颜色映射 # 此代码已为你提供 plt.figure(figsize=(8, 8)) plt.axis('off') plt.imshow(normalized_tensor, cmap='gray') plt.show() # 可选:将显著性图与原始图像叠加,然后显示它。 # 我们鼓励你这样做,以便更好地可视化结果 # 你的代码在这里 gradient_color = cv2.applyColorMap(normalized_tensor.numpy(),cv2.COLORMAP_HOT) gradient_color = gradient_color/255.0 super_imposed = cv2.addWeighted(image, 0.5, gradient_color, 0.5, 0.0) plt.figure(figsize=(8, 8)) plt.imshow(super_imposed) plt.axis('off') plt.show() # 将归一化张量图像保存到文件中。这已经为你提供了 salient_image_name = prefix + image normalized_tensor = tf.expand_dims(normalized_tensor, -1) normalized_tensor = tf.io.encode_jpeg(normalized_tensor, quality=100, format='grayscale') writer = tf.io.write_file(salient_image_name, normalized_tensor)# 加载初始权重model.load_weights('0_epochs.h5')# 为5个测试图像生成显著性图# 你的代码在这里do_salience('cat1.jpg', model, 0, "salient")do_salience('cat2.jpg', model, 0, "salient")do_salience('catanddog.jpg', model, 0, "salient")do_salience('dog1.jpg', model, 1, "salient")do_salience('dog2.jpg', model, 1, "salient")
我想通过运行do_salience()来查看显著性图,但我的代码不起作用,我不知道这个错误是什么意思。如果你能帮我修复它,我将不胜感激。
回答:
通常在深度学习/机器学习中,我们喜欢批量输入,以便在训练或进行推理时一次考虑多个输入。Tensorflow就是为此构建的,并为你的批处理数据的第一个维度提供了灵活的维度,它将其称为None
,这就是为什么它寻找维度为None, 300, 300, 3
的数据(你使用的每个数据点都是一个像素数组,维度为300, 300, 3)。你一次只对一张图像进行推理,所以你希望将数据准备成一个只有一个元素的批次,你在这一行中这样做了
tensor_image = tf.expand_dims(image, axis=0)
。
然而,你在代码的后面使用了image
,而不是tensor_image
,例如
inputs = tf.cast(image,tf.float32)
。
尝试在这里使用tensor_image
,即
inputs = tf.cast(tensor_image,tf.float32)