Python 3.x 计算混淆矩阵的更快方法?

Python 3.x 计算混淆矩阵的更快方法?,python-3.x,pytorch,metrics,confusion-matrix,Python 3.x,Pytorch,Metrics,Confusion Matrix,我正在计算我的混淆矩阵,如下所示,用于图像语义分割,这是一种非常详细的方法: def confusion_matrix(preds, labels, conf_m, sample_size): preds = normalize(preds,0.9) # returns [0,1] tensor preds = preds.flatten() labels = labels.flatten() for i in range(len(preds)):

我正在计算我的混淆矩阵,如下所示,用于图像语义分割,这是一种非常详细的方法:

def confusion_matrix(preds, labels, conf_m, sample_size):
    preds = normalize(preds,0.9) # returns [0,1] tensor
    preds = preds.flatten()
    labels = labels.flatten()
    for i in range(len(preds)):
        if preds[i]==1 and labels[i]==1:
            conf_m[0,0] += 1/(len(preds)*sample_size) # TP
        elif preds[i]==1 and labels[i]==0:
            conf_m[0,1] += 1/(len(preds)*sample_size) # FP
        elif preds[i]==0 and labels[i]==0:
            conf_m[1,0] += 1/(len(preds)*sample_size) # TN
        elif preds[i]==0 and labels[i]==1:
            conf_m[1,1] += 1/(len(preds)*sample_size) # FN 
    return conf_m
在预测循环中:

conf_m = torch.zeros(2,2) # two classes (object or no-object)
for img,label in enumerate(data):
    ...
    out = Net(img)
    conf_m = confusion_matrix(out, label, len(data))
    ...

是否有一种更快的方法(在PyTorch中)来有效地计算图像语义分割输入样本的混淆矩阵?

我使用这两个函数来计算混淆矩阵(如中所定义):

#将sklearn方法重写为torch
定义混淆矩阵1(y_真,y_pred):
N=max(max(y_真)、max(y_pred))+1
y_-true=torch.tensor(y_-true,dtype=torch.long)
y_pred=火炬.张量(y_pred,dtype=火炬.长)
返回火炬.稀疏.长传感器(
火炬堆栈([y_true,y_pred]),
torch.one_like(y_true,dtype=torch.long),
火炬尺寸([N,N])至密度()
#用bincount玩的诡计
def混淆矩阵2(y_真,y_pred):
N=max(max(y_真)、max(y_pred))+1
y_-true=torch.tensor(y_-true,dtype=torch.long)
y_pred=火炬.张量(y_pred,dtype=火炬.长)
y=N*y_真+y_预测
y=火炬的宾数(y)
如果len(y)
第二个函数在类数较少的情况下速度更快

%%timeit
混淆矩阵1(y_真,y_pred)
#每个回路102µs±30.7µs(7次运行的平均值±标准偏差,每个1000个回路)
%%时间
混淆矩阵2(y_真,y_pred)
#每个回路25µs±149 ns(7次运行的平均值±标准偏差,每个10000个回路)
谢谢您的回答!我不得不改变一些事情来配合我的实现

对于未来的观察者,这里是我的最后一个函数,它总结了一批输入中每个混淆矩阵的百分比(用于训练或测试循环)

def混淆矩阵2(y_真,y_pred,sample_sz,conf_m):
y_pred=标准化(y_pred,0.9)
obj=y_真[y_真==1]
否对象=y\u真[y\u真==0]
N=火炬张量(火炬最大值(火炬最大值(y_真)、火炬最大值(y_pred))+1,dtype=火炬int)
y_-true=torch.tensor(y_-true,dtype=torch.long)
y_pred=火炬.张量(y_pred,dtype=火炬.长)
y=N*y_真+y_预测
y=火炬。bincount(y.展平()
如果len(y)
也感谢格里戈里·费尔德曼的回答
我和O先生和numpy在一起

# weird trick with bincount
def confusion_matrix_2_numpy(y_true, y_pred, N=None):
    y_true = y_true.reshape(-1)
    y_pred = y_pred.reshape(-1) 
    if (N is None):
        N = max(max(y_true), max(y_pred)) + 1
    y = N * y_true + y_pred
    y = np.bincount(y, minlength=N*N)
    y = y.reshape(N, N)
    return y
请试试这个。
当你使用一个已知的类号时,它会更快。
我应该提到的一点是,在某些情况下,最大值与原始类数不匹配。

例如,当批量较小且每次迭代都集成了混淆矩阵时。

未定义规范化。你是说
y\u pred=(ypred>0.9).float()
?加上这个实现在混淆矩阵2中给出了NaNs.return y而不是T
# weird trick with bincount
def confusion_matrix_2_numpy(y_true, y_pred, N=None):
    y_true = y_true.reshape(-1)
    y_pred = y_pred.reshape(-1) 
    if (N is None):
        N = max(max(y_true), max(y_pred)) + 1
    y = N * y_true + y_pred
    y = np.bincount(y, minlength=N*N)
    y = y.reshape(N, N)
    return y