Esempio n. 1
0
class Solver(object):
    def __init__(self, config, train_loader, val_loader):
        self.use_cuda = torch.cuda.is_available()
        self.device = torch.device('cuda' if self.use_cuda else 'cpu')
        self.train_loader = train_loader
        self.val_loader = val_loader
        self.episodes_per_epoch = config.episodes_per_epoch
        self.N_way_train = config.N_way_train
        self.N_shot_train = config.N_shot_train
        self.N_query_train = config.N_query_train
        self.M_aug_train = config.M_aug_train
        self.N_way_val = config.N_way_val
        self.N_shot_val = config.N_shot_val
        self.N_query_val = config.N_query_val
        self.M_aug_val = config.M_aug_val
        self.matching_fn = config.matching_fn
        self.nz = config.nz

        self.num_epochs = config.num_epochs
        self.resume_iter = config.resume_iter
        self.lr = config.lr
        self.num_steps_decay = config.num_steps_decay
        self.beta1 = config.beta1
        self.beta2 = config.beta2
        self.weight_decay = config.weight_decay
        self.exp_name = config.name
        os.makedirs(config.ckp_dir, exist_ok=True)
        self.ckp_dir = os.path.join(config.ckp_dir, self.exp_name)
        os.makedirs(self.ckp_dir, exist_ok=True)
        self.log_interval = config.log_interval
        self.ckp_interval = config.ckp_interval

        self.use_wandb = config.use_wandb

        self.build_model()

    def build_model(self):
        self.cnn = Convnet().to(self.device)
        self.g = Hallucinator(self.nz).to(self.device)
        self.mlp = MLP().to(self.device)
        self.optimizer = torch.optim.AdamW(list(self.cnn.parameters()) +
                                           list(self.g.parameters()) +
                                           list(self.mlp.parameters()),
                                           lr=self.lr,
                                           betas=[self.beta1, self.beta2],
                                           weight_decay=self.weight_decay)

        if self.matching_fn == 'parametric':
            self.parametric = nn.Sequential(nn.Linear(800, 400), nn.ReLU(),
                                            nn.Dropout(),
                                            nn.Linear(400, 1)).to(self.device)
            self.optimizer = torch.optim.AdamW(
                list(self.cnn.parameters()) + list(self.g.parameters()) +
                list(self.mlp.parameters()) +
                list(self.parametric.parameters()),
                lr=self.lr,
                betas=[self.beta1, self.beta2],
                weight_decay=self.weight_decay)

        self.scheduler = StepLR(self.optimizer,
                                step_size=self.num_steps_decay,
                                gamma=0.9)

    def save_checkpoint(self, step):
        state = {
            'cnn': self.cnn.state_dict(),
            'g': self.g.state_dict(),
            'mlp': self.mlp.state_dict(),
            'optimizer': self.optimizer.state_dict()
        }

        if self.matching_fn == 'parametric':
            state['parametric'] = self.parametric.state_dict()

        new_checkpoint_path = os.path.join(self.ckp_dir,
                                           '{}-dhm.pth'.format(step + 1))
        torch.save(state, new_checkpoint_path)
        print('model saved to %s' % new_checkpoint_path)

    def load_checkpoint(self, resume_iter):
        print('Loading the trained models from step {}...'.format(resume_iter))
        new_checkpoint_path = os.path.join(self.ckp_dir,
                                           '{}-dhm.pth'.format(resume_iter))
        state = torch.load(new_checkpoint_path)
        self.cnn.load_state_dict(state['cnn'])
        self.g.load_state_dict(state['g'])
        self.mlp.load_state_dict(state['mlp'])
        self.optimizer.load_state_dict(state['optimizer'])
        if self.matching_fn == 'parametric':
            self.parametric.load_state_dict(state['parametric'])
        print('model loaded from %s' % new_checkpoint_path)

    def train(self):
        criterion = nn.CrossEntropyLoss()

        best_mean = 0
        iteration = 0
        self.sample_idx_val = []
        self.noise_val = []
        for i in range(self.episodes_per_epoch):
            self.sample_idx_val.append(
                torch.tensor([
                    torch.randint(self.N_shot_val * i,
                                  self.N_shot_val * (i + 1),
                                  (self.M_aug_val, )).numpy()
                    for i in range(self.N_way_val)
                ]).reshape(-1))
            self.noise_val.append(
                torch.randn((self.N_way_val * self.M_aug_val, self.nz),
                            device=self.device))

        if self.resume_iter:
            print("resuming step %d ..." % self.resume_iter)
            iteration = self.resume_iter
            self.load_checkpoint(self.resume_iter)
            loss, mean, std = self.eval()
            if mean > best_mean:
                best_mean = mean

        episodic_acc = []

        for ep in range(self.num_epochs):
            self.cnn.train()
            self.g.train()
            self.mlp.train()

            for batch_idx, (data, target) in enumerate(self.train_loader):
                data = data.to(self.device)
                self.optimizer.zero_grad()

                support_input = data[:self.N_way_train *
                                     self.N_shot_train, :, :, :]
                query_input = data[self.N_way_train *
                                   self.N_shot_train:, :, :, :]

                label_encoder = {
                    target[i * self.N_shot_train]: i
                    for i in range(self.N_way_train)
                }
                query_label = torch.cuda.LongTensor([
                    label_encoder[class_name]
                    for class_name in target[self.N_way_train *
                                             self.N_shot_train:]
                ])

                support = self.cnn(support_input)
                queries = self.cnn(query_input)

                sample_idx = torch.tensor([
                    torch.randint(self.N_shot_train * i,
                                  self.N_shot_train * (i + 1),
                                  (self.M_aug_train, )).numpy()
                    for i in range(self.N_way_train)
                ]).reshape(-1)

                sample = support[sample_idx]
                noise = torch.randn(
                    (self.N_way_train * self.M_aug_train, self.nz),
                    device=self.device)

                support_g = self.g(sample,
                                   noise).reshape(self.N_way_train,
                                                  self.M_aug_train, -1)
                support = support.reshape(self.N_way_train, self.N_shot_train,
                                          -1)

                support_aug = torch.cat([support, support_g], dim=1)
                support_aug = support_aug.reshape(
                    self.N_way_train * (self.N_shot_train + self.M_aug_train),
                    -1)

                prototypes = self.mlp(support_aug)
                prototypes = prototypes.reshape(
                    self.N_way_train, self.N_shot_train + self.M_aug_train,
                    -1).mean(dim=1)
                queries = self.mlp(queries)

                if self.matching_fn == 'parametric':
                    distances = pairwise_distances(queries, prototypes,
                                                   self.matching_fn,
                                                   self.parametric)

                else:
                    distances = pairwise_distances(queries, prototypes,
                                                   self.matching_fn)

                loss = criterion(-distances, query_label)
                loss.backward()
                self.optimizer.step()

                y_pred = (-distances).softmax(dim=1).max(1, keepdim=True)[1]
                episodic_acc.append(
                    1. * y_pred.eq(query_label.view_as(y_pred)).sum().item() /
                    len(query_label))

                if (iteration + 1) % self.log_interval == 0:
                    episodic_acc = np.array(episodic_acc)
                    mean = episodic_acc.mean()
                    std = episodic_acc.std()

                    print(
                        'Epoch: {:3d} [{:d}/{:d}]\tIteration: {:5d}\tLoss: {:.6f}\tAccuracy: {:.2f} +- {:.2f} %'
                        .format(
                            ep, (batch_idx + 1), len(self.train_loader),
                            iteration + 1, loss.item(), mean * 100,
                            1.96 * std / (self.log_interval)**(1 / 2) * 100))

                    if self.use_wandb:
                        import wandb
                        wandb.log(
                            {
                                "loss":
                                loss.item(),
                                "acc_mean":
                                mean * 100,
                                "acc_ci":
                                1.96 * std /
                                (self.log_interval)**(1 / 2) * 100,
                                'lr':
                                self.optimizer.param_groups[0]['lr']
                            },
                            step=iteration + 1)

                    episodic_acc = []

                if (iteration + 1) % self.ckp_interval == 0:
                    loss, mean, std = self.eval()
                    if mean > best_mean:
                        best_mean = mean
                        self.save_checkpoint(iteration)
                        if self.use_wandb:
                            wandb.run.summary[
                                "best_accuracy"] = best_mean * 100

                    if self.use_wandb:
                        import wandb
                        wandb.log(
                            {
                                "val_loss": loss,
                                "val_acc_mean": mean * 100,
                                "val_acc_ci": 1.96 * std / (600)**(1 / 2) * 100
                            },
                            step=iteration + 1,
                            commit=False)

                iteration += 1

            self.scheduler.step()
        self.save_checkpoint(iteration)

    def eval(self):
        criterion = nn.CrossEntropyLoss()
        self.cnn.eval()
        self.g.eval()
        self.mlp.eval()
        episodic_acc = []
        loss = []

        with torch.no_grad():
            for b_idx, (data, target) in enumerate(self.val_loader):
                data = data.to(self.device)
                support_input = data[:self.N_way_val *
                                     self.N_shot_val, :, :, :]
                query_input = data[self.N_way_val * self.N_shot_val:, :, :, :]

                label_encoder = {
                    target[i * self.N_shot_val]: i
                    for i in range(self.N_way_val)
                }
                query_label = torch.cuda.LongTensor([
                    label_encoder[class_name]
                    for class_name in target[self.N_way_val * self.N_shot_val:]
                ])

                support = self.cnn(support_input)
                queries = self.cnn(query_input)

                sample_idx = self.sample_idx_val[b_idx]
                sample = support[sample_idx]

                noise = self.noise_val[b_idx]

                support_g = self.g(sample,
                                   noise).reshape(self.N_way_val,
                                                  self.M_aug_val, -1)
                support = support.reshape(self.N_way_val, self.N_shot_val, -1)

                support_aug = torch.cat([support, support_g], dim=1)
                support_aug = support_aug.reshape(
                    self.N_way_val * (self.N_shot_val + self.M_aug_val), -1)

                prototypes = self.mlp(support_aug)
                prototypes = prototypes.reshape(
                    self.N_way_val, self.N_shot_val + self.M_aug_val,
                    -1).mean(dim=1)
                queries = self.mlp(queries)

                if self.matching_fn == 'parametric':
                    distances = pairwise_distances(queries, prototypes,
                                                   self.matching_fn,
                                                   self.parametric)
                else:
                    distances = pairwise_distances(queries, prototypes,
                                                   self.matching_fn)

                loss.append(criterion(-distances, query_label).item())
                y_pred = (-distances).softmax(dim=1).max(1, keepdim=True)[1]
                episodic_acc.append(
                    1. * y_pred.eq(query_label.view_as(y_pred)).sum().item() /
                    len(query_label))

        loss = np.array(loss)
        episodic_acc = np.array(episodic_acc)
        loss = loss.mean()
        mean = episodic_acc.mean()
        std = episodic_acc.std()

        print('\nLoss: {:.6f}\tAccuracy: {:.2f} +- {:.2f} %\n'.format(
            loss, mean * 100, 1.96 * std / (600)**(1 / 2) * 100))

        return loss, mean, std
