我使用预训练的ResNet为每个图像提取1000个维特征,然后将这些图像放入我自己构建的网络中以执行分类任务并使用三重损失函数。
我的代码中有一部分:
class Network(torch.nn.Module):
def __init__(self,n_feature = 1000, n_hidden_1 = 200, n_hidden_2 = 100, n_hidden_3 = 50, n_hidden_4 = 20,n_output = 3):
super(Network, self).__init__()
self.net = torch.nn.Sequential(
torch.nn.Linear(n_feature, n_hidden_1),
torch.nn.BatchNorm1d(n_hidden_1),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden_1, n_hidden_2),
torch.nn.BatchNorm1d(n_hidden_2),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden_2, n_hidden_3),
torch.nn.BatchNorm1d(n_hidden_3),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden_3, n_hidden_4),
torch.nn.BatchNorm1d(n_hidden_4),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden_4, n_output),
torch.nn.Sigmoid()
)
def forward(self, x):
x = self.net(x)
return x
并且有培训和验证过程:
for epoch in tqdm(range(n_epoch)):
model.train()
for step, (batch_anchor, batch_positive, batch_negative )in enumerate(train_loader):
anchor_out = model(batch_anchor)
positive_out = model(batch_positive)
negative_out = model(batch_negative)
loss = loss_func(anchor_out, positive_out, negative_out)
optimizer.zero_grad()
loss.backward()
optimizer.step()
model.eval()
for step, (batch_anchor_val, batch_positive_val, batch_negative_val) in enumerate(val_loader):
anchor_out_val = model(batch_anchor_val)
positive_out_val = model(batch_positive_val)
negative_out_val = model(batch_negative_val)
loss_val = loss_func(anchor_out_val, positive_out_val, negative_out_val)
我在其中定义损失函数和优化器,如下所示:
optimizer = optim.Adam(model.parameters(), lr=0.002)
loss_func = torch.nn.TripletMarginLoss(p=2, margin=1)
和一些结果:
Epoch: 1/50 - Loss: 0.8764 - Val_loss: 0.9920
Epoch: 2/50 - Loss: 0.7035 - Val_loss: 0.9897
Epoch: 3/50 - Loss: 0.6313 - Val_loss: 0.9972
Epoch: 4/50 - Loss: 0.5958 - Val_loss: 0.9980
Epoch: 5/50 - Loss: 0.5724 - Val_loss: 0.9930
Epoch: 6/50 - Loss: 0.5541 - Val_loss: 1.0123
...
虽然训练过程中,火车损失总是在减少,但val损失却没有改变,我不知道为什么,也许有人知道潜在的原因是什么?我已经阅读了一些博客,并检查了我的数据集,我确定我的数据集已正确拆分。
答案 0 :(得分:0)
似乎您的模型无法推广到val set。这意味着模型无法找到(锚定,正值)与(锚定,负值)之间的差异。在这种情况下,(锚定,正值)的距离-(锚定,负值)的距离==0。并且由于您的边距设置为1。损失将保持为1 。调用TripletMarginLoss中的损失函数定义。
我建议从上一层删除sigmoid
激活,并用relu
替换LeakyRelu
以提高模型的鲁棒性。