Python循环中Numpy数组未更新致指标异常的排查与修复
问题:Python嵌套循环中阈值计算指标重复的问题
在嵌套循环中针对不同阈值计算数据指标时,发现循环内各阈值得到的指标完全相同,但单独运行单个阈值时结果正常。
循环运行异常输出:
Thr: 0.1 iou median 0.8630754827737117 iou mean 0.8386529686837483 Thr: 0.2 iou median 0.8630754827737117 iou mean 0.8386529686837483 Thr: 0.3 iou median 0.8630754827737117 iou mean 0.8386529686837483
单独运行正常输出:
Thr: 0.1 iou median 0.8630754827737117 iou mean 0.8386529686837483 Thr: 0.2 iou median 0.8909001769131588 iou mean 0.8748827498937638 Thr: 0.3 iou median 0.9528955473520166 iou mean 0.9301409526378364
问题代码:
for t in thresholds: print(f"Thr: {t}") mse_tmp = list() iou_tmp = list() all_images = zip(all_test_images, all_generated_images) for test_image, generated_image in all_images: test_image[test_image > t] = 1. test_image[test_image != 1.] = 0. generated_image[generated_image > t] = 1. generated_image[generated_image != 1.] = 0. labels = [0., 1. ] #np.unique(test_image) score_iou = metrics.jaccard_score(test_image.ravel(), generated_image.ravel(), labels=labels, average='micro') mse_score = metrics.mean_squared_error(test_image.ravel(), generated_image.ravel()) iou_tmp.append(score_iou) mse_tmp.append(mse_score) iou_scores.append(iou_tmp) mse.append(mse_tmp) print("iou median {} \n".format(np.median(np.array(iou_tmp))), "iou mean {} \n".format(np.array(iou_tmp).mean())) mse_tmp = [] iou_tmp = [] del mse_tmp del iou_tmp
原因分析
核心问题是直接修改了原始的numpy数组:
all_test_images和all_generated_images中的元素是numpy数组,属于可变对象。- 第一次循环处理时,代码直接对
test_image和generated_image进行赋值操作(test_image[test_image > t] = 1.),这会修改原始数组的数据,将其永久变成二值化后的0/1。 - 后续循环迭代时,所有图像已经是0或1,无论阈值
t是多少,test_image > t的判断结果都完全一致,导致计算出的指标重复。
修复方案
在每次处理图像前,创建原始数组的副本,修改副本而非原始数据:
- 使用
test_image.copy()和generated_image.copy()生成副本,确保每次循环都基于原始数据进行阈值处理。
修复后的代码:
for t in thresholds: print(f"Thr: {t}") mse_tmp = list() iou_tmp = list() all_images = zip(all_test_images, all_generated_images) for test_image, generated_image in all_images: # 创建副本,避免修改原始数据 test_img_copy = test_image.copy() gen_img_copy = generated_image.copy() test_img_copy[test_img_copy > t] = 1. test_img_copy[test_img_copy != 1.] = 0. gen_img_copy[gen_img_copy > t] = 1. gen_img_copy[gen_img_copy != 1.] = 0. labels = [0., 1.] score_iou = metrics.jaccard_score(test_img_copy.ravel(), gen_img_copy.ravel(), labels=labels, average='micro') mse_score = metrics.mean_squared_error(test_img_copy.ravel(), gen_img_copy.ravel()) iou_tmp.append(score_iou) mse_tmp.append(mse_score) iou_scores.append(iou_tmp) mse.append(mse_tmp) print(f"iou median {np.median(np.array(iou_tmp))} \n", f"iou mean {np.array(iou_tmp).mean()} \n")
内容的提问来源于stack exchange,提问作者Misslinska
相关产品推荐
相关产品推荐