Esempio n. 2
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('--dataset', type=str, help='choose dataset')
    args = parser.parse_args()
    dataset = args.dataset
    logger.write("")
    logger.write(f"Current model: MLP")
    logger.write(f"Current dataset: {dataset}")

    setup_seeds(RANDOM_STATE)

    # Data loading
    train_file = osp.join(INPUT_PATH, dataset, "train.csv")
    test_file = osp.join(INPUT_PATH, dataset, "test.csv")
    train_df = pd.read_csv(train_file)
    test_df = pd.read_csv(test_file)

    columns = train_df.columns
    stat_columns_file = osp.join(INPUT_PATH, "stat_columns.txt")
    category_columns_file = osp.join(INPUT_PATH, "category_columns.txt")
    stat_columns = pickle_load(stat_columns_file)
    category_columns = pickle_load(category_columns_file)
    feature_columns = stat_columns + category_columns
    normalized_columns = [stat_columns[-2]]
    except_normalized_columns = [
        column for column in feature_columns
        if column not in normalized_columns
    ]

    standard_scaler = StandardScaler()
    standard_scaler.fit(train_df[normalized_columns].values)
    train_normalized = standard_scaler.transform(
        train_df[normalized_columns].values)
    test_normalized = standard_scaler.transform(
        test_df[normalized_columns].values)

    X_train = np.concatenate(
        (train_normalized, train_df[except_normalized_columns].values), axis=1)
    y_train = train_df["target"].values
    X_test = np.concatenate(
        (test_normalized, test_df[except_normalized_columns].values), axis=1)
    y_test = test_df["target"].values

    logger.write("x_train.shape: " + str(X_train.shape))
    logger.write("y_train.shape: " + str(y_train.shape))
    logger.write("x_test.shape: " + str(X_test.shape))

    n_features = len(feature_columns)
    n_category_features = len(category_columns)
    n_stat_features = len(stat_columns)

    n_classes = 1
    embeds_desc = []

    X_total = np.concatenate((X_train, X_test), axis=0)
    for i in range(n_stat_features, n_features):
        cur_column = X_total[:, i]
        num_embed = int(max(cur_column) + 1)
        embeds_desc.append([num_embed, 16])

    # Train process

    logger.write("Training...")
    model = MLP(n_stat_features, 64, embeds_desc, n_classes, 0.1)
    model_path = osp.join(INPUT_PATH, "mlp", dataset)
    if not osp.exists(model_path):
        os.makedirs(model_path)
    model_file = osp.join(model_path, "checkpoint.pt")
    patience = 6
    early_stopping = EarlyStopping(patience=patience,
                                   verbose=True,
                                   path=model_file)

    logger.write(model)

    train(X_train, y_train, model, n_stat_features, n_features, early_stopping)

    # Predict process
    logger.write("Predicting...")
    stat_matrix_test = X_test[:, :n_stat_features]
    embeds_input_test = []
    for i in range(n_stat_features, n_features):
        embeds_input_test.append(X_test[:, i])
    stat_matrix_test = torch.tensor(stat_matrix_test, dtype=torch.float)
    embeds_input_test = torch.tensor(embeds_input_test, dtype=torch.long)
    test_data = [stat_matrix_test, embeds_input_test]

    model.load_state_dict(torch.load(model_file))

    y_test_prob = predict(test_data, model)

    # calc metrics

    logger.write(f"test max prob:{y_test_prob.max()}")
    logger.write(f"test min prob:{y_test_prob.min()}")

    logger.write("Metrics calculation...")
    recall_precision_score(y_test_prob, y_test)

    print("")
Esempio n. 3
0
import torch
import torch.nn as nn
import numpy as np
import os
import pickle
from data_loader import load_test_dataset
from model import MLP
from torch.autograd import Variable
import math
import time

size = 5.0

# Load trained model for path generation
mlp = MLP(32, 2)  # simple @D
mlp.load_state_dict(torch.load('models/mlp_100_4000_PReLU_ae_dd150.pkl'))

if torch.cuda.is_available():
    mlp.cuda()

#load test dataset
obc, obstacles, paths, path_lengths = load_test_dataset()


def IsInCollision(x, idx):
    s = np.zeros(2, dtype=np.float32)
    s[0] = x[0]
    s[1] = x[1]
    for i in range(0, 7):
        cf = True
        for j in range(0, 2):
