如何绘制分割模型的精确召回曲线?
How to draw the precision-recall curve for a segmentation model?
我正在使用 U-Net 来分割我感兴趣的数据。蒙版是灰度的,大小为 (256,256,1)。测试集中有 80 张图像。测试图像 (X_ts) 及其各自的真实掩模 (Y_ts) 的构建、保存和加载如下:
from tqdm import tqdm
im_width = 256
im_height = 256
ids_test = next(os.walk("data/test/image"))[2]
print("No. of images = ", len(ids_test))
X_ts = np.zeros((len(ids_test), im_height, im_width, 3), dtype=np.float32)
Y_ts = np.zeros((len(ids_test), im_height, im_width, 1), dtype=np.float32)
print(X_ts.shape)
print(Y_ts.shape)
for n, id_ in tqdm(enumerate(ids_test), total=len(ids_test)):
# Load images
img = load_img("data/test/image/"+id_,
color_mode = "rgb")
x_img = img_to_array(img)
x_img = resize(x_img, (256,256,3),
mode = 'constant', preserve_range = True)
# Load masks
mask = img_to_array(load_img("data/test/label/"+id_,
color_mode = "grayscale"))
mask = resize(mask, (256,256,1),
mode = 'constant', preserve_range = True)
# Save images
X_ts[n] = x_img/255.0
Y_ts[n] = mask/255.0
np.save('./data/X_ts.npy',X_ts)
np.save('./data/Y_ts.npy',Y_ts)
#load the data
X_ts = np.load('./data/X_ts.npy')
Y_ts = np.load('./data/Y_ts.npy')
Y_ts(ground truth)的形状因此是(80,256,256,1)并且它们是“类型为 float32 的数组”类型。我使用训练有素的模型预测了面具,如下所示:
Y_ts_pred = model.predict(X_ts,batch_size=1)
print(Y_ts_pred.shape)
threshold=0.5
Y_ts_pred[Y_ts_pred<threshold]=0
Y_ts_pred[Y_ts_pred>=threshold]=1
Y_ts_pred 的形状是 (80,256,256,1),它们的类型是“Array of type float32”。现在,我使用 Y_ts(ground truth masks)和 Y_ts_pred(预测的 masks)计算精确召回曲线,如下所示:
from sklearn.metrics import precision_recall_curve
import numpy as np
import matplotlib.pyplot as plt
precision, recall, thresholds = precision_recall_curve(Y_ts, Y_ts_pred)
precision = np.fliplr([precision])[0] #to avoid getting negative AUC)
recall = np.fliplr([recall])[0] #to avoid getting negative AUC)
AUC_prec_rec = np.trapz(precision,recall)
print "\nArea under Precision-Recall curve: " +str(AUC_prec_rec)
prec_rec_curve = plt.figure()
plt.plot(recall,precision,'-',label='Area Under the Curve (AUC = %0.4f)' % AUC_prec_rec)
plt.title('Precision - Recall curve')
plt.xlabel("Recall")
plt.ylabel("Precision")
plt.legend(loc="lower right")
plt.savefig("Precision_recall.png")
我收到以下错误:
File "/tmp/ipykernel_2425796/385729104.py", line 1, in <module>
precision, recall, thresholds = precision_recall_curve(Y_ts, Y_ts_pred)
File "/home/anaconda3/envs/tf262/lib/python3.7/site-packages/sklearn/metrics/_ranking.py", line 859, in precision_recall_curve
y_true, probas_pred, pos_label=pos_label, sample_weight=sample_weight
File "/home/anaconda3/envs/tf262/lib/python3.7/site-packages/sklearn/metrics/_ranking.py", line 731, in _binary_clf_curve
raise ValueError("{0} format is not supported".format(y_type))
ValueError: unknown format is not supported
precision_recall_curve() 只能接受 1D 输入,而您的数据是 3D。您不能直接在蒙版上计算精度和召回率。
我必须将我的基本事实和预测蒙版转换为 one-dimensional 向量,并使用如下阈值将它们二值化。然后,上面的代码就可以工作了。
Y_ts_pred = Y_ts_pred.reshape(Y_ts_pred.shape[0]*Y_ts_pred.shape[1]*Y_ts_pred.shape[2], 1)
print(Y_ts_pred.shape)
Y_ts = Y_ts.reshape(Y_ts.shape[0]*Y_ts.shape[1]*Y_ts.shape[2], 1)
print(Y_ts.shape)
Y_ts_pred = np.where(Y_ts_pred>0.5, 1, 0)
Y_ts = np.where(Y_ts>0.5, 1, 0)
我正在使用 U-Net 来分割我感兴趣的数据。蒙版是灰度的,大小为 (256,256,1)。测试集中有 80 张图像。测试图像 (X_ts) 及其各自的真实掩模 (Y_ts) 的构建、保存和加载如下:
from tqdm import tqdm
im_width = 256
im_height = 256
ids_test = next(os.walk("data/test/image"))[2]
print("No. of images = ", len(ids_test))
X_ts = np.zeros((len(ids_test), im_height, im_width, 3), dtype=np.float32)
Y_ts = np.zeros((len(ids_test), im_height, im_width, 1), dtype=np.float32)
print(X_ts.shape)
print(Y_ts.shape)
for n, id_ in tqdm(enumerate(ids_test), total=len(ids_test)):
# Load images
img = load_img("data/test/image/"+id_,
color_mode = "rgb")
x_img = img_to_array(img)
x_img = resize(x_img, (256,256,3),
mode = 'constant', preserve_range = True)
# Load masks
mask = img_to_array(load_img("data/test/label/"+id_,
color_mode = "grayscale"))
mask = resize(mask, (256,256,1),
mode = 'constant', preserve_range = True)
# Save images
X_ts[n] = x_img/255.0
Y_ts[n] = mask/255.0
np.save('./data/X_ts.npy',X_ts)
np.save('./data/Y_ts.npy',Y_ts)
#load the data
X_ts = np.load('./data/X_ts.npy')
Y_ts = np.load('./data/Y_ts.npy')
Y_ts(ground truth)的形状因此是(80,256,256,1)并且它们是“类型为 float32 的数组”类型。我使用训练有素的模型预测了面具,如下所示:
Y_ts_pred = model.predict(X_ts,batch_size=1)
print(Y_ts_pred.shape)
threshold=0.5
Y_ts_pred[Y_ts_pred<threshold]=0
Y_ts_pred[Y_ts_pred>=threshold]=1
Y_ts_pred 的形状是 (80,256,256,1),它们的类型是“Array of type float32”。现在,我使用 Y_ts(ground truth masks)和 Y_ts_pred(预测的 masks)计算精确召回曲线,如下所示:
from sklearn.metrics import precision_recall_curve
import numpy as np
import matplotlib.pyplot as plt
precision, recall, thresholds = precision_recall_curve(Y_ts, Y_ts_pred)
precision = np.fliplr([precision])[0] #to avoid getting negative AUC)
recall = np.fliplr([recall])[0] #to avoid getting negative AUC)
AUC_prec_rec = np.trapz(precision,recall)
print "\nArea under Precision-Recall curve: " +str(AUC_prec_rec)
prec_rec_curve = plt.figure()
plt.plot(recall,precision,'-',label='Area Under the Curve (AUC = %0.4f)' % AUC_prec_rec)
plt.title('Precision - Recall curve')
plt.xlabel("Recall")
plt.ylabel("Precision")
plt.legend(loc="lower right")
plt.savefig("Precision_recall.png")
我收到以下错误:
File "/tmp/ipykernel_2425796/385729104.py", line 1, in <module>
precision, recall, thresholds = precision_recall_curve(Y_ts, Y_ts_pred)
File "/home/anaconda3/envs/tf262/lib/python3.7/site-packages/sklearn/metrics/_ranking.py", line 859, in precision_recall_curve
y_true, probas_pred, pos_label=pos_label, sample_weight=sample_weight
File "/home/anaconda3/envs/tf262/lib/python3.7/site-packages/sklearn/metrics/_ranking.py", line 731, in _binary_clf_curve
raise ValueError("{0} format is not supported".format(y_type))
ValueError: unknown format is not supported
precision_recall_curve() 只能接受 1D 输入,而您的数据是 3D。您不能直接在蒙版上计算精度和召回率。
我必须将我的基本事实和预测蒙版转换为 one-dimensional 向量,并使用如下阈值将它们二值化。然后,上面的代码就可以工作了。
Y_ts_pred = Y_ts_pred.reshape(Y_ts_pred.shape[0]*Y_ts_pred.shape[1]*Y_ts_pred.shape[2], 1)
print(Y_ts_pred.shape)
Y_ts = Y_ts.reshape(Y_ts.shape[0]*Y_ts.shape[1]*Y_ts.shape[2], 1)
print(Y_ts.shape)
Y_ts_pred = np.where(Y_ts_pred>0.5, 1, 0)
Y_ts = np.where(Y_ts>0.5, 1, 0)