from .loss import cross_entropy from .optim import clip_grad_norm from .schedule import lr_schedule def loss_on_batch(model, x, y, ignore_index=-1): logits = model(x) return cross_entropy(logits, y, ignore_index=ignore_index) def train_step(model, opt, x, y, max_norm=1.0, ignore_index=-1): opt.zero_grad() loss = loss_on_batch(model, x, y, ignore_index) loss.backward() clip_grad_norm(opt.params, max_norm) opt.step() return float(loss.data) def train(model, opt, batches, peak_lr, warmup_steps, total_steps, min_lr=0.0, max_norm=1.0, ignore_index=-1, start_step=0, log_every=0): history = [] for i, (x, y) in enumerate(batches): step = start_step + i opt.lr = lr_schedule(step, peak_lr, warmup_steps, total_steps, min_lr) loss = train_step(model, opt, x, y, max_norm, ignore_index) history.append(loss) if log_every and (step + 1) % log_every == 0: print(f"step {step + 1}/{total_steps} lr={opt.lr:.5f} loss={loss:.4f}") return history