Ali Mohsin commited on
Commit
25ea1c9
Β·
1 Parent(s): ac45468

last changes final deployment, hopefully

Browse files
Files changed (1) hide show
  1. inference.py +50 -29
inference.py CHANGED
@@ -387,8 +387,8 @@ class InferenceService:
387
 
388
  # 2) Candidate generation with outfit templates
389
  rng = np.random.default_rng(int(context.get("seed", 42)))
390
- num_outfits = int(context.get("num_outfits", 3))
391
- min_size, max_size = 4, 6
392
  ids = list(range(len(proc_items)))
393
 
394
  # Outfit templates for cohesive styling
@@ -569,7 +569,7 @@ class InferenceService:
569
  print(f"πŸ” DEBUG: Will use flexible outfit generation with available items")
570
 
571
  candidates: List[List[int]] = []
572
- num_samples = max(num_outfits * 15, 30) # Increased for more variety
573
  print(f"πŸ” DEBUG: Generating {num_samples} candidate outfits...")
574
 
575
  def has_category_diversity(subset: List[int]) -> bool:
@@ -607,17 +607,18 @@ class InferenceService:
607
  outfit_length = rng.choice([2, 3, 4, 5], p=[0.1, 0.4, 0.4, 0.1]) # Prefer 3-4 items
608
 
609
  # Strategy 1: Core outfit (shirt + pants + shoes) + accessories
610
- if rng.random() < 0.6 and uppers and bottoms and shoes:
611
  # Core outfit: exactly 1 of each required slot
612
  subset.append(int(rng.choice(uppers)))
613
  subset.append(int(rng.choice(bottoms)))
614
  subset.append(int(rng.choice(shoes)))
615
 
616
- # Add accessories based on template limit and remaining slots
617
  remaining_slots = outfit_length - len(subset)
618
  if accs and remaining_slots > 0:
619
  max_accs = min(template["accessory_limit"], remaining_slots, len(accs))
620
- num_accs = rng.integers(0, max_accs + 1)
 
621
  available_accs = [i for i in accs if i not in subset]
622
  if available_accs and num_accs > 0:
623
  selected_accs = rng.choice(available_accs, size=min(num_accs, len(available_accs)), replace=False)
@@ -632,29 +633,12 @@ class InferenceService:
632
  selected_others = rng.choice(available_others, size=num_others, replace=False)
633
  subset.extend(selected_others.tolist())
634
 
635
- # Strategy 2: Flexible combination (no strict slot requirements)
636
- elif rng.random() < 0.3:
637
- # Randomly select items from all categories
638
- all_items = list(ids)
639
- rng.shuffle(all_items)
640
-
641
- # Select items ensuring diversity
642
- selected_categories = set()
643
- for item in all_items:
644
- if len(subset) >= outfit_length:
645
- break
646
- item_category = get_category_type(cat_str(item))
647
- if item_category not in selected_categories or len(subset) < 2:
648
- subset.append(item)
649
- selected_categories.add(item_category)
650
-
651
- # Strategy 3: Accessory-focused outfit (for small wardrobes)
652
- else:
653
  # Start with accessories if available
654
- if accs:
655
- num_accs = min(outfit_length, len(accs))
656
- selected_accs = rng.choice(accs, size=num_accs, replace=False)
657
- subset.extend(selected_accs.tolist())
658
 
659
  # Fill remaining with other categories
660
  remaining_slots = outfit_length - len(subset)
@@ -671,6 +655,22 @@ class InferenceService:
671
  selected_others = rng.choice(available_others, size=num_others, replace=False)
672
  subset.extend(selected_others.tolist())
673
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  # Remove duplicates and validate
675
  subset = list(set(subset))
676
  if len(subset) >= 2 and len(subset) <= max_size and has_category_diversity(subset):
@@ -768,6 +768,11 @@ class InferenceService:
768
  if style_score > 0.6: # Good style match
769
  bonus += 0.2
770
 
 
 
 
 
 
771
  return base_score + penalty + bonus
772
 
773
  # Score and filter valid outfits with penalty adjustment
@@ -786,6 +791,22 @@ class InferenceService:
786
  # Sort by penalty-adjusted score with randomization
787
  scored.sort(key=lambda x: x[1], reverse=True)
788
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  # Add randomization to prevent identical recommendations
790
  if len(scored) > num_outfits:
791
  # Take top 50% and randomly sample from them
@@ -795,7 +816,7 @@ class InferenceService:
795
  else:
796
  # If we have fewer candidates than requested, shuffle them
797
  rng.shuffle(scored)
798
- topk = scored[:num_outfits]
799
 
800
  results = []
801
  for subset, adjusted_score, base_score in topk:
 
387
 
388
  # 2) Candidate generation with outfit templates
389
  rng = np.random.default_rng(int(context.get("seed", 42)))