Esempio n. 4
0
class DQN:
    def __init__(self, state_dim, action_dim, cfg):
        """

        :param state_dim: About Task
        :param action_dim: About Task
        :param cfg: Config, About DQN setting
        """
        self.device = cfg.device
        self.action_dim = action_dim
        self.gamma = cfg.gamma
        self.frame_idx = 0  # Decay count for epsilon
        self.epsilon = lambda frame_idx: \
            cfg.epsilon_end + \
            (cfg.epsilon_start - cfg.epsilon_end) * \
            math.exp(-1. * frame_idx / cfg.epsilon_decay)
        self.batch_size = cfg.batch_size
        self.q_value_net = MLP(state_dim,
                               action_dim,
                               hidden_dim=cfg.hidden_dim).to(self.device)
        self.target_net = MLP(state_dim, action_dim,
                              hidden_dim=cfg.hidden_dim).to(self.device)
        self.optimizer = optim.Adam(self.q_value_net.parameters(), lr=cfg.lr)
        self.loss = 0
        self.replay_buffer = ReplayBuffer(cfg.capacity)

    def choose_action(self, state):
        # Select actions using e—greedy principle
        self.frame_idx += 1
        if random.random() > self.epsilon(self.frame_idx):
            # Will not track the gradient
            with torch.no_grad():
                # Although Q(s,a) is written in the pseudocode of the original paper,
                # it is actually the value of Q(s) output |A| dimension
                state = torch.tensor([state],
                                     device=self.device,
                                     dtype=torch.float)
                q_value = self.q_value_net(state)

                # output = torch.max(input, dim)
                # dim is the dimension 0/1 of the max function index,
                # 0 is the maximum value of each column,
                # 1 is the maximum value of each row
                # The function will return two tensors,
                # the first tensor is the maximum value of each row;
                # the second tensor is the index of the maximum value of each row.

                # .item(): only one element tensors can be converted to Python scalars
                action = q_value.max(1)[1].item()
        else:
            action = random.randrange(self.action_dim)
        return action

    def update(self):
        if len(self.replay_buffer) < self.batch_size:
            return
        # Randomly sample transitions from the replay buffer
        state_batch, action_batch, reward_batch, next_state_batch, done_batch = \
            self.replay_buffer.sample(self.batch_size)
        state_batch = to_tensor_float(state_batch, device=self.device)
        # tensor([1, 2, 3, 4]).unsqueeze(1)  -> tensor([[1],[2],[3],[4]])
        action_batch = torch.tensor(action_batch,
                                    device=self.device).unsqueeze(1)
        reward_batch = to_tensor_float(reward_batch, device=self.device)
        next_state_batch = to_tensor_float(next_state_batch,
                                           device=self.device)
        done_batch = to_tensor_float(done_batch, device=self.device)

        # Calculate Q(s,a) at time t
        # q_t=Q(s_t,a_t)

        # Use index to index the value of a specific position in a dimension
        # a=torch.Tensor([[1,2],[3,4]]),
        # a.gather(1,torch.LongTensor([[0],[1]]))=torch.Tensor([[1],[4]])

        # index action_batch is obtained from the replay buffer
        q_value = self.q_value_net(state_batch).gather(
            dim=1, index=action_batch)  # shape: [32,1]
        # Calculate Q(s,a) at time t+1
        # q_{t+1}=max_a Q(s_t+1,a)

        # .detach():
        # Return a new Variable, which is separated from the current calculation graph,
        # but still points to the storage location of the original variable.
        # The difference is that requires grad is false.
        # The obtained Variable never needs to calculate its gradient and does not have grad.
        #
        # Even if it re-sets its requirements grad to true later,
        # it will not have a gradient grad
        next_q_value = self.target_net(next_state_batch).max(1)[0].detach()
        # For the termination state, the corresponding expected_q_value is equal to reward
        expected_q_value = reward_batch + self.gamma * next_q_value * (
            1 - done_batch)  # shape: 32
        # loss_fn = torch.nn.MSELoss(reduce=True, size_average=True)
        # reduce = False,return loss in vector form
        # reduce = True, return loss in scalar form
        # size_average = True,return loss.mean()
        # size_average = False,return loss.sum()
        self.loss = nn.MSELoss()(q_value, expected_q_value.unsqueeze(1))
        # Sets the gradients of all optimized :class:`torch.Tensor` s to zero.
        self.optimizer.zero_grad()
        self.loss.backward()
        # Performs a single optimization step (parameter update).
        self.optimizer.step()

    def save(self, path):
        # Returns a dictionary containing a whole state of the module.
        # Both parameters and persistent buffers (e.g. running averages) are included.
        # Keys are corresponding parameter and buffer names.
        torch.save(self.target_net.state_dict(), path + "dqn_checkpoint.pth")

    def load(self, path):
        self.target_net.load_state_dict(torch.load(path +
                                                   "dqn_checkpoint.pth"))
Esempio n. 5
0
class Test():
    def __init__(self, config_path):
        config = configparser.ConfigParser()
        config.read(config_path)

        self.save_dir = Path(config.get("general", "save_dir"))
        if not self.save_dir.exists():
            self.save_dir.mkdir(parents=True)
        self.clf_th = config.getfloat("general", "clf_th")

        self.mlp_model_path = config.get("model", "mlp")
        assert Path(self.mlp_model_path).exists()

        self.device = "cuda" if torch.cuda.is_available() else "cpu"
        bert_config_path = config.get("bert", "config_path")
        assert Path(bert_config_path).exists()
        self.bert_config = LongformerConfig.from_json_file(bert_config_path)
        self.max_seq_length = self.bert_config.max_position_embeddings - 2
        self.bert_tokenizer = LongformerTokenizer.from_pretrained(
            'allenai/longformer-base-4096')
        # bert_tokenizer_path = config.get("bert", "tokenizer_path")
        # assert Path(bert_config_path).exists()
        # self.bert_tokenizer = LongformerTokenizer.from_pretrained(bert_tokenizer_path)
        bert_model_path = config.get("bert", "model_path")
        assert Path(bert_model_path).exists()
        self.bert_model = LongformerModel.from_pretrained(
            bert_model_path, config=self.bert_config)
        self.bert_model.to(self.device)
        self.bert_model.eval()

        gold_dir = Path(config.get("data", "gold_dir"))
        assert Path(gold_dir).exists()
        self.gold_dataset = ConllDataset(gold_dir)
        target_dir = Path(config.get("data", "target_dir"))
        assert Path(target_dir).exists()
        self.target_dataset = ConllDataset(target_dir)

    def transforms(self, example, label_list, is_gold):
        feature = convert_single_example(example, label_list,
                                         self.max_seq_length,
                                         self.bert_tokenizer)
        label_ids = feature.label_ids
        label_map = feature.label_map
        if is_gold:
            gold_labels = [-1] * self.max_seq_length
            # Get "Element" or "Main" token indices
            for i, lid in enumerate(label_ids):
                if lid == label_map['B-Element']:
                    gold_labels[i] = 0
                elif lid == label_map['B-Main']:
                    gold_labels[i] = 1
                elif lid in (label_map['I-Element'], label_map['I-Main']):
                    gold_labels[i] = 2
                elif lid == label_map['X']:
                    gold_labels[i] = 3
            gold_labels = gold_labels
        else:
            gold_labels = [-1] * self.max_seq_length
            # Get "Element" or "Main" token indices
            for i, lid in enumerate(label_ids):
                if lid == label_map['B-Element']:
                    gold_labels[i] = 0
                elif lid == label_map['I-Element']:
                    gold_labels[i] = 2
                elif lid == label_map['X']:
                    gold_labels[i] = 3
            gold_labels = gold_labels
        # flush data to bert model
        input_ids = torch.tensor(feature.input_ids).unsqueeze(0).to(
            self.device)
        with torch.no_grad():
            bert_output = self.bert_model(input_ids)
        # lstm (ignore padding parts)
        bert_fv = bert_output[0]
        input_ids = torch.tensor(feature.input_ids)
        label_ids = torch.tensor(feature.label_ids)
        return bert_fv, input_ids, label_ids, label_map, gold_labels

    def load_model(self):
        # MLP
        self.mlp = MLP(self.bert_config.hidden_size)
        self.mlp.load_state_dict(torch.load(self.mlp_model_path))
        self.mlp.to(self.device)
        self.mlp.eval()

    def eval(self):
        self.load_model()

        correct_save_dir = self.save_dir / "correct"
        if not correct_save_dir.exists():
            correct_save_dir.mkdir(parents=True)
        incorrect_save_dir = self.save_dir / "incorrect"
        if not incorrect_save_dir.exists():
            incorrect_save_dir.mkdir(parents=True)

        tp, fp, tn, fn = 0, 0, 0, 0
        with torch.no_grad():
            for gold_data, target_data in tqdm(
                    zip(self.gold_dataset, self.target_dataset)):
                # flush to Bert
                gold_fname, gold_example = gold_data
                target_fname, target_example = target_data
                if not gold_fname == target_fname:
                    import pdb
                    pdb.set_trace()
                assert gold_fname == target_fname

                _, _, _, _, gold_labels = self.transforms(
                    gold_example, self.gold_dataset.label_list, is_gold=True)
                fvs, input_ids, label_ids, label_map, pred_labels = self.transforms(
                    target_example,
                    self.target_dataset.label_list,
                    is_gold=False)

                # extract Element/Main tokens
                is_correct = True
                _, ent_gold_labels, golds_mask = Trainer.extract_tokens(
                    fvs.squeeze(0), gold_labels)
                golds = {}
                if len(ent_gold_labels) >= 1:
                    i = 0
                    while True:
                        try:
                            ent_start = golds_mask.index(i)
                        except ValueError:
                            break
                        for n, j in enumerate(golds_mask[ent_start:]):
                            if j != i:
                                ent_end = (ent_start + n - 1)
                                break
                        golds[(ent_start, ent_end)] = ent_gold_labels[i]
                        i += 1

                ents, ent_pred_labels, preds_mask = Trainer.extract_tokens(
                    fvs.squeeze(0), pred_labels)

                preds = {}
                if len(ent_pred_labels) >= 1:
                    i = 0
                    while True:
                        try:
                            ent_start = preds_mask.index(i)
                        except ValueError:
                            break
                        for n, j in enumerate(preds_mask[ent_start:]):
                            if j != i:
                                ent_end = (ent_start + n - 1)
                                break
                        preds[(ent_start, ent_end)] = ent_pred_labels[i]
                        i += 1
                for gold_span, gold_label in golds.items():
                    if gold_span not in preds.keys():
                        if gold_label == 1:
                            fn += 1
                            is_correct = False

                ents_pred = [0] * len(ents)
                for i, pred in enumerate(preds):
                    # convert to torch.tensor
                    inputs = torch.empty(
                        [len(ents[i]),
                         self.bert_config.hidden_size]).to(self.device)
                    for j, token in enumerate(ents[i]):
                        inputs[j, :] = token

                    inputs = torch.mean(inputs, dim=0, keepdim=True)
                    outputs = self.mlp(inputs)

                    if pred in golds.keys():
                        target = golds[pred]
                        if target == 1:
                            if outputs < self.clf_th:
                                fn += 1
                                is_correct = False
                            else:
                                tp += 1
                        else:
                            if outputs < self.clf_th:
                                tn += 1
                            else:
                                fp += 1
                                is_correct = False
                    else:
                        if outputs < self.clf_th:
                            pass
                        else:
                            fp += 1
                            is_correct = False

                    outputs_ = outputs.to('cpu').detach().numpy().copy()
                    if np.all(outputs_ > self.clf_th):
                        ents_pred[i] = 1

                if is_correct:
                    save_dir = correct_save_dir
                else:
                    save_dir = incorrect_save_dir
                save_path = save_dir / (target_fname + ".conll")
                lines = []
                elem_cnt = -1
                for i in range(len(target_example.text)):
                    text = target_example.text[i]
                    label = target_example.label[i]
                    start = target_example.start[i]
                    end = target_example.end[i]
                    if label == "B-Element":
                        elem_cnt += 1
                        if ents_pred[elem_cnt] == 1:
                            lines.append(f"B-Main\t{start}\t{end}\t{text}")
                        elif ents_pred[elem_cnt] == 0:
                            lines.append(f"{label}\t{start}\t{end}\t{text}")
                    elif label == "I-Element":
                        if ents_pred[elem_cnt] == 1:
                            lines.append(f"I-Main\t{start}\t{end}\t{text}")
                        elif ents_pred[elem_cnt] == 0:
                            lines.append(f"{label}\t{start}\t{end}\t{text}")
                    else:
                        lines.append(f"{label}\t{start}\t{end}\t{text}")

                with save_path.open("w") as f:
                    f.write("\n".join(lines))

        return Score(tp, fp, tn, fn).calc_score()
