Example #1
0
def processing():
    dir_sent_train = f"../data/data_preprocessed/{domain}/train/"
    dir_sent_test = f"../data/data_preprocessed/{domain}/test/"
    # dir_doc = "../data/data_doc/"
    dir_output = "../data/pkl/IMN/"
    if not os.path.exists(dir_output):
        os.mkdir(dir_output)
    print("reading data file...")
    dataset_sent_train = read_data1(dir_sent_train)
    dataset_sent_test = read_data1(dir_sent_test)
    # dataset_doc = read_data2(dir_doc)
    # datasets = [dataset_sent_train, dataset_sent_test, dataset_doc]
    datasets = [dataset_sent_train, dataset_sent_test]
    print("making vocab...")
    vocab = get_vocab(datasets)
    word2idx, idx2word = get_word_to_idx(vocab)
    # read the embedding files
    print("making embedding")
    emb_dir = "../data/embeddings/"
    general_emb_file = emb_dir + "glove.840B.300d.txt"
    domain_emb_file = emb_dir + f"{domain}.txt"
    general_embeddings = read_emb_idx(general_emb_file, word2idx, 300)
    domain_embeddings = read_emb_idx(domain_emb_file, word2idx, 100)
    # dataset_total = {"train_sent": dataset_sent_train, "train_doc": dataset_doc, "test_sent": dataset_sent_test}
    dataset_total = {"train_sent": dataset_sent_train, "test_sent": dataset_sent_test}
    # transform sentence to word index
    datasets = make_datasets(dataset_total, word2idx)
    # dir_output the transformed files
    print("making pickle file...")
    utils.pkl_dump(datasets, dir_output + "/features.pkl")
    utils.pkl_dump(word2idx, dir_output + "/word2idx.pkl")
    utils.pkl_dump(general_embeddings, dir_output + "/general_embeddings.pkl")
    utils.pkl_dump(domain_embeddings, dir_output + "/domain_embeddings.pkl")
    utils.pkl_dump(idx2word, dir_output + "/idx2word.pkl")
Example #2
0
def persist_experiment(t_experiment, i_episode, agent, scores):
    os.chdir(t_experiment)
    torch.save(agent.actor_local.state_dict(),
               "checkpoint_actor_{}.pth".format(i_episode))
    torch.save(agent.critic_local.state_dict(),
               "checkpoint_critic_{}.pth".format(i_episode))
    pkl_dump(scores, "scores_{}.pkl".format(i_episode))
    os.chdir("..")
Example #3
0
def get_results(test_ds, type):
    dl = DataLoader(test_ds, batch_size=len(test_ds), num_workers=5)
    retdict = train.eval_model(model, dl, args.OP_tgt, 3)
    model_dir = os.path.join('models', args.modelname)
    try:
        os.makedirs(os.path.join(model_dir, f'{type}_eval_results'))
    except:
        shutil.rmtree(os.path.join(model_dir, f'{type}_eval_results'))
        os.makedirs(os.path.join(model_dir, f'{type}_eval_results'))

    retdict['modelname'] = args.modelname
    # Print
    pprint.pprint(retdict)
    utils.pkl_dump(
        retdict, os.path.join('models', args.modelname, f'{type}_report.dict'))
Example #4
0
    def df_to_training_pairs(self, seq_dir, auto_id, grp):
        def decompose_slice(indices):
            input_df = grp.loc[indices[0]:
                               indices[1]]  # Slice out an input sequence
            first_month = input_df.MONTH.iloc[0]
            seq_name = f'{auto_id}_{first_month}'

            # input_df = pd.DataFrame(self.scaler.transform(input_df), columns=input_df.columns)
            x = input_df[self.col_dict['input']]
            x_obs = x.shift(1).fillna(x.iloc[0]).values
            x = x.values
            m = input_df[self.col_dict['missing']].values
            t = input_df[self.col_dict['delta']].values

            return seq_name, np.array([x, m, t, x_obs])

        input_start_ix = grp.index[0]
        input_final_ix = grp.index[-1] - self.min_rows_reqd + 1
        input_seq_df = [(pos, pos + self.history_len - 1)
                        for pos in range(input_start_ix, input_final_ix + 1)
                        ]  # pandas slicing is inclusive

        target_start_ix = grp.index[0] + self.history_len
        target_final_ix = grp.index[-1] - self.future_len + 1
        target_seq_df = [(pos, pos + self.future_len - 1)
                         for pos in range(target_start_ix, target_final_ix + 1)
                         ]

        tgt_types = ['tgt1', 'tgt2']
        label_dict = {}
        target_loader = TargetFunc(grp)

        # sliding window
        for slice_ix in range(len(input_seq_df)):
            name, x = decompose_slice(input_seq_df[slice_ix])
            utils.pkl_dump(x, os.path.join(seq_dir, name + '.npy'))

            label_dict[name] = {}
            for tgt in tgt_types:
                fn = eval(f"target_loader.{tgt}")
                label_dict[name][tgt] = fn(target_seq_df[slice_ix])

        return label_dict  # return for collation with other patients