390
+ num_outfits = int(context.get("num_outfits", 5)) # Increased default from 3 to 5
391
+ min_size, max_size = 2, 6 # Allow smaller outfits (2 items minimum)
392
  ids = list(range(len(proc_items)))
393
 
394
  # Outfit templates for cohesive styling
 
569
  print(f"πŸ” DEBUG: Will use flexible outfit generation with available items")
570
 
571
  candidates: List[List[int]] = []
572
+ num_samples = max(num_outfits * 25, 50) # Further increased for more variety
573
  print(f"πŸ” DEBUG: Generating {num_samples} candidate outfits...")
574
 
575
  def has_category_diversity(subset: List[int]) -> bool:
 
607
  outfit_length = rng.choice([2, 3, 4, 5], p=[0.1, 0.4, 0.4, 0.1]) # Prefer 3-4 items
608
 
609
  # Strategy 1: Core outfit (shirt + pants + shoes) + accessories
610
+ if rng.random() < 0.5 and uppers and bottoms and shoes:
611
  # Core outfit: exactly 1 of each required slot
612
  subset.append(int(rng.choice(uppers)))
613
  subset.append(int(rng.choice(bottoms)))
614
  subset.append(int(rng.choice(shoes)))
615
 
616
+ # Prioritize accessories - higher chance of including them
617
  remaining_slots = outfit_length - len(subset)
618
  if accs and remaining_slots > 0:
619
  max_accs = min(template["accessory_limit"], remaining_slots, len(accs))
620
+ # Higher probability of including accessories
621
+ num_accs = rng.integers(1, max_accs + 1) if rng.random() < 0.8 else 0
622
  available_accs = [i for i in accs if i not in subset]
623
  if available_accs and num_accs > 0:
624
  selected_accs = rng.choice(available_accs, size=min(num_accs, len(available_accs)), replace=False)
 
633
  selected_others = rng.choice(available_others, size=num_others, replace=False)
634
  subset.extend(selected_others.tolist())
635
 
636
+ # Strategy 2: Accessory-focused outfit (prioritize accessories)
637
+ elif rng.random() < 0.3 and accs:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
638
  # Start with accessories if available
639
+ num_accs = min(outfit_length, len(accs))
640
+ selected_accs = rng.choice(accs, size=num_accs, replace=False)
641
+ subset.extend(selected_accs.tolist())
 
642
 
643
  # Fill remaining with other categories
644
  remaining_slots = outfit_length - len(subset)
 
655
  selected_others = rng.choice(available_others, size=num_others, replace=False)
656
  subset.extend(selected_others.tolist())
657
 
658
+ # Strategy 3: Flexible combination (no strict slot requirements)
659
+ else:
660
+ # Randomly select items from all categories
661
+ all_items = list(ids)
662
+ rng.shuffle(all_items)
663
+
664
+ # Select items ensuring diversity
665
+ selected_categories = set()
666
+ for item in all_items:
667
+ if len(subset) >= outfit_length:
668
+ break
669
+ item_category = get_category_type(cat_str(item))
670
+ if item_category not in selected_categories or len(subset) < 2:
671
+ subset.append(item)
672
+ selected_categories.add(item_category)
673
+
674
  # Remove duplicates and validate
675
  subset = list(set(subset))
676
  if len(subset) >= 2 and len(subset) <= max_size and has_category_diversity(subset):
 
768
  if style_score > 0.6: # Good style match
769
  bonus += 0.2
770
 
771
+ # Accessory inclusion bonus
772
+ categories = [get_category_type(cat_str(i)) for i in subset]
773
+ if "accessory" in categories:
774
+ bonus += 0.3 # Bonus for including accessories
775
+
776
  return base_score + penalty + bonus
777
 
778
  # Score and filter valid outfits with penalty adjustment
 
791
  # Sort by penalty-adjusted score with randomization
792
  scored.sort(key=lambda x: x[1], reverse=True)
793
 
794
+ # Remove duplicate outfits (same items, different order)
795
+ def normalize_outfit(subset):
796
+ """Normalize outfit by sorting item IDs for duplicate detection"""
797
+ return tuple(sorted(subset))
798
+
799
+ seen_outfits = set()
800
+ unique_scored = []
801
+ for subset, adjusted_score, base_score in scored:
802
+ normalized = normalize_outfit(subset)
803
+ if normalized not in seen_outfits:
804
+ seen_outfits.add(normalized)
805
+ unique_scored.append((subset, adjusted_score, base_score))
806
+
807
+ print(f"πŸ” DEBUG: Removed {len(scored) - len(unique_scored)} duplicate outfits")
808
+ scored = unique_scored
809
+
810
  # Add randomization to prevent identical recommendations
811
  if len(scored) > num_outfits:
812
  # Take top 50% and randomly sample from them
 
816
  else:
817
  # If we have fewer candidates than requested, shuffle them
818
  rng.shuffle(scored)
819
+ topk = scored[:num_outfits]
820
 
821
  results = []
822
  for subset, adjusted_score, base_score in topk: