summaryrefslogtreecommitdiff
path: root/models/model.py
diff options
context:
space:
mode:
authorJordan Gong <jordan.gong@protonmail.com>2021-02-28 23:12:58 +0800
committerJordan Gong <jordan.gong@protonmail.com>2021-02-28 23:12:58 +0800
commit0d2b643d7e04eba872e8b1fc9b04478a026bb3b0 (patch)
treea53d8aa69e050397d3443a602a42ed700a8e8bb5 /models/model.py
parent10b1299eb46343e119bc413ba8774dcb1a68595e (diff)
parente04f54d0bfc8fc711e53561065d772dae1926b64 (diff)
Merge branch 'python3.8' into python3.7
# Conflicts: # utils/configuration.py
Diffstat (limited to 'models/model.py')
-rw-r--r--models/model.py74
1 files changed, 59 insertions, 15 deletions
diff --git a/models/model.py b/models/model.py
index f4654f3..aef5302 100644
--- a/models/model.py
+++ b/models/model.py
@@ -56,6 +56,8 @@ class Model:
self.in_size: Tuple[int, int] = (64, 48)
self.pr: Optional[int] = None
self.k: Optional[int] = None
+ self.num_pairs: Optional[int] = None
+ self.num_pos_pairs: Optional[int] = None
self._gallery_dataset_meta: Optional[Dict[str, List]] = None
self._probe_datasets_meta: Optional[Dict[str, Dict[str, List]]] = None
@@ -141,6 +143,7 @@ class Model:
# Prepare for model, optimizer and scheduler
model_hp: Dict = self.hp.get('model', {}).copy()
triplet_is_hard = model_hp.pop('triplet_is_hard', True)
+ triplet_is_mean = model_hp.pop('triplet_is_mean', True)
triplet_margins = model_hp.pop('triplet_margins', None)
optim_hp: Dict = self.hp.get('optimizer', {}).copy()
start_iter = optim_hp.pop('start_iter', 0)
@@ -160,10 +163,13 @@ class Model:
)
else: # Different margins
self.triplet_loss = JointBatchTripletLoss(
- self.rgb_pn.hpm_num_parts, triplet_is_hard, triplet_margins
+ self.rgb_pn.hpm_num_parts,
+ triplet_is_hard, triplet_is_mean, triplet_margins
)
else: # Soft margins
- self.triplet_loss = BatchTripletLoss(triplet_is_hard, None)
+ self.triplet_loss = BatchTripletLoss(
+ triplet_is_hard, triplet_is_mean, None
+ )
# Try to accelerate computation using CUDA or others
self.rgb_pn = self.rgb_pn.to(self.device)
@@ -213,7 +219,7 @@ class Model:
y = batch_c1['label'].to(self.device)
# Duplicate labels for each part
y = y.repeat(self.rgb_pn.num_total_parts, 1)
- trip_loss, dist, non_zero_counts = self.triplet_loss(embedding, y)
+ trip_loss, dist, num_non_zero = self.triplet_loss(embedding, y)
losses = torch.cat((
ae_losses,
torch.stack((
@@ -237,18 +243,36 @@ class Model:
'HPM': losses[3],
'PartNet': losses[4]
}, self.curr_iter)
- self.writer.add_scalars('Loss/non-zero counts', {
- 'HPM': non_zero_counts[:self.rgb_pn.hpm_num_parts].mean(),
- 'PartNet': non_zero_counts[self.rgb_pn.hpm_num_parts:].mean()
- }, self.curr_iter)
- self.writer.add_scalars('Embedding/distance', {
- 'HPM': dist[:self.rgb_pn.hpm_num_parts].mean(),
- 'PartNet': dist[self.rgb_pn.hpm_num_parts].mean()
- }, self.curr_iter)
- self.writer.add_scalars('Embedding/2-norm', {
- 'HPM': embedding[:self.rgb_pn.hpm_num_parts].norm(),
- 'PartNet': embedding[self.rgb_pn.hpm_num_parts].norm()
- }, self.curr_iter)
+ # None-zero losses in batch
+ if num_non_zero is not None:
+ self.writer.add_scalars('Loss/non-zero counts', {
+ 'HPM': num_non_zero[:self.rgb_pn.hpm_num_parts].mean(),
+ 'PartNet': num_non_zero[self.rgb_pn.hpm_num_parts:].mean()
+ }, self.curr_iter)
+ # Embedding distance
+ mean_hpm_dist = dist[:self.rgb_pn.hpm_num_parts].mean(0)
+ self._add_ranked_scalars(
+ 'Embedding/HPM distance', mean_hpm_dist,
+ self.num_pos_pairs, self.num_pairs, self.curr_iter
+ )
+ mean_pa_dist = dist[self.rgb_pn.hpm_num_parts:].mean(0)
+ self._add_ranked_scalars(
+ 'Embedding/ParNet distance', mean_pa_dist,
+ self.num_pos_pairs, self.num_pairs, self.curr_iter
+ )
+ # Embedding norm
+ mean_hpm_embedding = embedding[:self.rgb_pn.hpm_num_parts].mean(0)
+ mean_hpm_norm = mean_hpm_embedding.norm(dim=-1)
+ self._add_ranked_scalars(
+ 'Embedding/HPM norm', mean_hpm_norm,
+ self.k, self.pr * self.k, self.curr_iter
+ )
+ mean_pa_embedding = embedding[self.rgb_pn.hpm_num_parts:].mean(0)
+ mean_pa_norm = mean_pa_embedding.norm(dim=-1)
+ self._add_ranked_scalars(
+ 'Embedding/PartNet norm', mean_pa_norm,
+ self.k, self.pr * self.k, self.curr_iter
+ )
if self.curr_iter % 100 == 0:
lrs = self.scheduler.get_last_lr()
@@ -300,6 +324,24 @@ class Model:
self.writer.close()
break
+ def _add_ranked_scalars(
+ self,
+ main_tag: str,
+ metric: torch.Tensor,
+ num_pos: int,
+ num_all: int,
+ global_step: int
+ ):
+ rank = metric.argsort()
+ pos_ile = 100 - (num_pos - 1) * 100 // num_all
+ self.writer.add_scalars(main_tag, {
+ '0%-ile': metric[rank[-1]],
+ f'{100 - pos_ile}%-ile': metric[rank[-num_pos]],
+ '50%-ile': metric[rank[num_all // 2 - 1]],
+ f'{pos_ile}%-ile': metric[rank[num_pos - 1]],
+ '100%-ile': metric[rank[0]]
+ }, global_step)
+
def predict_all(
self,
iters: Tuple[int],
@@ -521,6 +563,8 @@ class Model:
) -> DataLoader:
config: Dict = dataloader_config.copy()
(self.pr, self.k) = config.pop('batch_size', (8, 16))
+ self.num_pairs = (self.pr*self.k-1) * (self.pr*self.k) // 2
+ self.num_pos_pairs = (self.k*(self.k-1)//2) * self.pr
if self.is_train:
triplet_sampler = TripletSampler(dataset, (self.pr, self.k))
return DataLoader(dataset,