Example #5
0
def train_model(train_iter, valid_iter, X_Mean, tgt_col, aux_cols, epochs, modelname, nb_classes, \
                lr=0.001, aux_alpha=0, tr_alpha=0, class_weights=None, l2=None, model=None, print_every=100):
    """
    Train a GRUD model

    :param train_iter: Train DataLoader
    :param valid_iter: Valid DataLoader
    :param X_Mean: Empirical Mean values for each dimension in the input (only important for variables with missing data)
    :param tgt_col: (str) Name of OP target
    :param aux_cols: list(str) of names of Aux targets. 
    :param epochs: Int of epochs to run
    :param modelname: Unique name for this model
    :param nb_classes: Number of OP target classes
    :param aux_alpha: Weight for Aux Loss
    :param tr_alpha: Weight for TR Loss
    :param class_weights (optional): Weights to scale OP Loss (for skewed datasets)
    """
    device = utils.try_gpu()

    # Set directory for model outputs
    try:
        os.makedirs(os.path.join('models',modelname))
        os.makedirs(os.path.join('models',modelname, 'gradflow'))
    except FileExistsError: pass

    # Initialize plotter class for gradflow
    plotter = TrainPlot(modelname)

    # Initialize model and learners
    class_weights = class_weights or [1]*nb_classes 
    l2 = l2 or 0

    for X,y in train_iter: break
    input_dim = X.size(-1)
    aux_dim = [ (y[aux_c].size(-1) if len(y[aux_c].size())>1 else 1) for aux_c in aux_cols] # if-else for targets with single dimennsion. their size(-1) will be batchsize

    model = StackedGRUDClassifier(input_dim, nb_classes, X_Mean, aux_dim).to(device=device, dtype=torch.float)    
    criterion = nn.CrossEntropyLoss(weight=torch.Tensor(class_weights).to(device=device))
    optimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=l2)
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 30, 0.85)

    # Store training metrics    
    train_meta = {}
    train_meta['train_losses'] = []
    train_meta['valid_losses'] = []
    train_meta['min_valid_loss'] = sys.maxsize
    train_meta['epoch_results'] = []


    for epoch in range(epochs):
        # TRAIN EPOCH
        t0 = time.time()
        metrics = train_epoch(model, train_iter, tgt_col, aux_cols, criterion, optimizer, aux_alpha, tr_alpha, scheduler, print_every=print_every, plotter=plotter)
        if epoch<200:scheduler.step()
        print(f"Epoch trained in {time.time()-t0}")

        # EVALUATE AGAINST VALIDATION SET
        t0 = time.time()
        eval_scores = eval_model(model, valid_iter, tgt_col, nb_classes)
        train_meta['epoch_results'].append(eval_scores)
        print(f"Evaluation done in {time.time()-t0}")

        t0 = time.time()
        # SAVE CHECKPOINT
        if eval_scores['loss'] < train_meta['min_valid_loss'] or epoch % 20 == 0:
            train_meta['min_valid_loss'] = min(eval_scores['loss'], train_meta['min_valid_loss'])
            checkpoint = {
                'epoch': epoch + 1,
                'state_dict': model.state_dict(),
                'optimizer': optimizer.state_dict()
            }
            save_ckp(checkpoint, True, os.path.join('models', modelname, 'checkpoint.pt'), os.path.join('models', modelname, 'best_model.pt'))
            print(f"Checkpoint created")

        # LOG PROGRESS
        print("\n\n================================================================================================================\n")
        print(f"Epoch: {epoch+1}    TrainLoss: {metrics[1]/metrics[0]}    ValidLoss: {eval_scores['loss']}    ValidAcc:{eval_scores['accuracy']}       WallTime: {datetime.datetime.now()}\n")
        print(eval_scores['conf_matrix'])
        print(pd.DataFrame.from_dict(eval_scores['clf_report']))
        print(eval_scores['brier'])
        print(eval_scores['roc'])
        print("\n\n================================================================================================================\n")
        
        # SAVE TRAINING PROGRESS DATA
        train_meta['train_losses'].append(metrics[1]/metrics[0])
        train_meta['valid_losses'].append(eval_scores['loss'])
        utils.pkl_dump(train_meta, os.path.join('models', modelname, 'trainmeta.dict'))
        print(f"post eval dumping took {time.time()-t0}")

        # PLOT LOSSES
        t0 = time.time()
        plt.figure(1)
        plt.plot(train_meta['train_losses'])
        plt.plot(train_meta['valid_losses'])
        plt.xlabel("Minibatch")
        plt.ylabel("Loss")
        plt.savefig(os.path.join('models', modelname, modelname+'_lossPlot.png'), bbox_inches='tight')
        print(f"plotting took {time.time()-t0}")

    return model
