def eval_paths(self, paths, n=1, mode='val'): self.worker.reset_pipes() rewards = [] loader = self.dataloaders[mode] gen = paths if self.verbose: gen = tqdm(gen, desc='Child.eval_paths (%s)' % mode) correct, total = 0, 0 for path in gen: self.worker.set_path(path) if self.worker.is_valid: acc = 0 for _ in range(n): data, target = next(loader) output, loss = self.worker.eval_batch(data, target) if self.verbose: correct += (to_numpy(output).argmax(axis=1) == to_numpy(target)).sum() total += data.shape[0] gen.set_postfix({'acc' : correct / total, "loss" : loss}) acc += (to_numpy(output).argmax(axis=1) == to_numpy(target)).mean() self.records_seen[mode] += data.shape[0] else: acc = -0.1 raise Exception('not self.worker.is_valid') rewards.append(acc / n) return torch.FloatTensor(rewards).view(-1, 1)
def warmup(model, batch): batch = batch.cuda() model.exact = False approx_test = model(batch) approx_test = to_numpy(approx_test) model.exact = True exact_test = model(batch) exact_test = exact_test.topk(k=args.topk, dim=-1)[1] exact_test = to_numpy(exact_test) return (approx_test[:, 0] == exact_test[:, 0]).mean()
def fast_topk(preds, X_train, n_jobs=32): offsets = np.cumsum([p.shape[0] for p in preds]) offsets -= preds[0].shape[0] jobs = [ delayed(__filter_and_rank)(to_numpy(pred), to_numpy(X_train[offset:(offset + pred.shape[0])])) for pred, offset in zip(preds, offsets) ] top_k = Parallel(n_jobs=n_jobs, backend='threading')(jobs) top_k = np.vstack(top_k) return top_k
def log(self, epoch, rewards, actions, step_results=None, mode='train', extra=None): rewards = to_numpy(rewards).squeeze() actions = to_numpy(actions).squeeze() action_hashes = [str(a) for a in actions] # -- # Write log mean_rewards = pd.Series(rewards).groupby( action_hashes).mean().to_dict() max_rewards = pd.Series(rewards).groupby(action_hashes).max().to_dict() log_file = self.log_files[mode] record = OrderedDict([ ("mode", mode), ("step", epoch), ("mean_reward", mean_rewards), ("max_reward", max_rewards), ("mean_train_reward", mean_rewards), ("max_train_reward", max_rewards), ]) if extra is not None: for k, v in extra.items(): assert k not in record, "Logger: k in record.keys()" record[k] = v print(json.dumps(record), file=log_file) log_file.flush() # -- # Write actions action_file = self.action_files[mode] for reward, action, action_hash in zip(rewards, actions, action_hashes): line = [mode, epoch, round(float(reward), 5) ] + list(action) + [action_hash] line = '\t'.join(map(str, line)) print(line, file=action_file) action_file.flush()
def load_lm_weights(lm_weights_path, lm_itos_path, itos_path): lm_weights = torch.load(lm_weights_path, map_location=lambda storage, loc: storage) lm_itos = pickle.load(open(lm_itos_path, 'rb')) lm_stoi = {v: k for k, v in enumerate(lm_itos)} itos = pickle.load(open(itos_path, 'rb')) n_tok = len(itos) # Adjust vocabulary to match finetuning corpus lm_enc_weights = to_numpy(lm_weights['0.encoder.weight']) tmp = np.zeros((n_tok, lm_enc_weights.shape[1]), dtype=np.float32) tmp += lm_enc_weights.mean(axis=0) for i, w in enumerate(itos): if w in lm_stoi: tmp[i] = lm_enc_weights[lm_stoi[w]] lm_weights['0.encoder.weight'] = torch.Tensor(tmp.copy()) lm_weights['0.encoder_with_dropout.embed.weight'] = torch.Tensor( tmp.copy()) lm_weights['1.decoder.weight'] = torch.Tensor(tmp.copy()) return lm_weights, n_tok
def predict(self, X): dataloaders = { "test": DataLoader( TensorDataset( torch.LongTensor(X.values), torch.FloatTensor(np.zeros(X.shape[0]) - 1).view(-1, 1), ), shuffle=False, batch_size=self.batch_size, ) } # -- # Test all_preds = [] for model in self._models: model = model.to(self.device) preds, _ = model.predict(dataloaders, mode="test") all_preds.append(to_numpy(preds).squeeze()) model = model.to("cpu") return np.vstack(all_preds).mean(axis=0)
def precompute_features(self, dataloaders, mode, cache, force=False): if not os.path.exists(cache): os.makedirs(cache) cache_path = os.path.join(cache, mode + '.h5') if os.path.exists(cache_path) and (not force): print('precompute_conv: using cache %s' % cache_path, file=sys.stderr) else: if os.path.exists(cache_path) and force: os.remove(cache_path) _ = self.eval() cache_file = h5py.File(cache_path, 'w', libver='latest') data, targets = self.predict(dataloaders, mode=mode) data, targets = helpers.to_numpy(data), helpers.to_numpy(targets) for i,(d,t) in enumerate(zip(data, targets)): cache_file['%d/data' % i] = d cache_file['%d/target' % i] = t cache_file.flush() cache_file.close()
def reinforce_step(self, rewards, log_probs, entropies, entropy_penalty=0.0): """ REINFORCE """ if self._cuda: rewards = rewards.cuda() log_probs = log_probs.cuda() if entropies is not None: entropies = entropies.cuda() advantages = self.get_advantages(rewards) advantages = Variable(advantages, requires_grad=False) advantages = advantages.expand_as(log_probs) self.opt.zero_grad() loss = -(log_probs * advantages).sum() if entropies is not None: entropy_loss = entropy_penalty * entropies.sum() loss -= entropy_loss loss.backward() torch.nn.utils.clip_grad_norm(self.parameters(), 40) # !! Is this a reasonable value? self.opt.step() return { "advantages_mean": float(to_numpy(advantages.mean())), "loss": float(to_numpy(loss)), "entropy_loss": float(to_numpy(entropy_loss)) if entropies is not None else None, }
def hyperband_step(self, rewards, resample=False): reward_ranking = np.argsort(to_numpy(-rewards).squeeze()) update = [] self.population = self.population[reward_ranking] for member in self.population[int(self.population_size / 2):]: update.append({ "action": "popped", "member": list(map(int, member)), }) self.population = self.population[:int(self.population_size / 2)] if not resample: self.population_size = self.population.shape[0] else: # Sample perturbed versions of sucessful architectures new_population = [] for member in self.population: new_member = member.copy() while (new_member == member).all(): idx = np.random.choice(member.shape[0]) new_member[idx] = np.random.choice(self.template[idx]) new_population.append(new_member) for member in new_population: update.append({ "action": "pushed", "member": list(map(int, member)), }) self.population = np.column_stack( [self.population, new_population]).reshape( (self.population.shape[0] * 2, self.population.shape[1])) print('self.population -> \n %s' % str(self.population)) return update
def set_path(self, path, callback): path = to_numpy(path) for child in self.children(): if child.needs_path: child.set_path(path, callback) pipes = [] for i, path_block in enumerate(path.reshape(-1, 4)): trg_id = 'node_%d' % i # !! Indexing here is a little confusing src_0 = 'node_%d' % (path_block[0] - 1) if path_block[0] != 0 else "data_0" # !! Indexing here is a little confusing src_1 = 'node_%d' % (path_block[1] - 1) if path_block[1] != 0 else "data_0" # !! Indexing here is a little confusing pipes += [ (src_0, trg_id, self.op_lookup[path_block[2]], 0), (src_1, trg_id, self.op_lookup[path_block[3]], 1), ] for pipe in pipes: assert pipe in self.pipes.keys() self.set_pipes(pipes)
def prep_weight(logits, random): logits = Variable(logits.data) if random: logits.data = torch.randn(logits.shape) return to_numpy(F.softmax(logits, dim=-1))
# -- # Define model lm_weights = torch.load(args.lm_weights_path) n_tok = lm_weights['encoder.encoder.weight'].shape[0] n_class = lm_weights['decoder.layers.1.lin.weight'].shape[0] classifier = TextClassifier( bptt = bptt, max_seq = max_seq, n_class = n_class, n_tok = n_tok, emb_sz = emb_sz, n_hid = n_hid, n_layers = n_layers, pad_token = pad_token, head_layers = [emb_sz * 3, 50, n_class], head_drops = [0.0, 0.0], predict_only = True ).to('cuda') classifier.verbose = True classifier.load_state_dict(lm_weights, strict=True) _ = classifier.eval() preds, _ = classifier.predict(dataloaders, mode='inference') # return to correct order preds = to_numpy(preds)[np.argsort(o)] np.savetxt(args.outpath, preds, fmt='%.10f', delimiter='\t')
def run_one(batch_size, emb_dim, dropout, bias_offset, lr, lr_type): epochs = 6 lr = 10 ** lr dataloaders = { "train" : DataLoader( dataset=RaggedAutoencoderDataset(X=X_train, n_toks=n_toks), batch_size=int(batch_size), collate_fn=pad_collate_fn, num_workers=2, pin_memory=True, shuffle=True, drop_last=True, ), "valid" : DataLoader( dataset=RaggedAutoencoderDataset(X=X_train, n_toks=n_toks), batch_size=int(batch_size), collate_fn=pad_collate_fn, num_workers=2, pin_memory=True, shuffle=False, drop_last=False, ) } destiny_params = { "emb_dim" : int(emb_dim), "dropout" : dropout, "bias_offset" : bias_offset, } model = DestinyModel(n_toks=n_toks, **destiny_params).to(torch.device('cuda')) # print(model, file=sys.stderr) if lr_type == 0: lr_scheduler = HPSchedule.constant(hp_max=lr) elif lr_type == 1: lr_scheduler = HPSchedule.linear(hp_max=lr, epochs=epochs) elif lr_type == 2: lr_scheduler = HPSchedule.linear_cycle(hp_max=lr, epochs=epochs, low_hp=0.0, extra=0) model.init_optimizer( opt=torch.optim.Adam, params=model.parameters(), hp_scheduler={ "lr" : lr_scheduler, }, ) t = time() for epoch in range(epochs): train_hist = model.train_epoch(dataloaders, mode='train', compute_acc=False) preds, _ = model.predict(dataloaders, mode='valid') for i in range(preds.shape[0]): preds[i][X_train[i]] = -1 top_k = to_numpy(preds.topk(k=10, dim=-1)[1]) p_at_10 = np.mean([precision(X_test[i], top_k[i][:10]) for i in range(len(X_test))]) print(json.dumps({ "lr" : lr, "lr_type" : lr_type, "destiny_params" : destiny_params, "p_at_10" : p_at_10, })) return p_at_10
def accuracy(pred, act): return float((to_numpy(pred).argmax(axis=-1) == to_numpy(act)).mean())
plot-arch.py """ import sys from rsub import * from matplotlib import pyplot as plt import seaborn as sns import numpy as np import torch from torch.nn import functional as F torch.set_printoptions(linewidth=120) np.set_printoptions(linewidth=120) from basenet.helpers import to_numpy arch = torch.load(sys.argv[1], map_location=lambda *x: x[0]) arch = F.softmax(arch, dim=-1) arch = to_numpy(arch) print(arch) # Heatmap of weights _ = sns.heatmap(arch) show_plot() # Plot "none" prob _ = plt.plot(arch[:, 0]) _ = plt.axvline(1, c='grey') _ = plt.axvline(4, c='grey') _ = plt.axvline(8, c='grey') _ = plt.axvline(13, c='grey') show_plot()
for k3, v3 in v2.named_children(): for k4, v4 in v3.named_children(): if k4 == 'bn': print(list(v4.named_children())) # << rewards = child.eval_paths(paths, mode='test', n=10) res = {} for path in tqdm(paths): worker.verbose = False worker.set_path(path) preds, labs = worker.predict(dataloaders=dataloaders, mode='test') res[''.join(map(str, path))] = { "preds" : to_numpy(preds), "labs" : to_numpy(labs).squeeze(), } labs = res[list(res.keys())[0]]['labs'] preds = np.array([res[k]['preds'] for k in res.keys()]) ppreds = np.exp(preds) / np.exp(preds.sum(-1, keepdims=True)) _ = plt.hist((preds.argmax(axis=-1) == labs).mean(axis=-1), 100) _ = plt.axvline((preds.mean(axis=0).argmax(axis=-1) == labs).mean(), c='red') show_plot()
def set_path(self, mask): mask = to_numpy(mask) == 1 self.set_pipes(np.array(self.pipe_names)[mask])
logger.log( epoch=epoch, rewards=rewards, actions=actions[topk_idx], mode='test', extra={ "predict": True, "topk": topk, "test_n": test_n, "val_n": val_n, "action_order": [str(action) for action in to_numpy(actions[topk_idx])] }) # >> # Reset model if args.reset_model_interval > 0: if not (epoch + 1) % args.reset_model_interval: print('------ new model ------', file=sys.stderr) set_seeds(args.seed) worker = BoltWorker(num_nodes=args.num_nodes).cuda() lr_scheduler = getattr(LRSchedule, args.child_lr_schedule)( lr_init=args.child_lr_init, epochs=args.child_lr_epochs, period_length=args.child_sgdr_period_length, t_mult=args.child_sgdr_t_mult, )
new_member[idx] = np.random.choice(self.template[idx]) new_population.append(new_member) for member in new_population: update.append({ "action": "pushed", "member": list(map(int, member)), }) self.population = np.column_stack( [self.population, new_population]).reshape( (self.population.shape[0] * 2, self.population.shape[1])) print('self.population -> \n %s' % str(self.population)) return update def __call__(self, states): action_idx = np.random.choice(self.population_size, states.shape[0]) all_actions = torch.LongTensor(self.population[action_idx]) return all_actions, None, None if __name__ == '__main__': c = HyperbandController() print(to_numpy(c.population)) print(c.template) c.hyperband_step(np.arange(c.population_size), resample=True) c.population
entropy_penalty = 0.01 output_length = 16 output_channels = 2 controller_type = 'lstm' cuda = True env = SimpleEnv(output_length=output_length) if controller_type == 'mlp': controller = MLPController(input_dim=input_dim, output_length=output_length, output_channels=output_channels, cuda=cuda) elif controller_type == 'lstm': controller = LSTMController(input_dim=input_dim, output_length=output_length, output_channels=output_channels, cuda=cuda) else: raise Exception() all_rewards, all_actions = [], [] for _ in tqdm(range(500)): states = Variable(torch.zeros((batch_size, input_dim))).cuda() actions, log_probs, entropies = controller.sample(states) rewards = env.eval(actions) controller.step(rewards, log_probs, entropies=entropies, entropy_penalty=entropy_penalty) all_rewards.append(to_numpy(rewards)) all_actions.append(to_numpy(actions)) all_rewards = np.vstack(all_rewards) all_actions = np.vstack(all_actions) _ = plt.plot(all_rewards.squeeze()) show_plot()
states = Variable(torch.randn(controller_paths_per_step, state_dim)) actions, log_probs, entropies = controller(states) rewards = child.eval_paths(actions, n=1) if args.algorithm == 'reinforce': controller.reinforce_step(rewards, log_probs=log_probs, entropies=entropies) elif args.algorithm == 'ppo': controller.ppo_step(rewards, states=states, actions=actions) else: raise Exception('unknown algorithm %s' % args.algorithm, file=sys.stderr) history.append({ "mean_reward": to_numpy(rewards).mean(), "mean_actions": to_numpy(actions).mean(axis=0), "controller_step": len(history), "eval_records": child.eval_records, }) print(history[-1]) # # -- # # Eval best architecture # print('eval=%d' % iter, file=sys.stderr) # states = Variable(torch.randn(controller_candidates_per_eval, state_dim)) # actions, log_probs, entropies = controller(states) # rewards = child.eval_paths(actions) # print("rewards.min ->", rewards.min(), file=sys.stderr)