triplet loss with hard negative mining, inspired by http://www.bmva.org/bmvc/2016/papers/paper119/paper119.pdf section3.3 :param criterion: loss function :param f1: [lvl, B, C, H, W] :param f2: [lvl, B, C, H, W] :return: loss
(f1, f2, margin=1.)
| 369 | return loss |
| 370 | |
| 371 | def triplet_loss_hard_negative_mining(f1, f2, margin=1.): |
| 372 | ''' |
| 373 | triplet loss with hard negative mining, inspired by http://www.bmva.org/bmvc/2016/papers/paper119/paper119.pdf section3.3 |
| 374 | :param criterion: loss function |
| 375 | :param f1: [lvl, B, C, H, W] |
| 376 | :param f2: [lvl, B, C, H, W] |
| 377 | :return: |
| 378 | loss |
| 379 | ''' |
| 380 | criterion = nn.TripletMarginLoss(margin=margin, reduction='mean') |
| 381 | anchor = f1 |
| 382 | anchor_negative = torch.roll(f1, shifts=1, dims=1) |
| 383 | positive = f2 |
| 384 | negative = torch.roll(f2, shifts=1, dims=1) |
| 385 | |
| 386 | # select in-triplet hard negative, reference: section3.3 |
| 387 | mse = nn.MSELoss(reduction='mean') |
| 388 | with torch.no_grad(): |
| 389 | case1 = mse(anchor, negative) |
| 390 | case2 = mse(positive, anchor_negative) |
| 391 | |
| 392 | # perform anchor swap if necessary |
| 393 | if case1 < case2: |
| 394 | loss = criterion(anchor, positive, negative) |
| 395 | else: |
| 396 | loss = criterion(positive, anchor, anchor_negative) |
| 397 | return loss |
| 398 | |
| 399 | def triplet_loss_hard_negative_mining_plus(f1, f2, margin=1.): |
| 400 | ''' |