Example #6
0
    def train_test_split(self, dataset, x_mean, datadir, train_size):
        """
        IBDSequenceGenerator.write_to_disk:
         - Reads padded X, M, T matrices
         - Generate overlapping sequences and {tgt_type} training labels for each patient
         - Persist sequences as numpy arrays at data/{datadir}/{train, valid, test}/{ID}_{START_TS}.npy
         - Persist labels for all sequences in data/{datadir}/{train, valid, test}/label_dict.pkl
         - Persist empirical mean values at data/{datadir}/x_mean.pkl
        """
        print(SequenceGenerator.write_to_disk.__doc__)

        # Create out directories
        if not datadir: datadir = f'm{self.history_len}p{self.future_len}'
        out_fp = os.path.join('data', datadir)
        train_seq_dir = os.path.join(out_fp, 'train')
        valid_seq_dir = os.path.join(out_fp, 'valid')
        test_seq_dir = os.path.join(out_fp, 'test')
        if not os.path.exists(out_fp): os.makedirs(out_fp)
        if not os.path.exists(train_seq_dir): os.makedirs(train_seq_dir)
        if not os.path.exists(valid_seq_dir): os.makedirs(valid_seq_dir)
        if not os.path.exists(test_seq_dir): os.makedirs(test_seq_dir)

        groups = dataset.groupby('ID')

        TRAIN_LABELS = {}
        VALID_LABELS = {}
        TEST_LABELS = {}
        valid_size = (1 + train_size) / 2
        patients_dropped = 0

        for auto_id, grp in groups:
            grplen = grp.shape[0]

            if grplen < self.min_rows_reqd:
                patients_dropped += 1
                continue

            train = grp.iloc[:int(train_size * grplen)]
            valid = grp.iloc[int(train_size * grplen):int(valid_size * grplen)]
            test = grp.iloc[int(valid_size * grplen):]

            # if not enough observations for a validation sequence, use them either as test or train (don't waste any data)
            if valid.shape[0] < self.min_rows_reqd:
                if valid.shape[0] + test.shape[0] >= self.min_rows_reqd:
                    test = pd.concat([valid, test])
                    valid = None
                else:
                    train = pd.concat([train, valid, test])
                    valid = None
                    test = None

            TRAIN_LABELS.update(
                self.df_to_training_pairs(train_seq_dir, auto_id, train))
            if valid is not None:
                VALID_LABELS.update(
                    self.df_to_training_pairs(valid_seq_dir, auto_id, valid))
            if test is not None:
                TEST_LABELS.update(
                    self.df_to_training_pairs(test_seq_dir, auto_id, test))

        utils.pkl_dump(TRAIN_LABELS,
                       os.path.join(train_seq_dir, 'label_dict.pkl'))
        utils.pkl_dump(VALID_LABELS,
                       os.path.join(valid_seq_dir, 'label_dict.pkl'))
        utils.pkl_dump(TEST_LABELS, os.path.join(test_seq_dir,
                                                 'label_dict.pkl'))

        utils.pkl_dump(x_mean[2:], os.path.join(
            out_fp, 'x_mean.pkl'))  # remove auto id and month ts
        print(f"Patients dropped: {patients_dropped}")
Example #7
0
    all_data = pd.concat([df, m, t], axis=1)
    col_dict = {'input': df.columns, 'missing': m.columns, 'delta': t.columns}

    return all_data, col_dict, x_mean