Esempio n. 6
0
File: main.py Progetto: hsack6/AGATE
def main(opt):
    train_dataset = BADataset(opt.dataroot, opt.L, True, False, False)
    train_dataloader = BADataloader(train_dataset, batch_size=opt.batchSize, \
                                      shuffle=True, num_workers=opt.workers, drop_last=True)

    valid_dataset = BADataset(opt.dataroot, opt.L, False, True, False)
    valid_dataloader = BADataloader(valid_dataset, batch_size=opt.batchSize, \
                                     shuffle=True, num_workers=opt.workers, drop_last=True)

    test_dataset = BADataset(opt.dataroot, opt.L, False, False, True)
    test_dataloader = BADataloader(test_dataset, batch_size=opt.batchSize, \
                                     shuffle=True, num_workers=opt.workers, drop_last=True)

    all_dataset = BADataset(opt.dataroot, opt.L, False, False, False)
    all_dataloader = BADataloader(all_dataset, batch_size=opt.batchSize, \
                                     shuffle=False, num_workers=opt.workers, drop_last=False)

    opt.n_edge_types = train_dataset.n_edge_types
    opt.n_node = train_dataset.n_node

    net = MLP(opt)
    net.double()
    print(net)

    criterion = nn.BCELoss()

    if opt.cuda:
        net.cuda()
        criterion.cuda()

    optimizer = optim.Adam(net.parameters(), lr=opt.lr)
    early_stopping = EarlyStopping(patience=opt.patience, verbose=True)

    os.makedirs(OutputDir, exist_ok=True)
    train_loss_ls = []
    valid_loss_ls = []
    test_loss_ls = []

    for epoch in range(0, opt.niter):
        train_loss = train(epoch, train_dataloader, net, criterion, optimizer,
                           opt)
        valid_loss = valid(valid_dataloader, net, criterion, opt)
        test_loss = test(test_dataloader, net, criterion, opt)

        train_loss_ls.append(train_loss)
        valid_loss_ls.append(valid_loss)
        test_loss_ls.append(test_loss)

        early_stopping(valid_loss, net, OutputDir)
        if early_stopping.early_stop:
            print("Early stopping")
            break

    df = pd.DataFrame({
        'epoch': [i for i in range(1,
                                   len(train_loss_ls) + 1)],
        'train_loss': train_loss_ls,
        'valid_loss': valid_loss_ls,
        'test_loss': test_loss_ls
    })
    df.to_csv(OutputDir + '/loss.csv', index=False)

    net.load_state_dict(torch.load(OutputDir + '/checkpoint.pt'))
    inference(all_dataloader, net, criterion, opt, OutputDir)
