# softmax-within-event two-tower with outside option; trained on pre-J25 train events (all users) import numpy as np, torch, sys, polars as pl, argparse torch.set_num_threads(2); pass ap=argparse.ArgumentParser(); ap.add_argument('--d',type=int,default=12); ap.add_argument('--ep',type=int,default=6) ap.add_argument('--user',type=int,default=0); ap.add_argument('--tied',type=int,default=0); ap.add_argument('--nonull',type=int,default=0) ap.add_argument('--init',default='');ap.add_argument('--freeze',type=int,default=0);ap.add_argument('--lr',type=float,default=0.005) ap.add_argument('--nobias',type=int,default=0) ap.add_argument('--wd',type=float,default=0.0); ap.add_argument('--tag',default='m'); ap.add_argument('--nullu',type=int,default=1) ap.add_argument('--seed',type=int,default=0) a=ap.parse_args(); torch.manual_seed(a.seed); np.random.seed(a.seed) T=np.load('/tmp/dig/tr_ev.npz'); V=np.load('/tmp/dig/val_t.npz') NI=50000; NU=int(T['uid'].max())+1; d=a.d # map val users to train uid um=dict(zip(T['user'],T['uid'])); vu=np.array([um.get(u,-1) for u in V['evuser']]) class M(torch.nn.Module): def __init__(s): super().__init__() s.P=torch.nn.Embedding(NI+1,d,padding_idx=NI); s.Q=s.P if a.tied else torch.nn.Embedding(NI,d) s.b=torch.nn.Embedding(NI,1); s.c0=torch.nn.Parameter(torch.zeros(1)); s.wn=torch.nn.Linear(d,1) torch.nn.init.normal_(s.P.weight,0,0.1); if not a.tied: torch.nn.init.normal_(s.Q.weight,0,0.1) torch.nn.init.zeros_(s.b.weight) if a.user: s.E=torch.nn.Embedding(NU+1,d,padding_idx=NU); torch.nn.init.zeros_(s.E.weight); s.ub=torch.nn.Embedding(NU+1,1,padding_idx=NU); torch.nn.init.zeros_(s.ub.weight) with torch.no_grad(): s.P.weight[NI]=0 def uvec(s,H,uid): m=(H