if __name__ == "__main__":

    # Generate dummy data
    arr = pd.DataFrame(np.random.rand(5, 5, 5).reshape(25, 5),
                       columns=[f'col{i+1}' for i in range(5)])
    arr['ID'] = sum([[i] * 5 for i in range(3, 8)], [])
    arr['YEAR'] = 2020
    arr['MONTH'] = [1, 4, 5, 7, 8] * 5

    # Generate cleaned, resampled, imputed data with missing mask and delta + save to pickles folder
    df, col_dict, x_mean = clean_longitudinal_inputs(arr)

    # Init SequenceGenerator with look-back and look-forward durations
    seqgen = SequenceGenerator(3, 1, col_dict)

    # Generate time series inputs with their target labels
    # X (input arrays) pickled to disk at /tmp/input_id.npy
    # y returned as a dict {input_id : {tgt1: 0, tgt2: 1}}
    c = 0
    target_dict = {}
    for auto_id, group in df.groupby('ID'):
        target_dict.update(seqgen.df_to_training_pairs('tmp', auto_id, group))

    utils.pkl_dump(target_dict, 'tmp/label_dict.pkl')
Example #8
0
def ddpg_multiagent(env, agent1, agent2, cfg, db):
    # Get configuration
    n_episodes = cfg["Training"]["Number_episodes"]
    max_t = cfg["Training"]["Max_timesteps"]
    print_every = cfg["Training"]["Score_window"]
    starting_random = cfg["Training"]["Starting_random"]
    brain_index = cfg["Agent"]["Brain_index"]
    persist_mongodb = cfg["Training"]["Persist_mongodb"]
    success = cfg["Environment"]["Success"]

    #Initialize score lists
    scores_deque = deque(maxlen=print_every)
    scores = []
    # Create a directory to save the findings.
    # experiment_dir = setup_experiment(cfg)
    if persist_mongodb:
        experiment_id = setup_experiment(db, cfg)
    brain_name = env.brain_names[brain_index]
    # Train for n_episodes
    for i_episode in range(1, n_episodes + 1):
        env_info = env.reset(train_mode=True)[brain_name]
        n_agents = len(env_info.agents)
        states = env_info.vector_observations
        agent1.reset()
        agent2.reset()
        actions = np.zeros((n_agents, agent1.action_size))
        score = np.zeros(n_agents)
        for t in range(max_t):
            if i_episode < starting_random:
                actions = 2 * np.random.randn(n_agents,
                                              agent1.action_size) - 1.0
            else:
                actions[0, :] = agent1.act(states[0, :])
                actions[1, :] = agent2.act(states[1, :])
                # for i_agent in range(n_agents):
                #     actions[i_agent, :] = agent.act(states[i_agent, :])
            next_states, rewards, dones, _ = step_unity(
                env, actions, brain_name)
            for i_agent in range(n_agents):
                # Add experience to both of the agent's replay buffers
                agent1.step(states[i_agent, :], actions[i_agent, :],
                            rewards[i_agent], next_states[i_agent, :],
                            dones[i_agent])
                agent2.step(states[i_agent, :], actions[i_agent, :],
                            rewards[i_agent], next_states[i_agent, :],
                            dones[i_agent])
            states = next_states
            score += rewards
            if np.any(dones):
                break
        scores_deque.append(score)
        scores.append(score)
        mean_score = np.vstack(scores_deque).mean(axis=0).max()
        print("\rEpisode {}\tAverage Score: {:.4f}\tNoise Modulation: {:.3f}".
              format(i_episode, mean_score, agent1.noise_modulation),
              end="")
        # print("\rEpisode {}\tAverage Score: {}".format(i_episode, scores_deque), end="")

        visualize = False
        if i_episode % print_every == 0:
            # persist_experiment(experiment_dir, i_episode, agent, scores)
            if persist_mongodb:
                persist_experiment(db, experiment_id, i_episode, agent1,
                                   scores, print_every)
                persist_experiment(db, experiment_id, i_episode, agent2,
                                   scores, print_every)
            else:
                torch.save(agent1.actor_local.state_dict(),
                           f"checkpoint_actor_1_{i_episode}.pth")
                torch.save(agent1.critic_local.state_dict(),
                           f"checkpoint_critic_1_{i_episode}.pth")
                torch.save(agent2.actor_local.state_dict(),
                           f"checkpoint_actor_2_{i_episode}.pth")
                torch.save(agent2.critic_local.state_dict(),
                           f"checkpoint_critic_2_{i_episode}.pth")
            print("\rEpisode {}\tAverage Score: {:.4f}".format(
                i_episode, mean_score))

        if mean_score >= success:
            # This is going to be the first thing I'd be digging in the database for,
            # so here you go.
            fpath_actor_1 = "checkpoint_actor_1_winner_{}.pth".format(
                i_episode)
            fpath_critic_1 = "checkpoint_critic_1_winner_{}.pth".format(
                i_episode)
            torch.save(agent1.actor_local.state_dict(), fpath_actor_1)
            torch.save(agent1.critic_local.state_dict(), fpath_critic_1)
            fpath_actor_2 = "checkpoint_actor_2_winner_{}.pth".format(
                i_episode)
            fpath_critic_2 = "checkpoint_critic_2_winner_{}.pth".format(
                i_episode)
            torch.save(agent2.actor_local.state_dict(), fpath_actor_2)
            torch.save(agent2.critic_local.state_dict(), fpath_critic_2)
            pkl_dump(scores, "scores_winner.pkl")
            break

    return scores
