变化检测里面的尺寸变换问题

有个问题想寻求解决,就是batch-size设置1就正常,设置为4就报错:RuntimeError: shape '[32, 65536]' is invalid for input of size 8388608,找根源,指向一段代码,代码功能是把两个尺寸为 ( 4,32,256,256 )的输入进行尺寸变换,然后计算这两个输入的余弦相似度。该怎样进行修改,才能适应整体功能。

def single_layer_similar_heatmap_visual(idx,output_t0,output_t1,save_change_map_dir,epoch,batch_idx,filename,layer_flag,dist_flag):
    n, c, h, w = output_t0.data.shape     #####[4, 32, 256, 256]
    out_t0_rz = torch.transpose(output_t0.view(c, h * w ), 1, 0)    #####我觉得问题应该出在这里的变换
    out_t1_rz = torch.transpose(output_t1.view(c, h * w ), 1, 0)

      # 计算像素对在通道上的距离,比如0,0处的两个通道的距离,这个距离应该是都小于2的
    distance = various_distance(out_t0_rz,out_t1_rz,dist_flag=dist_flag)
    similar_distance_map = distance.view(h,w).data.cpu().numpy() # 256x256

    # 插值到256x256
    similar_distance_map_rz = nn.functional.interpolate(torch.from_numpy(similar_distance_map[np.newaxis, np.newaxis, :]),
                                                        size=[cfg.TRANSFROM_SCALES[1],cfg.TRANSFROM_SCALES[0]], mode='bilinear',align_corners=True)
# 渲染热力图并保存
    save_change_map_dir_ = os.path.join(save_change_map_dir, 'epoch_' + str(epoch))
    check_dir(save_change_map_dir_)
    save_change_map_dir_layer = os.path.join(save_change_map_dir_,layer_flag)
    check_dir(save_change_map_dir_layer)
    save_weight_fig_dir = os.path.join(save_change_map_dir_layer, str(batch_idx) + '_' + filename[0].split('/')[2])
    if idx % 20 == 0:
        # similar_dis_map_colorize = cv2.applyColorMap(np.uint8(255 * similar_distance_map_rz.data.cpu().numpy()[0][0]), cv2.COLORMAP_JET)
        # cv2.imwrite(save_weight_fig_dir, similar_dis_map_colorize)
        similar_dis_map_colorize = cv2.applyColorMap(np.uint8(255 * similar_distance_map_rz.data.cpu().numpy()[0][0]),
                                                     cv2.COLORMAP_JET)
        cv2.imwrite(os.path.join(save_weight_fig_dir, 'vertira.jpg'), similar_dis_map_colorize)
    # 返回距离map
    return similar_distance_map_rz.data.cpu().numpy()

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
问题出在这两行代码:

out_t0_rz = torch.transpose(output_t0.view(c, h * w ), 1, 0)
out_t1_rz = torch.transpose(output_t1.view(c, h * w ), 1, 0)

当batch_size设置为4时,output_t0output_t1的形状变为[4, 32, 256, 256]。然后你试图将它们reshape为[4, 32*256, 256],这会导致形状不匹配的错误。

解决方法是将这两行代码修改为:

out_t0_rz = output_t0.view(n, c, h, w)
out_t1_rz = output_t1.view(n, c, h, w)

这样,无论batch_size设置为多少,都可以正确地进行尺寸变换。所以,完整的修改后的函数如下:

def single_layer_similar_heatmap_visual(idx,output_t0,output_t1,save_change_map_dir,epoch,batch_idx,filename,layer_flag,dist_flag):
    n, c, h, w = output_t0.data.shape     #####[4, 32, 256, 256]
    out_t0_rz = output_t0.view(n, c, h, w)
    out_t1_rz = output_t1.view(n, c, h, w)
 
    # 计算像素对在通道上的距离,比如0,0处的两个通道的距离,这个距离应该是都小于2的
    distance = various_distance(out_t0_rz,out_t1_rz,dist_flag=dist_flag)
    similar_distance_map = distance.view(h,w).data.cpu().numpy() # 256x256
 
    # 插值到256x256
    similar_distance_map_rz = nn.functional.interpolate(torch.from_numpy(similar_distance_map[np.newaxis, np.newaxis, :]),
                                                        size=[cfg.TRANSFROM_SCALES[1],cfg.TRANSFROM_SCALES[0]], mode='bilinear',align_corners=True)