Esempio n. 7
0
class DQN:
    def __init__(self,
                 n_states,
                 n_actions,
                 gamma=0.99,
                 epsilon_start=0.9,
                 epsilon_end=0.05,
                 epsilon_decay=200,
                 memory_capacity=10000,
                 policy_lr=0.01,
                 batch_size=128,
                 device="cpu"):
        self.actions_count = 0
        self.n_actions = n_actions  # 总的动作个数
        self.device = device  # 设备,cpu或gpu等
        self.gamma = gamma
        # e-greedy策略相关参数
        self.epsilon = 0
        self.epsilon_start = epsilon_start
        self.epsilon_end = epsilon_end
        self.epsilon_decay = epsilon_decay
        self.batch_size = batch_size
        self.policy_net = MLP(n_states, n_actions).to(self.device)
        self.target_net = MLP(n_states, n_actions).to(self.device)
        # target_net的初始模型参数完全复制policy_net
        self.target_net.load_state_dict(self.policy_net.state_dict())
        self.target_net.eval()  # 不启用 BatchNormalization 和 Dropout
        # 可查parameters()与state_dict()的区别,前者require_grad=True
        self.optimizer = optim.Adam(self.policy_net.parameters(), lr=policy_lr)
        self.loss = 0
        self.memory = ReplayBuffer(memory_capacity)

    def choose_action(self, state, train=True):
        '''选择动作
        '''
        if train:
            self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \
                math.exp(-1. * self.actions_count / self.epsilon_decay)
            self.actions_count += 1
            if random.random() > self.epsilon:
                with torch.no_grad():
                    # 先转为张量便于丢给神经网络,state元素数据原本为float64
                    # 注意state=torch.tensor(state).unsqueeze(0)跟state=torch.tensor([state])等价
                    state = torch.tensor([state],
                                         device=self.device,
                                         dtype=torch.float32)
                    # 如tensor([[-0.0798, -0.0079]], grad_fn=<AddmmBackward>)
                    q_value = self.policy_net(state)
                    # tensor.max(1)返回每行的最大值以及对应的下标,
                    # 如torch.return_types.max(values=tensor([10.3587]),indices=tensor([0]))
                    # 所以tensor.max(1)[1]返回最大值对应的下标,即action
                    action = q_value.max(1)[1].item()
            else:
                action = random.randrange(self.n_actions)
            return action
        else:
            with torch.no_grad():
                # 先转为张量便于丢给神经网络,state元素数据原本为float64
                # 注意state=torch.tensor(state).unsqueeze(0)跟state=torch.tensor([state])等价
                state = torch.tensor([state],
                                     device='cpu',
                                     dtype=torch.float32)
                # 如tensor([[-0.0798, -0.0079]], grad_fn=<AddmmBackward>)
                q_value = self.target_net(state)
                # tensor.max(1)返回每行的最大值以及对应的下标,
                # 如torch.return_types.max(values=tensor([10.3587]),indices=tensor([0]))
                # 所以tensor.max(1)[1]返回最大值对应的下标,即action
                action = q_value.max(1)[1].item()
            return action

    def update(self):

        if len(self.memory) < self.batch_size:
            return
        # 从memory中随机采样transition
        state_batch, action_batch, reward_batch, next_state_batch, done_batch = self.memory.sample(
            self.batch_size)
        # 转为张量
        # 例如tensor([[-4.5543e-02, -2.3910e-01,  1.8344e-02,  2.3158e-01],...,[-1.8615e-02, -2.3921e-01, -1.1791e-02,  2.3400e-01]])
        state_batch = torch.tensor(state_batch,
                                   device=self.device,
                                   dtype=torch.float)
        action_batch = torch.tensor(action_batch,
                                    device=self.device).unsqueeze(
                                        1)  # 例如tensor([[1],...,[0]])
        reward_batch = torch.tensor(
            reward_batch, device=self.device,
            dtype=torch.float)  # tensor([1., 1.,...,1])
        next_state_batch = torch.tensor(next_state_batch,
                                        device=self.device,
                                        dtype=torch.float)
        done_batch = torch.tensor(np.float32(done_batch),
                                  device=self.device).unsqueeze(
                                      1)  # 将bool转为float然后转为张量

        # 计算当前(s_t,a)对应的Q(s_t, a)
        q_values = self.policy_net(state_batch)
        next_q_values = self.policy_net(next_state_batch)
        # 代入当前选择的action,得到Q(s_t|a=a_t)
        q_value = q_values.gather(dim=1, index=action_batch)
        '''以下是Nature DQN的q_target计算方式
        # 计算所有next states的Q'(s_{t+1})的最大值,Q'为目标网络的q函数
        next_q_state_value = self.target_net(
            next_state_batch).max(1)[0].detach()  # 比如tensor([ 0.0060, -0.0171,...,])
        # 计算 q_target
        # 对于终止状态,此时done_batch[0]=1, 对应的expected_q_value等于reward
        q_target = reward_batch + self.gamma * next_q_state_value * (1-done_batch[0])
        '''
        '''以下是Double DQNq_target计算方式,与NatureDQN稍有不同'''
        next_target_values = self.target_net(next_state_batch)
        # 选出Q(s_t‘, a)对应的action,代入到next_target_values获得target net对应的next_q_value,即Q’(s_t|a=argmax Q(s_t‘, a))
        next_target_q_value = next_target_values.gather(
            1,
            torch.max(next_q_values, 1)[1].unsqueeze(1)).squeeze(1)
        q_target = reward_batch + self.gamma * next_target_q_value * (
            1 - done_batch[0])
        self.loss = nn.MSELoss()(q_value, q_target.unsqueeze(1))  # 计算 均方误差loss
        # 优化模型
        self.optimizer.zero_grad(
        )  # zero_grad清除上一步所有旧的gradients from the last step
        # loss.backward()使用backpropagation计算loss相对于所有parameters(需要gradients)的微分
        self.loss.backward()
        for param in self.policy_net.parameters():  # clip防止梯度爆炸
            param.grad.data.clamp_(-1, 1)
        self.optimizer.step()  # 更新模型

    def save_model(self, path):
        torch.save(self.target_net.state_dict(), path)

    def load_model(self, path):
        self.target_net.load_state_dict(torch.load(path))
Esempio n. 8
0
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torchvision import datasets
from torch.utils.data import DataLoader
from model import MLP
import train
criterion = nn.CrossEntropyLoss()
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
data_test = datasets.CIFAR10('/data', train=False, download=True, transform=transform)

net = MLP(3 * 32 * 32, 10)
PATH = './cifar_net.pth'
net.load_state_dict(torch.load(PATH))
print(net)
test_loader = DataLoader(data_test, num_workers=0, batch_size=4)  # error with num_workers != 0
criterion = nn.CrossEntropyLoss()
# accuracy computation
all_labels_number = 0
all_correct_labels_number = 0
for data, label in test_loader:
    # print(data,label)
    net_out = net(data)
    _, label_pred = torch.max(net_out, 1)
    labels_in_batch = label.shape[0]
    correct_labels_in_batch = (label_pred == label).sum().item()
    all_labels_number += labels_in_batch
    all_correct_labels_number += correct_labels_in_batch
    # print(all_labels_number)
Esempio n. 9
0
def main():
    # Initialize environment
    env = UnityEnvironment(file_name='../env/Pong/Pong')

    default_brain = env.brain_names[0]
    brain = env.brains[default_brain]

    env_info = env.reset(train_mode=True)[default_brain]

    obs_dim = env_info.vector_observations[0].shape[0]
    act_num = brain.vector_action_space_size[0]
    print('State dimension:', obs_dim)
    print('Action number:', act_num)

    # Set a random seed
    np.random.seed(0)
    torch.manual_seed(0)

    # Create a SummaryWriter object by TensorBoard
    dir_name = 'runs/' + 'dqn/' + 'Pong_dqn' + '_' + time.ctime()
    writer = SummaryWriter(log_dir=dir_name)

    # Main network
    qf = MLP(obs_dim, act_num).to(device)
    # Target network
    qf_target = MLP(obs_dim, act_num).to(device)

    # Initialize target parameters to match main parameters
    qf_target.load_state_dict(qf.state_dict())

    # Create an optimizer
    qf_optimizer = optim.Adam(qf.parameters(), lr=1e-3)

    # Experience buffer
    replay_buffer = ReplayBuffer(obs_dim, 1, args.buffer_size)

    step_count = 0
    sum_returns = 0.
    num_episodes = 0
    recent_returns = deque(maxlen=10)

    start_time = time.time()

    for episode in range(1, args.episode_num + 1):
        total_reward = 0.

        env_info = env.reset(train_mode=True)[default_brain]
        obs = env_info.vector_observations[0]
        done = False

        # Keep interacting until agent reaches a terminal state.
        while not done:
            step_count += 1

            # Collect experience (s, a, r, s') using some policy
            action = select_action(torch.Tensor(obs).to(device), act_num, qf)

            env_info = env.step(int(action))[default_brain]

            next_obs = env_info.vector_observations[0]
            reward = env_info.rewards[0]
            done = env_info.local_done[0]

            # Add experience to replay buffer
            replay_buffer.add(obs, action, reward, next_obs, done)

            # Start training when the number of experience is greater than batch size
            if step_count > args.batch_size:
                batch = replay_buffer.sample(args.batch_size)
                train_model(qf, qf_target, qf_optimizer, batch, step_count)

            total_reward += reward
            obs = next_obs

        recent_returns.append(total_reward)
        sum_returns += total_reward
        num_episodes += 1
        average_return = sum_returns / num_episodes if num_episodes > 0 else 0.0

        # Log experiment result for training episodes
        writer.add_scalar('Train/AverageReturns', average_return, episode)
        writer.add_scalar('Train/EpisodeReturns', sum_returns, episode)

        if episode % 10 == 0:
            print('---------------------------------------')
            print('Episodes:', episode)
            print('Steps:', step_count)
            print('AverageReturn:', round(average_return, 2))
            print('RecentReturn:', np.mean(recent_returns))
            print('Time:', int(time.time() - start_time))
            print('---------------------------------------')

        # Save a training model
        if (np.mean(recent_returns)) >= args.threshold_return:
            print('Recent returns {} exceed threshold return. So end'.format(
                np.mean(recent_returns)))
            if not os.path.exists('./save_model'):
                os.mkdir('./save_model')

            ckpt_path = os.path.join('./save_model/' + 'Pong_dqn' + '_ep_' + str(episode) \
                                                                  + '_rt_' + str(round(average_return, 2)) \
                                                                  + '_t_' + str(int(time.time() - start_time)) + '.pt')
            torch.save(qf.state_dict(), ckpt_path)
            break

    env.close()
