您可以使用这个混淆矩阵 PyTorch 示例计算误报/误报等:
import torch
def confusion(prediction, truth):
""" Returns the confusion matrix for the values in the `prediction` and `truth`
tensors, i.e. the amount of positions where the values of `prediction`
and `truth` are
- 1 and 1 (True Positive)
- 1 and 0 (False Positive)
- 0 and 0 (True Negative)
- 0 and 1 (False Negative)
"""
confusion_vector = prediction / truth
# Element-wise division of the 2 tensors returns a new tensor which holds a
# unique value for each case:
# 1 where prediction and truth are 1 (True Positive)
# inf where prediction is 1 and truth is 0 (False Positive)
# nan where prediction and truth are 0 (True Negative)
# 0 where prediction is 0 and truth is 1 (False Negative)
true_positives = torch.sum(confusion_vector == 1).item()
false_positives = torch.sum(confusion_vector == float('inf')).item()
true_negatives = torch.sum(torch.isnan(confusion_vector)).item()
false_negatives = torch.sum(confusion_vector == 0).item()
return true_positives, false_positives, true_negatives, false_negatives
您可以使用 nn.BCEWithLogitsLoss(因此删除 sigmoid)并设置 pos_weight > 1 以增加召回率。或者进一步优化它,使用Dice Coefficients 来惩罚模型的误报,例如:
def Dice(y_true, y_pred):
"""Returns Dice Similarity Coefficient for ground truth and predicted masks."""
#print(y_true.dtype)
#print(y_pred.dtype)
y_true = np.squeeze(y_true)/255
y_pred = np.squeeze(y_pred)/255
y_true.astype('bool')
y_pred.astype('bool')
intersection = np.logical_and(y_true, y_pred).sum()
return ((2. * intersection.sum()) + 1.) / (y_true.sum() + y_pred.sum() + 1.)
IOU 计算说明
- 计数真阳性 (TP)
- 计数误报 (FP)
- 计数假阴性 (FN)
- 交叉口 = TP
- 联合 = TP + FP + FN
- IOU = 交集/联合
左侧是我们的基本事实,而右侧包含我们的预测。左侧突出显示的单元格说明我们正在查看右侧的统计信息的类。右侧的突出显示奶油色为真阳性,橙色为假阳性,黄色为假阴性(请注意,所有其他都是真阴性——它们被预测为这个单独的类,不应基于基本事实)。
对于 0 类,只有 4x4 矩阵的顶行应预测为零。这是真实基础事实的相当简化的版本。实际上,零点可以在矩阵中的任何位置。在右侧,我们看到 1,0,0,0,这意味着第一个是假阴性,但其他三个是真阳性(也就是交叉路口的 3)。从那里,我们需要找到错误预测为零的其他任何地方,我们注意到第二行发生了一次,第四行发生了两次,总共有三个误报。
为了得到并集,我们将 TP (3)、FP (3) 和 FN (1) 相加得到 7。因此,这个类的 IOU 是 3/7。
如果我们对所有类都这样做并平均 IOU,我们会得到:
Mean IOU = [(3/7) + (2/6) + (3/4) + (1/6)] / 4 = 0.420
您还需要了解如何获取 mAP(平均平均精度)的统计数据:
- https://www.youtube.com/watch?v=pM6DJ0ZZee0
- https://towardsdatascience.com/breaking-down-mean-average-precision-map-ae462f623a52#1a59
- https://medium.com/@hfdtsinghua/calculate-mean-average-precision-map-for-multi-label-classification-b082679d31be
计算协方差矩阵
变量的方差描述了值的分布程度。协方差是一种衡量两个变量之间依赖程度的度量。
正协方差意味着当第二个变量的值也很大时,第一个变量的值很大。负协方差意味着相反:一个变量的大值与另一个变量的小值相关。
协方差值取决于变量的规模,因此很难对其进行分析。可以使用更容易解释的相关系数。相关系数就是归一化的协方差。
正协方差意味着一个变量的大值与另一个变量的大值相关联(左)。负协方差意味着一个变量的大值与另一个变量的小值相关联(右)。
协方差矩阵是一个矩阵,它总结了一组向量的方差和协方差,它可以告诉你关于变量的很多事情。对角线对应于每个向量的方差:
矩阵 A 及其协方差矩阵。对角线对应于每个列向量的方差。让我们检查方差的公式:
n 是向量的长度,x̄ 是向量的平均值。例如,A 的第一列向量的方差为:
这是协方差矩阵的第一个单元格。对角线上的第二个元素对应于 A 的第二个列向量的方差,依此类推。
注意:从矩阵A中提取的向量对应A的列。
其他单元格对应于来自 A 的两个列向量之间的协方差。例如,第一列和第三列之间的协方差位于协方差矩阵中,即第 1 列和第 3 行(或第 3 列和第第 1 行):
协方差矩阵中的位置。列对应于第一个变量,行对应于第二个(或相反)。 A 的第一列向量和第三列向量之间的协方差是第 1 列和第 3 行中的元素(或相反 = 相同的值)。
让我们检查 A 的第一列向量和第三列向量之间的协方差是否等于 -2.67。两个变量 X 和 Y 之间的协方差公式为:
变量 X 和 Y 是上一个示例中的第一个和第三个列向量。让我们拆分这个公式以确保它非常清晰:
-
求和符号 (Σ) 表示我们将对向量的元素进行迭代。我们将从第一个元素 (i=1) 开始,计算 X 的第一个元素减去向量 X 的平均值:
-
将结果乘以 Y 的第一个元素减去向量 Y 的平均值:
-
对向量的每个元素重复该过程并计算所有结果的总和:
-
除以向量中的元素个数。
示例 - 让我们从矩阵 A 开始:
我们将计算第一列向量和第三列向量之间的协方差:
和
x̄=3, ȳ=4, n=3 所以我们有:
代码示例 -
使用 NumPy,可以通过函数 np.cov 计算协方差矩阵。
值得注意的是,如果您希望 NumPy 将列用作向量,则必须使用参数 rowvar=False。此外,bias=True 除以 n 而不是 n-1。
让我们先创建数组:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
A = np.array([[1, 3, 5], [5, 4, 1], [3, 8, 6]])
现在我们将使用 NumPy 函数计算协方差:
np.cov(A, rowvar=False, bias=True)
用点积求协方差矩阵
还有另一种计算 A 的协方差矩阵的方法。您可以将 A 以 0 为中心。从向量的每个元素中减去向量的平均值,得到一个平均值等于 0 的向量。乘以它的自己的转置,并除以观察次数。
让我们从一个实现开始,然后我们将尝试理解与前面等式的联系:
def calculateCovariance(X):
meanX = np.mean(X, axis = 0)
lenX = X.shape[0]
X = X - meanX
covariance = X.T.dot(X)/lenX
return covariance
print(calculateCovariance(A))
输出:
array([[ 2.66666667, 0.66666667, -2.66666667],
[ 0.66666667, 4.66666667, 2.33333333],
[-2.66666667, 2.33333333, 4.66666667]])
两个向量之间的点积可以表示为:
它是向量的每个元素的乘积之和:
如果我们有一个矩阵 A,A 和它的转置之间的点积会给你一个新的矩阵:
可视化数据和协方差矩阵
为了更深入地了解协方差矩阵及其用途,我们将创建一个函数以将其与 2D 数据一起可视化。您将能够看到协方差矩阵和数据之间的联系。
这个函数将计算我们上面看到的协方差矩阵。它将创建两个子图 — 一个用于协方差矩阵,一个用于数据。 Seaborn 的 heatmap() 函数用于创建颜色渐变 — 小值将被着色为浅绿色,大值将被着色为深蓝色。我们选择了一种调色板颜色,但您可能更喜欢其他颜色。数据表示为散点图。
def plotDataAndCov(data):
ACov = np.cov(data, rowvar=False, bias=True)
print 'Covariance matrix:\n', ACov
fig, ax = plt.subplots(nrows=1, ncols=2)
fig.set_size_inches(10, 10)
ax0 = plt.subplot(2, 2, 1)
# Choosing the colors
cmap = sns.color_palette("GnBu", 10)
sns.heatmap(ACov, cmap=cmap, vmin=0)
ax1 = plt.subplot(2, 2, 2)
# data can include the colors
if data.shape[1]==3:
c=data[:,2]
else:
c="#0A98BE"
ax1.scatter(data[:,0], data[:,1], c=c, s=40)
# Remove the top and right axes from the data plot
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
不相关的数据
现在我们有了绘图函数,我们将生成一些随机数据来可视化协方差矩阵可以告诉我们的信息。我们将从使用 NumPy 函数 np.random.normal() 从正态分布中提取的一些数据开始。
此函数需要分布的均值、标准差和观察次数作为输入。我们将创建两个随机变量,包含 300 个观测值,标准差为 1。第一个的平均值为 1,第二个的平均值为 2。如果我们从正态分布中随机抽取两组 300 个观测值,则两个向量都是不相关。
np.random.seed(1234)
a1 = np.random.normal(2, 1, 300)
a2 = np.random.normal(1, 1, 300)
A = np.array([a1, a2]).T
A.shape
注意 1:我们使用 .T 转置数据,因为原始形状是 (2, 300),并且我们希望观察的数量为行(因此形状为 (300, 2))。
注 2:我们使用 np.random.seed 函数来实现重现性。下次我们运行该单元时将使用相同的随机数。让我们检查一下数据的样子:
A[:10,:]
array([[ 2.47143516, 1.52704645],
[ 0.80902431, 1.7111124 ],
[ 3.43270697, 0.78245452],
[ 1.6873481 , 3.63779121],
[ 1.27941127, -0.74213763],
[ 2.88716294, 0.90556519],
[ 2.85958841, 2.43118375],
[ 1.3634765 , 1.59275845],
[ 2.01569637, 1.1702969 ],
[-0.24268495, -0.75170595]])
很好,我们有两个列向量;现在,我们可以检查分布是否正常:
sns.distplot(A[:,0], color="#53BB04")
sns.distplot(A[:,1], color="#0A98BE")
plt.show()
plt.close()
我们可以看到分布具有相同的标准差,但均值不同(1 和 2)。这正是我们所要求的。
现在我们可以用函数绘制数据集及其协方差矩阵:
plotDataAndCov(A)
plt.show()
plt.close()
Covariance matrix:
[[ 0.95171641 -0.0447816 ]
[-0.0447816 0.87959853]]
我们可以在散点图上看到这两个维度是不相关的。请注意,我们有一个维度的平均值为 1(y 轴),而另一个维度的平均值为 2(x 轴)。
此外,协方差矩阵显示每个变量的方差非常大(大约为 1),而第 1 列和第 2 列的协方差非常小(大约为 0)。由于我们确保这两个向量是独立的,因此这是一致的。相反不一定正确:covariance of 0 doesn’t guarantee independence。
相关数据
现在,让我们通过从另一列中指定一列来构造依赖数据。
np.random.seed(1234)
b1 = np.random.normal(3, 1, 300)
b2 = b1 + np.random.normal(7, 1, 300)/2.
B = np.array([b1, b2]).T
plotDataAndCov(B)
plt.show()
plt.close()
Covariance matrix:
[[ 0.95171641 0.92932561]
[ 0.92932561 1.12683445]]
两个维度之间的相关性在散点图上可见。我们可以看到可以绘制一条线并用于从 x 预测 y,反之亦然。协方差矩阵不是对角线(对角线之外有非零单元格)。这意味着维度之间的协方差不为零。
通过协方差矩阵,您可以进一步研究以下内容:
- 均值归一化
- 标准化或规范化
- 美白
- 归零
- 去相关
- 重新缩放