4

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

我使用成对的三个图像来馈送网络(x = 锚图像,标准图像,x+ = 正图像,包含与 x 相同对象的图像 - 实际上,x+ 与 x 属于同一类,并且x- = 负image与 x 具有不同类别的图像

在此处输入图像描述

我正在使用这里描述的三元组损失成本函数。

如何确定网络的准确性?

4

2 回答 2

4

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

您应该首先随机生成一些三元组,或者使用一些硬(半硬)负挖掘方法。然后你将你的三元组分成训练集和验证集。

如果你这样做,那么你可以将你的验证准确度定义为三元组数量的比例,其中锚点和正数之间的特征距离小于你的验证三元组中锚点和负数之间的距离。你可以在这里看到一个用 PyTorch 编写的示例。

作为另一种方式,您可以直接根据最终测试指标进行衡量。例如,对于图像检索,我们通常使用平均精度来衡量模型在测试集上的性能。如果你使用这个指标,你应该首先在你的验证集上定义一些查询和它们对应的地面实况图像。

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

于 2017-12-04T02:33:45.273 回答
0

所以我正在执行使用 Triplet loss 进行分类的类似任务。这是我如何将新颖的损失方法与分类器一起使用。首先,使用标准的三元组损失函数训练你的模型 N epochs。一旦您确定模型(我们将其称为嵌入生成器)经过训练,请保存权重,因为我们将在前面使用这些权重。假设您的嵌入生成器定义为:

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)

现在使用 BinaryCrossEntropy 或 CrossEntropy 等标准分类损失来训练这个分类器网络。

于 2021-04-08T11:27:40.880 回答