# 渲染热力图并保存
    save_change_map_dir_ = os.path.join(save_change_map_dir, 'epoch_' + str(epoch))
    check_dir(save_change_map_dir_)
    save_change_map_dir_layer = os.path.join(save_change_map_dir_,layer_flag)
    check_dir(save_change_map_dir_layer)
    save_weight_fig_dir = os.path.join(save_change_map_dir_layer, str(batch_idx) + '_' + filename[0].split('/')[2])
    if idx % 20 == 0:
        # similar_dis_map_colorize = cv2.applyColorMap(np.uint8(255 * similar_distance_map_rz.data.cpu().numpy()[0][0]), cv2.COLORMAP_JET)
        # cv2.imwrite(save_weight_fig_dir, similar_dis_map_colorize)
        similar_dis_map_colorize = cv2.applyColorMap(np.uint8(255 * similar_distance_map_rz.data.cpu().numpy()[0][0]),
                                                     cv2.COLORMAP_JET)
        cv2.imwrite(os.path.join(save_weight_fig_dir, 'vertira.jpg'), similar_dis_map_colorize)
    # 返回距离map
    return similar_distance_map_rz.data.cpu().numpy()

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

看起来这个错误是因为你在将 output_t0output_t1 变形为二维矩阵时,试图创建一个形状为 [32, 65536] 的矩阵,而你的输入数据的总大小只有 8388608,这是不可能的。

你的代码中, output_t0.view(c, h * w )output_t1.view(c, h * w ) 这部分可能存在问题。view 函数会尝试创建一个新的张量,其形状由参数给出,而不会考虑原始张量的形状。因此,当你试图将尺寸为 [4, 32, 256, 256] 的张量变形为 [32, 65536] 时,PyTorch 就会抛出错误,因为这需要原始张量至少有 32 * 65536 = 2048000 个元素,而实际上只有 4 * 32 * 256 * 256 = 8388608 个元素。

要修复这个问题,你需要重新考虑你的 single_layer_similar_heatmap_visual 函数中的数据流和尺寸变换。具体来说,你需要了解你的 output_t0output_t1 的具体内容和目标用途,然后确保你在使用 viewtranspose 等操作时,不会尝试创建一个不合法的张量。

引用 皆我百晓生 小程序回复内容作答:
问题的根源在于输入的batch size不同导致的尺寸不匹配。当batch size为1时,尺寸为[4, 32, 256, 256]的输入进行尺寸变换没有问题。但是当batch size为4时,尺寸变换的代码会出错。

为了适应整体功能,你可以通过以下方式修改代码:

  1. 将尺寸变换的代码修改为适应不同batch size的情况。可以使用torch.reshape函数来改变张量的形状,而不改变其元素的总数。修改代码如下:
out_t0_rz = torch.transpose(output_t0.view(n * c, h * w), 1, 0)
out_t1_rz = torch.transpose(output_t1.view(n * c, h * w), 1, 0)

这样可以将输入张量的尺寸从[4, 32, 256, 256]变为[128, 65536]。

  1. 由于你的代码要求输出的尺寸为[256, 256],你需要根据不同batch size的情况,将输出的尺寸修改为匹配的值。修改代码如下:
similar_distance_map_rz = nn.functional.interpolate(torch.from_numpy(similar_distance_map[np.newaxis, np.newaxis, :]),
                                                    size=[n * 256, 256], mode='bilinear', align_corners=True)

这样可以将输出的尺寸从[1, 1, 256, 256]变为[4, 1, 256, 256]或其它适应不同batch size的尺寸。

通过以上修改,你的代码应该能够适应不同batch size的情况,并计算两个输入的余弦相似度。

Open CV里面有resize
TensorFlow里面也有归一化。

【以下回答由 GPT 生成】

首先,根据您的描述,您遇到了设置批处理大小为4时的错误。您怀疑问题出在尺寸变换的处理上。以下是对代码的检查和可能的修改建议:

  1. 检查输入数据的维度:确保output_t0output_t1的形状为[batch_size, channels, height, width]。确保batch_size为4。

  2. 检查尺寸变换的处理:根据代码,将output_t0output_t1展平为[channels, height * width]的形状。您可以使用以下代码执行尺寸变换:

out_t0_rz = output_t0.view(n * c, h * w) # 将尺寸变换应用于output_t0
out_t1_rz = output_t1.view(n * c, h * w) # 将尺寸变换应用于output_t1
  1. 检查距离计算:根据代码,距离计算应用于out_t0_rzout_t1_rz。确保out_t0_rzout_t1_rz的形状为[batch_size * channels, height * width]。以下是一个示例代码,用于计算通道上像素对之间的距离:
def various_distance(out_t0_rz, out_t1_rz, dist_flag):
    # 在这里执行距离计算
    # 返回计算结果
  1. 检查插值操作:根据代码,使用nn.functional.interpolate将距离图像插值为目标尺寸。确保插值操作的目标尺寸与cfg.TRANSFROM_SCALES中定义的尺寸相匹配,如[256, 256]。以下是一个示例代码,用于插值操作:
def resize_image(similar_distance_map, target_size):
    resized_map = nn.functional.interpolate(similar_distance_map, size=target_size, mode='bilinear', align_corners=True)
    return resized_map
  1. 检查保存图片的路径:确保保存路径的目录存在。您可以使用os.path.exists()函数来检查目录是否存在,并使用os.makedirs()函数来创建目录。

根据以上建议,修改代码如下:

def single_layer_similar_heatmap_visual(idx, output_t0, output_t1, save_change_map_dir, epoch, batch_idx, filename, layer_flag, dist_flag):
    # 检查输入数据的维度
    n, c, h, w = output_t0.size()
    assert batch_size == 4

    # 尺寸变换
    out_t0_rz = output_t0.view(n * c, h * w)
    out_t1_rz = output_t1.view(n * c, h * w)

    # 计算通道上像素对之间的距离
    distance = various_distance(out_t0_rz, out_t1_rz, dist_flag=dist_flag)
    similar_distance_map = distance.view(h, w).data.cpu().numpy() # 256x256

    # 插值操作
    target_size = [cfg.TRANSFROM_SCALES[1], cfg.TRANSFROM_SCALES[0]]
    similar_distance_map_rz = resize_image(torch.from_numpy(similar_distance_map[np.newaxis, np.newaxis, :]), target_size)

    # 保存热力图图片
    save_change_map_dir_ = os.path.join(save_change_map_dir, 'epoch_' + str(epoch))
    if not os.path.exists(save_change_map_dir_):
        os.makedirs(save_change_map_dir_)

    save_change_map_dir_layer = os.path.join(save_change_map_dir_, layer_flag)
    if not os.path.exists(save_change_map_dir_layer):
        os.makedirs(save_change_map_dir_layer)

    save_weight_fig_dir = os.path.join(save_change_map_dir_layer, str(batch_idx) + '_' + filename[0].split('/')[2])
    if idx % 20 == 0:
        # similar_dis_map_colorize = cv2.applyColorMap(np.
        # 这里继续实现保存图片的逻辑

请注意,在以上代码示例中可能仍需要继续实现保存图片的逻辑。希望以上修改建议能够帮助您解决问题。如果还有其他疑问,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

结合GPT给出回答如下请题主参考
根据你提供的信息,可以初步判断这个错误是由于输入的 batch size 导致的。在 batch size 为 1 时正常,但当 batch size 改为 4 时,输入的数据形状变化导致了维度不匹配的错误。

具体来说,一般情况下,深度学习模型输入的数据形状是 (batch_size, channels, height, width),其中 batch_size 表示输入的样本数,channels 表示输入数据的通道数,height 和 width 分别表示输入数据的高度和宽度。在输入数据时,需要确保不同的样本之间的数据形状一致,因此在设置 batch size 时需要注意。

对于你的错误信息,在 batch size 为 4 时,输入数据形状为 [32, 65536],其中 32 为 batch size,但这个形状是不合法的,因为缺少了 channels、height 和 width 的维度。可能是你在输入数据时出现了错误,导致输入数据的形状与你的模型不匹配。

解决该问题,建议检查数据集中的数据形状是否正确,或者检查代码中是否存在数据 reshape 或 transpose 操作,以确保输入数据形状与模型期望的形状匹配。


