"""Combina counts (sys7k + conversaciones + vision) y selecciona top-300 expertos POR CAPA, GARANTIZANDO los expertos de imagenes. Guarda la seleccion [L,300] para la extraccion. """ import numpy as np sys7k=np.load("/counts_sys7k.npy").astype(np.float64) conv=np.load("/counts_conv.npy").astype(np.float64) vis=np.load("/counts_vision.npy").astype(np.float64) L,E=conv.shape N=300 # normalizar por capa (frecuencia relativa) def norm(c): s=c.sum(1,keepdims=True); s[s==0]=1; return c/s nc, ns, nv = norm(conv), norm(sys7k), norm(vis) sel=np.zeros((L,N),dtype=np.int64) stats={"vis_garantizados":0,"vis_total":0} for l in range(L): # expertos de VISION: los que procesan tokens de imagen (activacion > 0) vis_experts=np.where(vis[l]>0)[0] stats["vis_total"]+=len(vis_experts) # score combinado: conversaciones (seƱal principal) + sys7k (contexto) score = 0.7*nc[l] + 0.3*ns[l] # ranking por score order=np.argsort(-score) chosen=set() # 1) GARANTIZAR expertos de vision (hasta un cap razonable para no copar) vis_sorted=vis_experts[np.argsort(-vis[l][vis_experts])] for e in vis_sorted: if len(chosen)=N: break chosen.add(int(e)) sel[l]=sorted(chosen)[:N] if len(chosen)>=N else list(chosen)+[order[i] for i in range(N-len(chosen))] np.save("/expert_selection.npy",sel) print(f"seleccion [{L},{N}] guardada -> /expert_selection.npy") print(f"expertos de vision: {stats['vis_total']/L:.0f} prom/capa, todos garantizados en el top-300") # overlap con un prune por solo-conversaciones (cuanto cambia al meter vision) print(f"capas: {L}, expertos finales/capa: {N}")