Neural network 如何利用卷积神经网络中的三重态损失确定精度

Neural network 如何利用卷积神经网络中的三重态损失确定精度,neural-network,conv-neural-network,triplet,Neural Network,Conv Neural Network,Triplet,三重网络(受“暹罗网络”启发)由相同前馈网络的3个实例组成(具有共享参数)。当馈送3个样本时,网络输出2个中间值——其两个输入的嵌入表示之间的L2(欧几里德)距离 第三个代表 我正在使用三对图像为网络提供信息(x=锚图像,标准图像,x+=正图像,包含与x相同对象的图像-实际上,x+与x属于同一类,x-=负图像,与x属于不同类的图像 我正在使用所描述的三重线损耗成本函数。 如何确定网络的准确性?我假设您正在从事图像检索或类似任务 您应该首先生成一些三元组,可以是随机生成的,也可以是使用某种硬(半

三重网络(受“暹罗网络”启发)由相同前馈网络的3个实例组成(具有共享参数)。当馈送3个样本时,网络输出2个中间值——其两个输入的嵌入表示之间的L2(欧几里德)距离 第三个代表

我正在使用三对图像为网络提供信息(x=锚图像,标准图像,x+=正图像,包含与x相同对象的图像-实际上,x+与x属于同一类x-=负图像,与x属于不同类的图像

我正在使用所描述的三重线损耗成本函数。


如何确定网络的准确性?

我假设您正在从事图像检索或类似任务

您应该首先生成一些三元组,可以是随机生成的,也可以是使用某种硬(半硬)负挖掘方法生成的。然后将三元组拆分为训练集和验证集

如果您这样做,那么您可以将验证精度定义为验证三元组中锚定和正片之间的特征距离小于锚定和负片之间的特征距离的三元组数的比例。您可以看到哪个是用PyTorch编写的

另一种方法是,您可以直接根据最终的测试度量进行度量。例如,对于图像检索,通常我们使用度量测试集上模型的性能。如果您使用此度量,则应首先在验证集及其相应的基本事实图像上定义一些查询


以上两个指标中的任何一个都可以。选择您认为适合您的情况的任何指标。

因此,我正在执行一项类似的任务,即使用三重态损失进行分类。下面是我如何将新的损失方法用于分类器。 首先,使用N个历元的标准三重态损失函数训练模型。一旦确定模型(我们将称之为嵌入生成器)已训练,请保存权重,因为我们将在前面使用这些权重。 假设您的嵌入生成器定义为:

class EmbeddingNetwork(nn.Module):
def __init__(self):
    super(EmbeddingNetwork, self).__init__()
    self.conv1 = nn.Sequential(
        nn.Conv2d(1, 64, (7,7), stride=(2,2), padding=(3,3)),
        nn.BatchNorm2d(64),
        nn.LeakyReLU(0.001),
        nn.MaxPool2d((3, 3), 2, padding=(1,1))
    )
    self.conv2 = nn.Sequential(
        nn.Conv2d(64,64,(1,1), stride=(1,1)),
        nn.BatchNorm2d(64),
        nn.LeakyReLU(0.001),
        nn.Conv2d(64,192, (3,3), stride=(1,1), padding=(1,1)),
        nn.BatchNorm2d(192),
        nn.LeakyReLU(0.001),
        nn.MaxPool2d((3,3),2, padding=(1,1))
    )
    self.fullyConnected = nn.Sequential(
        nn.Linear(7*7*256,32*128),
        nn.BatchNorm1d(32*128),
        nn.LeakyReLU(0.001),
        nn.Linear(32*128,128)
    )
def forward(self,x):
  x = self.conv1(x)
  x = self.conv2(x)
  x = self.fullyConnected(x)
  return torch.nn.functional.normalize(x, p=2, dim=-1)
现在,我们将使用此嵌入生成器创建另一个分类器,将之前保存的权重拟合到网络的这一部分,然后冻结这一部分,这样我们的分类器培训师就不会干扰三元组模型。可以这样做:

class classifierNet(nn.Module):
def __init__(self, EmbeddingNet):
    super(classifierNet, self).__init__()
    self.embeddingLayer = EmbeddingNet
    self.classifierLayer = nn.Linear(128,62)
    self.dropout = nn.Dropout(0.5)

def forward(self, x):
    x = self.dropout(self.embeddingLayer(x))
    x = self.classifierLayer(x)
    return F.log_softmax(x, dim=1)
现在,我们将加载之前保存的重量,并使用以下方法将其冻结:

embeddingNetwork = EmbeddingNetwork().to(device)
embeddingNetwork.load_state_dict(torch.load('embeddingNetwork.pt'))
classifierNetwork = classifierNet(embeddingNetwork)

现在,使用标准分类损失(如二进制交叉熵或交叉熵)来训练分类器网络。

发生了一些非常奇怪的事情:准确率高达99%(定义见您的答案),但当我使用模型生成的嵌入对人进行分类时,只有20%的分类是正确的(网络将图像转换为124个浮点数).你能帮我吗?功能嵌入是为检索或聚类任务量身定做的。我不确定功能在分类任务中的有效性。另外,99%的准确率在验证集上?是的,我在验证集上得到了意想不到的好结果。实际上,我正在关注这篇文章,他们使用三重丢失进行人脸验证ion。我使用CASIA作为训练集(我正在生成违反丢失的三胞胎)和来自LFW的6400张随机照片作为验证集。我确信这两个数据集不会重叠(因此没有过度拟合)。有这么多影响因素。您的特征L2是否规范化?如何为val集生成三元组。您是否使用任何正则化(权重衰减、退出等)。您的测试集是什么?同样,为什么要使用为检索任务训练的特征来执行分类任务。