def single_layer_similar_heatmap_visual(idx, output_t0, output_t1, save_change_map_dir, epoch, batch_idx, filename, layer_flag, dist_flag):
    n, c, h, w = output_t0.data.shape  # 获取输入数据的形状
    out_t0_rz = torch.transpose(output_t0.view(n, c, -1), 2, 1)  # 将输入数据重新排列为(batch-size,通道数,h*w)
    out_t1_rz = torch.transpose(output_t1.view(n, c, -1), 2, 1)

    # 计算像素对在通道上的距离
    distance = various_distance(out_t0_rz, out_t1_rz, dist_flag=dist_flag)
    similar_distance_map = distance.view(n, h, w).data.cpu().numpy()  # 将结果还原为(batch-size,h,w)

    # 插值到指定大小的图像
    target_size = [cfg.TRANSFROM_SCALES[1], cfg.TRANSFROM_SCALES[0]]
    similar_distance_map_rz = nn.functional.interpolate(torch.from_numpy(similar_distance_map),
                                                        size=target_size, mode='bilinear', align_corners=True)

    # 渲染热力图并保存
    save_change_map_dir_ = os.path.join(save_change_map_dir, 'epoch_' + str(epoch))
    check_dir(save_change_map_dir_)
    save_change_map_dir_layer = os.path.join(save_change_map_dir_, layer_flag)
    check_dir(save_change_map_dir_layer)
    save_weight_fig_dir = os.path.join(save_change_map_dir_layer, str(batch_idx) + '_' + filename[0].split('/')[2])
    if idx % 20 == 0:
        similar_dis_map_colorize = cv2.applyColorMap(np.uint8(255 * similar_distance_map_rz.data.cpu().numpy()[0][0]),
                                                     cv2.COLORMAP_JET)
        cv2.imwrite(os.path.join(save_weight_fig_dir, 'vertira.jpg'), similar_dis_map_colorize)

    # 返回距离map
    return similar_distance_map_rz.data.cpu().numpy()

这个错误发生的原因是,你的网络或者操作试图在Tensor的形状为 [32, 65536] 的地方进行操作,但是这个形状对于你的输入数据来说是不合适的。这通常是由于你的网络结构或者操作要求特定的输入形状,但你的输入数据并没有满足这个要求。

对于你的问题,你提到了输入尺寸为 (4, 32, 256, 256)。如果你要进行余弦相似度的计算,那么通常你需要确保你的输入形状是可以进行这种计算的。一般来说,余弦相似度通常在两个相同形状的Tensor之间计算,所以你的两个输入应该具有相同的形状。

根据你的描述,我猜测你可能在使用PyTorch或者TensorFlow这类框架进行深度学习的开发。如果你想要计算两个不同形状的Tensor之间的余弦相似度,那么你可能需要对你的数据进行相应的调整。

你可以尝试以下步骤来解决问题:

  1. 首先,检查你的网络结构或者操作是否需要特定的输入形状。如果有,确保你的输入满足这些要求。
  2. 其次,检查你的数据预处理步骤。这是否有可能导致你的输入数据改变了形状?例如,如果你在进行数据增强或者预处理步骤的时候进行了重采样或者裁剪,这可能会导致数据的形状发生变化。
  3. 最后,确保你计算余弦相似度的两个输入具有相同的形状。如果你不能改变其中一个输入的形状,你可能需要重新考虑你的计算方法。例如,你可以将两个不同形状的Tensor拼接在一起,然后取它们之间的余弦相似度。但是请注意,这样做可能会改变你的结果。

希望以上建议能帮助你解决问题。如果你需要更具体的帮助,例如修改代码,欢迎提供更多的信息,我会尽力提供更详细的建议。

可能的问题以下几点:

维度匹配问题:您在torch.transpose(output_t0.view(c, h * w ), 1, 0)这一行使用了torch.transpose来转置一个张量,这通常用于对二维或更高维度的张量进行转置。但如果output_t0的维度小于2,这个函数就会报错。因此,您需要确保output_t0的维度至少为2。
理解torch.transpose的作用:torch.transpose函数用于交换张量的维度。它的三个参数是输入张量、需要交换的维度1和需要交换的维度2。例如,如果您的张量是二维的,并且您想交换第0和第1维度,那么您应该使用torch.transpose(input_tensor, 0, 1)。在这里,您需要确保您在正确的维度上进行转置。
检查各种距离函数:代码中使用了various_distance函数来计算两个张量之间的距离,但没有给出这个函数的定义。请确保这个函数的输入和输出是符合预期的。
路径问题:请确保所有涉及的文件和文件夹路径(例如save_change_map_dir_layer和save_weight_fig_dir)都是存在的,否则在尝试写入文件时可能会引发错误。
检查图片名称:您在写入图片时使用了'vertira.jpg'作为文件名。请确保这是您预期的文件名,或者根据您的需求进行相应的更改。