Esempio n. 10
0
def train_model(config, gpu_id, save_dir, exp_name):

    # Instantiating the model
    model_type = config.get('model_type', 'MLP')
    if model_type == "MLP":
        model = MLP(config['input_size'],
                    config["hidden_layers"],
                    1,
                    config["nonlinearity"],
                    config["initialization"],
                    config["dropout"],
                    verbose=True)
    elif model_type == "CNN":
        model = CNN(config["initialization"],
                    config["is_batch_norm"],
                    verbose=True)
    else:
        raise ValueError(
            'config["model_type"] not supported : {}'.format(model_type))

    if config['resume']:
        model.load_state_dict(
            torch.load(os.path.join(save_dir, exp_name, "model")))

    # If GPU is available, sends model and dataset on the GPU
    if torch.cuda.is_available():
        model.cuda(gpu_id)
        print("USING GPU-{}".format(gpu_id))

    # Optimizer and Loss Function
    optimizer = optim.RMSprop(model.parameters(), lr=config['lr'])
    loss_fn = nn.CrossEntropyLoss()
    """ Trains an agent with (stochastic) Policy Gradients on Pong. Uses OpenAI Gym. """
    env = gym.make("Pong-v0")
    observation = env.reset()

    prev_x = None  # used in computing the difference frame
    y_list, LL_list, reward_list = [], [], []
    running_reward = None
    reward_sum = 0
    episode_number = 0

    start = time.time()

    # Initializing recorders
    update = 0
    loss_tape = []
    our_score_tape = []
    opponent_score_tape = []
    our_score = 0
    opponent_score = 0

    # TRAINING LOOP
    while update < config['max_updates']:

        if config['render']: env.render()

        # preprocess the observation and set input to network to be difference image
        cur_x = utils.preprocess(observation,
                                 data_format=config['data_format'])
        if prev_x is None:
            x = np.zeros(cur_x.shape)
        else:
            x = cur_x - prev_x
        prev_x = cur_x

        x_torch = Variable(torch.from_numpy(x).float(), requires_grad=False)
        if config['data_format'] == "array":
            x_torch = x_torch.unsqueeze(dim=0).unsqueeze(dim=0)

        if torch.cuda.is_available():
            x_torch = x_torch.cuda(gpu_id)

        # Feedforward through the policy network
        action_prob = model(x_torch)

        # Sample an action from the returned probability
        if np.random.uniform() < action_prob.cpu().data.numpy():
            action = 2  # UP
        else:
            action = 3  # DOWN

        # record the log-likelihoods
        y = 1 if action == 2 else 0  # a "fake label"
        NLL = -y * torch.log(action_prob) - (1 - y) * torch.log(1 -
                                                                action_prob)
        LL_list.append(NLL)
        y_list.append(
            y
        )  # grad that encourages the action that was taken to be taken        TODO: the tensor graph breaks here. Find a way to backpropagate the PG error.

        # step the environment and get new measurements
        observation, reward, done, info = env.step(action)
        reward_sum += reward

        reward_list.append(
            reward
        )  # record reward (has to be done after we call step() to get reward for previous action)

        if done:  # an episode finished (an episode ends when one of the player wins 21 games)
            episode_number += 1

            # Computes loss and reward for each step of the episode
            R = torch.zeros(1, 1)
            loss = 0
            for i in reversed(range(len(reward_list))):
                R = config['gamma'] * R + reward_list[i]
                Return_i = Variable(R)
                if torch.cuda.is_available():
                    Return_i = Return_i.cuda(gpu_id)
                loss = loss + (LL_list[i] *
                               (Return_i)).sum()  # .expand_as(LL_list[i])
            loss = loss / len(reward_list)
            print(loss)

            # Backpropagates to compute the gradients
            loss.backward()

            y_list, LL_list, reward_list = [], [], []  # reset array memory

            # Performs parameter update every config['mb_size'] episodes
            if episode_number % config['mb_size'] == 0:

                # Takes one training step
                optimizer.step()

                # Empties the gradients
                optimizer.zero_grad()

                stop = time.time()
                print("PARAMETER UPDATE ------------ {}".format(stop - start))
                start = time.time()

                utils.save_results(save_dir, exp_name, loss_tape,
                                   our_score_tape, opponent_score_tape, config)

                update += 1
                if update % 10 == 0:
                    torch.save(
                        model.state_dict(),
                        os.path.join(save_dir, exp_name,
                                     "model_" + model.name()))

            # Records the average loss and score of the episode
            loss_tape.append(loss.cpu().data.numpy())

            our_score_tape.append(our_score)
            opponent_score_tape.append(opponent_score)
            our_score = 0
            opponent_score = 0

            # boring book-keeping
            if running_reward is None:
                running_reward = reward_sum
            else:
                running_reward = running_reward * 0.99 + reward_sum * 0.01
            print(
                'resetting env. episode reward total was {0:.2f}. running mean: {1:.2f}'
                .format(reward_sum, running_reward))

            reward_sum = 0
            observation = env.reset()  # reset env
            prev_x = None

        if reward != 0:  # Pong has either +1 or -1 reward exactly when game ends.
            if reward == -1:
                opponent_score += 1
                print('ep {0}: game finished, reward: {1:.2f}'.format(
                    episode_number, reward))
            else:
                our_score += 1
                print(
                    'ep {0}: game finished, reward: {1:.2f} !!!!!!!!!'.format(
                        episode_number, reward))
Esempio n. 11
0
def test(args):
    # setup multiprocessing instance
    torch.multiprocessing.set_sharing_strategy('file_system')

    # setup data_loader instances
    if args.arch == "MLP":
        test_data_loader = EdgeDataLoader(mode="test",
                                          data_path=args.data,
                                          batch_size=1,
                                          shuffle=True,
                                          num_workers=4,
                                          batch_type="large_batch")
    elif args.arch == "DeepSetMLP":
        test_data_loader = SubGraphDataLoader(mode="test",
                                              data_path=args.data,
                                              batch_size=1,
                                              shuffle=True,
                                              num_workers=4,
                                              batch_type="large_batch")
    elif args.arch == "DeepAPGMLP":
        test_data_loader = AnchorParentDataLoader(mode="test",
                                                  data_path=args.data,
                                                  batch_size=1,
                                                  shuffle=True,
                                                  num_workers=4,
                                                  batch_type="large_batch")

    # setup device
    device = torch.device(
        f'cuda:{args.device}' if torch.cuda.is_available() else 'cpu')

    # load model
    if args.arch == "MLP":
        model = MLP(vocab_size=29654,
                    embed_dim=250,
                    first_hidden=1000,
                    second_hidden=500,
                    activation=nn.LeakyReLU())
        # model = MLP(vocab_size=431416, embed_dim=250, first_hidden=1000, second_hidden=500, activation=nn.LeakyReLU())
    elif args.arch == "DeepSetMLP":
        model = DeepSetMLP(vocab_size=29654,
                           embed_dim=250,
                           first_hidden=1500,
                           second_hidden=1000,
                           activation=nn.LeakyReLU())
        # model = DeepSetMLP(vocab_size=431416, embed_dim=250, first_hidden=1500, second_hidden=1000, activation=nn.LeakyReLU())
    elif args.arch == "DeepAPGMLP":
        model = DeepAPGMLP(vocab_size=29654,
                           embed_dim=250,
                           first_hidden=2000,
                           second_hidden=1000,
                           activation=nn.LeakyReLU())
    checkpoint = torch.load(args.resume)
    state_dict = checkpoint['state_dict']
    model.load_state_dict(state_dict)
    model = model.to(device)
    model.eval()

    # get function handles of loss and metrics
    loss_fn = bce_loss
    metric_fn = [
        macro_averaged_rank, batched_topk_hit_1, batched_topk_hit_3,
        batched_topk_hit_5, batched_scaled_MRR
    ]

    # start evaluation on test data
    total_loss = 0.0
    total_metrics = torch.zeros(len(metric_fn))

    with torch.no_grad():
        for batched_examples in tqdm(test_data_loader):
            energy_scores = []
            all_labels = []
            if len(batched_examples) == 3:
                batched_parents, batched_children, batched_labels = batched_examples[
                    0], batched_examples[1], batched_examples[2]
                for parents, children, labels in zip(batched_parents,
                                                     batched_children,
                                                     batched_labels):
                    parents, children = parents.to(device), children.to(device)
                    prediction = model(parents, children).to(device)
                    loss = loss_fn(prediction, labels.to(device))
                    total_loss += loss.item()
                    energy_scores.extend(prediction.squeeze_().tolist())
                    all_labels.extend(labels.tolist())
            elif len(batched_examples) == 4:
                batched_parents, batched_siblings, batched_children, batched_labels = batched_examples[
                    0], batched_examples[1], batched_examples[
                        2], batched_examples[3]
                for parents, siblings, children, labels in zip(
                        batched_parents, batched_siblings, batched_children,
                        batched_labels):
                    parents, siblings, children = parents.to(
                        device), siblings.to(device), children.to(device)
                    prediction = model(parents, siblings, children).to(device)
                    loss = loss_fn(prediction, labels.to(device))
                    total_loss += loss.item()
                    energy_scores.extend(prediction.squeeze_().tolist())
                    all_labels.extend(labels.tolist())
            elif len(batched_examples) == 5:
                batched_parents, batched_siblings, batched_grand_parents, batched_children, batched_labels = batched_examples[
                    0], batched_examples[1], batched_examples[
                        2], batched_examples[3], batched_examples[4]
                for parents, siblings, grand_parents, children, labels in zip(
                        batched_parents, batched_siblings,
                        batched_grand_parents, batched_children,
                        batched_labels):
                    parents, siblings, grand_parents, children = parents.to(
                        device), siblings.to(device), grand_parents.to(
                            device), children.to(device)
                    prediction = model(parents, siblings, grand_parents,
                                       children).to(device)
                    loss = loss_fn(prediction, labels.to(device))
                    total_loss += loss.item()
                    energy_scores.extend(prediction.squeeze_().tolist())
                    all_labels.extend(labels.tolist())

            energy_scores = torch.tensor(energy_scores).unsqueeze_(1)
            all_labels = torch.tensor(all_labels)

            # computing metrics on test set
            for i, metric in enumerate(metric_fn):
                total_metrics[i] += metric(energy_scores, all_labels)

    n_samples = test_data_loader.n_samples
    print(f"Test loss: {total_loss / n_samples}")
    for i in range(len(metric_fn)):
        print(
            f"{metric_fn[i].__name__} : {total_metrics[i].item() / n_samples}")