Example #9
0
def ddpg_selfplay(env, agent, cfg, db):
    # Get configuration
    n_episodes = cfg["Training"]["Number_episodes"]
    max_t = cfg["Training"]["Max_timesteps"]
    print_every = cfg["Training"]["Score_window"]
    starting_random = cfg["Training"]["Starting_random"]
    brain_index = cfg["Agent"]["Brain_index"]
    dump_agent = cfg["Training"]["Dump_agent"]
    success = cfg["Environment"]["Success"]
    persist_mongodb = cfg["Training"]["Persist_mongodb"]
    pretrained = cfg["Training"]["Pretrained"]

    agent.update_every = max_t * starting_random * 2
    #Initialize score lists
    scores_deque = deque(maxlen=print_every)
    scores = []
    # Create a directory to save the findings.
    # experiment_dir = setup_experiment(cfg)
    experiment_id = setup_experiment(db, cfg)
    print("Experiment ID: {}".format(experiment_id))
    brain_name = env.brain_names[brain_index]
    # Train for n_episodes
    for i_episode in range(1, n_episodes + 1):
        env_info = env.reset(train_mode=True)[brain_name]
        n_agents = len(env_info.agents)
        states = env_info.vector_observations
        agent.reset()
        actions = np.zeros((n_agents, agent.action_size))
        score = np.zeros(n_agents)
        if i_episode == starting_random and pretrained:
            print("Loading pre-trained weights")
            agent = load_agent_weights(agent, cfg)
            print("Pre-trained weights loaded!")
            agent.update_every = cfg["Agent"]["Update_every"]
        for t in range(max_t):
            if i_episode < starting_random:
                actions = 2 * np.random.rand(n_agents, agent.action_size) - 1.0
            else:
                for i_agent in range(n_agents):
                    actions[i_agent, :] = agent.act(states[i_agent, :])
            next_states, rewards, dones, _ = step_unity(
                env, actions, brain_name)
            for i_agent in range(n_agents):
                # Add experience to both of the agent's replay buffers
                agent.step(states[i_agent, :], actions[i_agent, :],
                           rewards[i_agent], next_states[i_agent, :],
                           dones[i_agent])
            states = next_states
            score += rewards
            if np.any(dones):
                break
        scores_deque.append(score)
        scores.append(score)
        mean_score = np.vstack(scores_deque).max(axis=1).mean()
        print(
            "\rEpisode {}\tAverage Score: {:.4f}\t Score: {:.3f} {:.3f} noise {:.2f}"
            .format(i_episode, mean_score, score[0], score[1],
                    agent.noise_modulation),
            end="")
        # print("\rEpisode {}\tAverage Score: {}".format(i_episode, scores_deque), end="")

        visualize = False
        if i_episode % print_every == 0:
            print("\rEpisode {}\tAverage Score: {:.4f}".format(
                i_episode, mean_score))
            if persist_mongodb:
                persist_experiment(db, experiment_id, i_episode, agent, scores,
                                   print_every)
            else:
                torch.save(agent.actor_local.state_dict(),
                           f"checkpoint_actor_{i_episode}.pth")
                torch.save(agent.critic_local.state_dict(),
                           f"checkpoint_critic_{i_episode}.pth")
        if i_episode % dump_agent == 0:
            # To heck with it let's save some to disk even though I have utilities to load.
            # It's important.
            fpath_actor = "checkpoint_actor_{}.pth".format(i_episode)
            fpath_critic = "checkpoint_critic_{}.pth".format(i_episode)
            torch.save(agent.actor_local.state_dict(), fpath_actor)
            torch.save(agent.critic_local.state_dict(), fpath_critic)
        if mean_score >= success:
            # This is going to be the first thing I'd be digging in the database for,
            # so here you go.
            fpath_actor = "checkpoint_actor_winner_{}.pth".format(i_episode)
            fpath_critic = "checkpoint_critic_winner_{}.pth".format(i_episode)
            torch.save(agent.actor_local.state_dict(), fpath_actor)
            torch.save(agent.critic_local.state_dict(), fpath_critic)
            pkl_dump(scores, "scores_winner.pkl")
            break

    return scores