Esempio n. 12
0
def train(lr=args.lr,
          n_hidden=args.n_hidden,
          batch_size=args.batch_size,
          dropout=args.dropout,
          valid_freq=3000,
          disp_freq=1000,
          save_freq=100000,
          max_epochs=args.n_epoch,
          patience=15,
          save_name=args.save_name,
          save_dir=args.save_dir,
          device=args.device):
    # Load train and valid dataset
    print('loading train')
    with open(args.train_path, 'rb') as f:
        train_val_y = pickle.load(f)
        train_val_x = pickle.load(f)

    print('loading english test')
    with open(args.en_test_path, 'rb') as f:
        en_test_y = pickle.load(f)
        en_test_x = pickle.load(f)

    print('loading french test')
    with open(args.fr_test_path, 'rb') as f:
        fr_test_y = pickle.load(f)
        fr_test_x = pickle.load(f)

    sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=1125)
    for train_index, test_index in sss.split(train_val_x, train_val_y):
        train_y = train_val_y[train_index]
        train_x = train_val_x[train_index]
        valid_y = train_val_y[test_index]
        valid_x = train_val_x[test_index]

    print('Number of training sample: %d' % train_x.shape[0])
    print('Number of validation sample: %d' % valid_x.shape[0])
    print('Number of english testing sample: %d' % en_test_x.shape[0])
    print('Number of french testing sample: %d' % fr_test_x.shape[0])
    print('-' * 100)

    kf_valid = get_minibatches_idx(len(valid_y), batch_size)
    kf_en_test = get_minibatches_idx(len(en_test_y), batch_size)
    kf_fr_test = get_minibatches_idx(len(fr_test_y), batch_size)

    # Loader parameter: use CUDA pinned memory for faster data loading
    pin_memory = (device == args.device)
    # Test set

    n_emb = train_x.shape[1]
    n_class = len(set(train_y))
    best_valid_acc = None
    bad_counter = 0

    uidx = 0  # the number of update done
    estop = False  # early stop switch
    net = MLP(n_mlp_layer=args.n_mlp_layers,
              n_hidden=args.n_hidden,
              dropout=args.dropout,
              n_class=n_class,
              n_emb=n_emb,
              device=args.device)

    if args.load_net != '':
        assert os.path.exists(
            args.load_net), 'Path to pretrained net does not exist'
        net.load_state_dict(torch.load(args.load_net))
        print('Load exists model stored at: ', args.load_net)

    if args.device == 'gpu':
        net = net.cuda()

    # Begin Training
    net.train()
    print('-' * 100)
    print('Model structure: ')
    print('MLP baseline')
    print(net.main)
    print('-' * 100)
    print('Parameters for tuning: ')
    print(net.state_dict().keys())
    print('-' * 100)

    # Define optimizer
    assert args.optimizer in [
        'SGD', 'Adam', "RMSprop", "LBFGS", "Rprop", "ASGD", "Adadelta",
        "Adagrad", "Adamax"
    ], 'Please choose either SGD or Adam'
    if args.optimizer == 'SGD':
        optimizer = optim.SGD(lr=lr,
                              params=filter(lambda p: p.requires_grad,
                                            net.parameters()),
                              momentum=0.9)
    else:
        optimizer = getattr(optim, args.optimizer)(params=filter(
            lambda p: p.requires_grad, net.parameters()),
                                                   lr=lr)

    #lambda1 = lambda epoch: epoch // 30
    lambda2 = lambda epoch: 0.98**epoch
    scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda2])
    #scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=max_epochs)
    #scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'max')
    try:
        for eidx in range(max_epochs):
            scheduler.step()
            # print('Training mode on: ' ,net.training)
            start_time = time.time()
            n_samples = 0
            # Get new shuffled index for the training set
            kf = get_minibatches_idx(len(train_y), batch_size, shuffle=True)

            for _, train_index in kf:
                # Remove gradient from previous batch
                #net.zero_grad()
                optimizer.zero_grad()
                uidx += 1
                y_batch = torch.autograd.Variable(
                    torch.from_numpy(train_y[train_index]).long())
                x_batch = torch.autograd.Variable(
                    torch.from_numpy(train_x[train_index]).float())
                if net.device == 'gpu':
                    y_batch = y_batch.cuda()
                scores = net.forward(x_batch)
                loss = net.loss(scores, y_batch)

                loss.backward()
                optimizer.step()
                n_samples += len(x_batch)
                gradient = 0

                # For logging gradient information
                for name, w in net.named_parameters():
                    if w.grad is not None:
                        w_grad = torch.norm(w.grad.data, 2)**2
                        gradient += w_grad
                gradient = gradient**0.5
                if np.mod(uidx, disp_freq) == 0:
                    print('Epoch ', eidx, 'Update ', uidx, 'Cost ',
                          loss.data[0], 'Gradient ', gradient)

                if save_name and np.mod(uidx, save_freq) == 0:
                    print('Saving...')
                    torch.save(
                        net.state_dict(), '%s/%s_epoch%d_update%d.net' %
                        (save_dir, save_name, eidx, uidx))

                if np.mod(uidx, valid_freq) == 0:
                    print("=" * 50)
                    print('Evaluation on validation set: ')
                    kf_valid = get_minibatches_idx(len(valid_y), batch_size)
                    top_1_acc, top_n_acc = eval.net_evaluation(
                        net, kf_valid, valid_x, valid_y)
                    #scheduler.step(top_1_acc)

                    # Save best performance state_dict for testing
                    if best_valid_acc is None:
                        best_valid_acc = top_1_acc
                        best_state_dict = net.state_dict()
                        torch.save(best_state_dict,
                                   '%s/%s_best.net' % (save_dir, save_name))
                    else:
                        if top_1_acc > best_valid_acc:
                            print(
                                'Best validation performance so far, saving model parameters'
                            )
                            print("*" * 50)
                            bad_counter = 0  # reset counter
                            best_valid_acc = top_1_acc
                            best_state_dict = net.state_dict()
                            torch.save(
                                best_state_dict,
                                '%s/%s_best.net' % (save_dir, save_name))
                        else:
                            bad_counter += 1
                            print('Validation accuracy: ', 100 * top_1_acc)
                            print('Getting worse, patience left: ',
                                  patience - bad_counter)
                            print('Best validation accuracy  now: ',
                                  100 * best_valid_acc)
                            # Learning rate annealing
                            lr /= args.lr_anneal
                            print('Learning rate annealed to: ', lr)
                            print('*' * 100)
                            if args.optimizer == 'SGD':
                                optimizer = optim.SGD(
                                    lr=lr,
                                    params=filter(lambda p: p.requires_grad,
                                                  net.parameters()),
                                    momentum=0.9)
                            else:
                                optimizer = getattr(optim, args.optimizer)(
                                    params=filter(lambda p: p.requires_grad,
                                                  net.parameters()),
                                    lr=lr)
                            if bad_counter > patience:
                                print('-' * 100)
                                print('Early Stop!')
                                estop = True
                                break

            epoch_time = time.time() - start_time
            print('Epoch processing time: %.2f s' % epoch_time)
            print('Seen %d samples' % n_samples)
            if estop:
                break
        print('-' * 100)
        print('Training finish')
        best_state_dict = torch.load('%s/%s_best.net' % (save_dir, save_name))
        torch.save(net.state_dict(), '%s/%s_final.net' % (save_dir, save_name))
        net.load_state_dict(best_state_dict)

        # add self connection
        print('Evaluation on validation set: ')
        kf_valid = get_minibatches_idx(len(valid_y), batch_size)
        eval.net_evaluation(net, kf_valid, valid_x, valid_y)

        # Evaluate model on test set
        print('Evaluation on test set: ')
        print('Evaluation on English testset: ')
        eval.net_evaluation(net, kf_en_test, en_test_x, en_test_y)
        print('Evaluation on French testset: ')
        eval.net_evaluation(net, kf_fr_test, fr_test_x, fr_test_y)
    except KeyboardInterrupt:
        print('-' * 100)
        print("Training interrupted, saving final model...")
        best_state_dict = torch.load('%s/%s_best.net' % (save_dir, save_name))
        torch.save(net.state_dict(), '%s/%s_final.net' % (save_dir, save_name))
        net.load_state_dict(best_state_dict)
        print('Evaluation on validation set: ')
        kf_valid = get_minibatches_idx(len(valid_y), batch_size)
        eval.net_evaluation(net, kf_valid, valid_x, valid_y)

        # Evaluate model on test set
        print('Evaluation on English testset: ')
        eval.net_evaluation(net, kf_en_test, en_test_x, en_test_y)
        print('Evaluation on French testset: ')
        eval.net_evaluation(net, kf_fr_test, fr_test_x, fr_test_y)
    input_dim = 40*(2*k+1)
    output_dim = 138

    print('Loading Inference Data...')
    val_data, val_idx = utils.load_data(os.path.join(args.data_path, 'test.npy'), k)
    val_label = np.arange(val_idx[-1]+len(val_data[val_idx[-1]]))
    val_dataset = utils.SpeechDataset(val_data,val_label,val_idx,k)
    val_dataloader = DataLoader(
        val_dataset,
        batch_size=batch_size,
        shuffle=False
    )

    print('Data Loaded!')

    #Load Model
    model = MLP(input_dim, output_dim)
    model.to(device)
    model.load_state_dict(torch.load(args.model_file))
    model.eval()

    print('Inference begins: ')

    pred_result = Val(
        val_dataloader,
        model
    )

    datafile = pd.DataFrame({'id': pred_result[:,0], 'label': pred_result[:,1]}, index=None)
    datafile.to_csv('result.csv', index=False)
def test(n, run_number):
    df_4_40 = pd.read_csv('./test_{}/merged_config_test_4_40.csv'.format(run_number))
    df_4_60 = pd.read_csv('./test_{}/merged_config_test_4_60.csv'.format(run_number))
    df_4_80 = pd.read_csv('./test_{}/merged_config_test_4_80.csv'.format(run_number))
    df_4_100 = pd.read_csv('./test_{}/merged_config_test_4_100.csv'.format(run_number))
    df_8_40 = pd.read_csv('./test_{}/merged_config_test_8_40.csv'.format(run_number))
    df_8_60 = pd.read_csv('./test_{}/merged_config_test_8_60.csv'.format(run_number))
    df_8_80 = pd.read_csv('./test_{}/merged_config_test_8_80.csv'.format(run_number))
    df_8_100 = pd.read_csv('./test_{}/merged_config_test_8_100.csv'.format(run_number))
    best_config = pd.read_csv('./test_{}/best_config_file.csv'.format(run_number))
    df_keys = {0: df_4_40, 1: df_4_60, 2: df_4_80, 3: df_4_100,
               4: df_8_40, 5: df_8_60, 6: df_8_80, 7: df_8_100}

    min_rows = 0
    min_rows = get_min_rows(df_keys, min_rows)

    if n == 1:
        model = MLP(15, 16, 8)
    else:
        model = MLP(7, 16, 8)
    model.load_state_dict(torch.load('checkpoint/MLP_model_19_train.pwf', map_location='cpu'))
    model.eval()

    data_point = list(df_8_100.iloc[0, [1, 2, 3, 5, 6, 7, 8]].values)

    if n == 1:
        one_hot_y = [0, 0, 0, 0, 0, 0, 0, 0]
        data_point = torch.Tensor(data_point + one_hot_y)
    else:
        data_point = torch.Tensor(data_point)

    with open("parameters.txt", "w") as f:
        f.write("Parameters \n")
        for i, param in enumerate(list(model.parameters())):
            if i % 2 == 0:
                weight = "weight for {} layer: ".format(i / 2 + 1) + str(param) + "\n"
                f.write(weight)
            else:
                bias = "bias for {} layer: ".format(int(i / 2) + 1) + str(param) + "\n"
                f.write(bias)

    cycles = df_8_100.iloc[0, 4]
    cycles_complete = df_8_100.iloc[0, 4]
    best_cycles = df_keys[best_config.iloc[0, -1]].iloc[0, 4]
    predicted = model.forward(data_point.reshape(1, -1))
    predicted = np.argmax(predicted.detach().cpu().numpy(), axis=-1)
    cycles_array = [int(cycles)]
    cores = [8]
    llc = [100]
    x_pos = [0]
    for i in range(1, min_rows):
        data_point = list(df_keys[predicted[0]].iloc[i, [1, 2, 3, 5, 6, 7, 8]].values)
        if n == 1:
            one_hot_y = oneHotEncoding(predicted)[0]
            data_point = torch.Tensor(data_point + one_hot_y)
        else:
            data_point = torch.Tensor(data_point)
        x_pos.append(cycles)
        cycles_array.append(int(df_keys[predicted[0]].iloc[i, 4]))
        cores.append(cores_llc_dict[predicted[0]]['cores'])
        llc.append(cores_llc_dict[predicted[0]]['llc'])
        cycles = cycles + df_keys[predicted[0]].iloc[i, 4]
        predicted = model.forward(data_point.reshape(1, -1))
        predicted = np.argmax(predicted.detach().cpu().numpy(), axis=-1)
        cycles_complete = cycles_complete + df_8_100.iloc[i, 4]
        best_cycles = best_cycles + df_keys[best_config.iloc[i, -1]].iloc[i, 4]

    print('About to plot the graphs for run_number: {}'.format(run_number))
    font = {'family': 'serif',
            'color': 'darkred',
            'weight': 'normal',
            'size': 32,
            }

    widths = [cycle * 10**-8*0.8 for cycle in cycles_array]
    x_pos_reduced = [x * 10**-8 for x in x_pos]
    plot_test_results(cores, font, run_number, widths, x_pos_reduced, 'Cores')
    plot_test_results(llc, font, run_number, widths, x_pos_reduced, 'LLC')

    print('run number:', run_number)
    print('cycles calculated:', cycles)
    print('cycles for complete configuration:', cycles_complete)
    print('best configuration cycles:', best_cycles)
    print('complete cycle percentage', cycles/cycles_complete * 100)
    print('best cycle percentage', cycles/best_cycles*100)
    print('\n')
Esempio n. 15
0
    #############################
    #####Random Ovesampling######
    #############################

    model = MLP()
    model = model.to(device)

    for name, param in model.named_parameters():
        if param.device.type != 'cuda':
            print('param {}, not on GPU'.format(name))

    wandb.init(project='Seq Boost2',
               config=config,
               name='RUS p={} mu={} eta={}'.format(P, M, E))

    optimizer = optim.SGD(model.parameters(),
                          lr=config['learning_rate'],
                          momentum=config['momentum'])
    mid_model, train_loss, valid_loss = train(model,
                                              rus_train_loader,
                                              valid_loader,
                                              batch_size=BATCH_SIZE,
                                              wandb_log=True,
                                              patience=EARLY_STOPPING,
                                              consolidate=False,
                                              n_epochs=config['epoch'])

    model.load_state_dict(torch.load(os.path.join(PATH, 'checkpoint.pt')))
    evaluate(model, test_loader, batch_size=BATCH_SIZE)