Beispiel #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu', type=int, default=0, help='the gpu will be used, e.g "0,1,2,3"')
    parser.add_argument('--max_iter', type=int, default=50, help='number of iterations')
    parser.add_argument('--decay_epoch', type=int, default=20, help='number of iterations')
    parser.add_argument('--test', type=bool, default=False, help='enable testing')
    parser.add_argument('--train_test', type=bool, default=True, help='enable testing')
    parser.add_argument('--show', type=bool, default=True, help='print progress')
    parser.add_argument('--init_std', type=float, default=0.1, help='weight initialization std')
    parser.add_argument('--init_lr', type=float, default=0.01, help='initial learning rate')
    parser.add_argument('--lr_decay', type=float, default=0.75, help='learning rate decay')
    parser.add_argument('--final_lr', type=float, default=1E-5,
                        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum', type=float, default=0.9, help='momentum rate')
    parser.add_argument('--max_grad_norm', type=float, default=50.0, help='maximum gradient norm')
    # parser.add_argument('--final_fc_dim', type=float, default=200, help='hidden state dim for final fc layer')
    parser.add_argument('--first_k', type=int, default=8, help='first k question without loss calculation')
    parser.add_argument('--dataset', type=str, default='assist2009_updated')
    parser.add_argument('--train_set', type=int, default=1)

    parser.add_argument('--memory_size', type=int, default=20, help='memory size')
    parser.add_argument('--q_embed_dim', type=int, default=50, help='question embedding dimensions')
    parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
    
    if parser.parse_args().dataset == 'assist2009_updated':
        # memory_size: 20, q_embed_dim: 50, qa_embed_dim: 200
        parser.add_argument('--batch_size', type=int, default=128, help='the batch size')
        parser.add_argument('--n_question', type=int, default=110, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2009_updated', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2009_updated', help='data set name')
        parser.add_argument('--load', type=str, default='assist2009_updated', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2009_updated', help='path to save model')
        parser.add_argument('--final_fc_dim', type=float, default=110, help='hidden state dim for final fc layer')
    
    elif parser.parse_args().dataset == 'assist2015':
        # memory_size: 50, q_embed_dim: 50, qa_embed_dim: 200
        parser.add_argument('--batch_size', type=int, default=128, help='the batch size')
        parser.add_argument('--n_question', type=int, default=100, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2015', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2015', help='data set name')
        parser.add_argument('--load', type=str, default='assist2015', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2015', help='path to save model')
        parser.add_argument('--final_fc_dim', type=float, default=100, help='hidden state dim for final fc layer')
   
    elif parser.parse_args().dataset == 'assist2017':
        # memory_size: 20, q_embed_dim: 50, qa_embed_dim: 100
        parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        parser.add_argument('--n_question', type=int, default=102,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2017/train_valid_test/', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2017', help='data set name')
        parser.add_argument('--load', type=str, default='assist2017', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2017', help='path to save model')
        parser.add_argument('--final_fc_dim', type=float, default=102, help='hidden state dim for final fc layer')

    elif parser.parse_args().dataset == 'STATICS':
        # memory_size: 50, q_embed_dim: 50, qa_embed_dim: 100
        parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        parser.add_argument('--n_question', type=int, default=1223, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/STATICS', help='data directory')
        parser.add_argument('--data_name', type=str, default='STATICS', help='data set name')
        parser.add_argument('--load', type=str, default='STATICS', help='model file to load')
        parser.add_argument('--save', type=str, default='STATICS', help='path to save model')
        parser.add_argument('--final_fc_dim', type=float, default=1223, help='hidden state dim for final fc layer')

    elif parser.parse_args().dataset == 'synthetic':
        # memory_size: 20, q_embed_dim: 50, qa_embed_dim: 100
        parser.add_argument('--batch_size', type=int, default=128, help='the batch size')
        parser.add_argument('--n_question', type=int, default=50,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/synthetic/', help='data directory')
        parser.add_argument('--data_name', type=str, default='synthetic', help='data set name')
        parser.add_argument('--load', type=str, default='synthetic', help='model file to load')
        parser.add_argument('--save', type=str, default='synthetic', help='path to save model')
        parser.add_argument('--final_fc_dim', type=float, default=50, help='hidden state dim for final fc layer')

    params = parser.parse_args()
    params.lr = params.init_lr
    params.memory_key_state_dim = params.q_embed_dim
    params.memory_value_state_dim = params.qa_embed_dim

    print(params)

    dat = DATA(n_question=params.n_question, seqlen=params.seqlen, separate_char=',')
    if params.dataset != 'synthetic':
        train_data_path = params.data_dir + "/" + params.data_name + "_train" + str(params.train_set) + ".csv"
        valid_data_path = params.data_dir + "/" + params.data_name + "_valid" + str(params.train_set) + ".csv"
        test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    else:
        train_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_train" + str(params.train_set) + ".csv"
        valid_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_valid" + str(params.train_set) + ".csv"
        test_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_test.csv"

    train_q_data, train_qa_data, train_a_data = dat.load_data(train_data_path)
    valid_q_data, valid_qa_data, valid_a_data = dat.load_data(valid_data_path)
    test_q_data, test_qa_data, test_a_data = dat.load_data(test_data_path)

    params.memory_key_state_dim = params.q_embed_dim
    params.memory_value_state_dim = params.qa_embed_dim

    model = MODEL(n_question=params.n_question,
                  batch_size=params.batch_size,
                  q_embed_dim=params.q_embed_dim,
                  qa_embed_dim=params.qa_embed_dim,
                  memory_size=params.memory_size,
                  memory_key_state_dim=params.memory_key_state_dim,
                  memory_value_state_dim=params.memory_value_state_dim,
                  final_fc_dim=params.final_fc_dim,
                  first_k=params.first_k,
                  gpu=params.gpu)


    model.init_embeddings()
    model.init_params()
    optimizer = optim.Adam(params=model.parameters(), lr=params.lr, betas=(0.9, 0.9))

    if params.gpu >= 0:
        print('device: ' + str(params.gpu))
        torch.cuda.set_device(params.gpu)
        model.cuda()

    best_valid_auc = 0
    correspond_train_auc = 0
    correspond_test_auc = 0

    for idx in range(params.max_iter):
        train_loss, train_accuracy, train_auc = train(model, params, optimizer, train_q_data, train_qa_data, train_a_data)
        print('Epoch %d/%d, loss : %3.5f, auc : %3.5f, accuracy : %3.5f' % (idx + 1, params.max_iter, train_loss, train_auc, train_accuracy))
        valid_loss, valid_accuracy, valid_auc = test(model, params, optimizer, valid_q_data, valid_qa_data, valid_a_data)
        print('Epoch %d/%d, valid auc : %3.5f, valid accuracy : %3.5f' % (idx + 1, params.max_iter, valid_auc, valid_accuracy))
        test_loss, test_accuracy, test_auc = test(model, params, optimizer, test_q_data, test_qa_data, test_a_data)
        print('Epoch %d/%d, test auc : %3.5f, test accuracy : %3.5f' % (idx + 1, params.max_iter, test_auc, test_accuracy))

        # output the epoch with the best validation auc
        if valid_auc > best_valid_auc:
            print('%3.4f to %3.4f' % (best_valid_auc, valid_auc))
            best_valid_auc = valid_auc
            correspond_train_auc = train_auc
            correspond_test_auc = test_auc

    print("DATASET: {}, MEMO_SIZE: {}, Q_EMBED_SIZE: {}, QA_EMBED_SIZE: {}, LR: {}".format(params.data_name, params.memory_size, params.q_embed_dim, params.qa_embed_dim, params.init_lr))
    print("BEST VALID AUC: {}, CORRESPOND TRAIN AUC: {}, CORRESPOND TEST AUC: {}".format(best_valid_auc, correspond_train_auc, correspond_test_auc))
Beispiel #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu',
                        type=int,
                        default=0,
                        help='the gpu will be used, e.g "0,1,2,3"')
    parser.add_argument('--max_iter',
                        type=int,
                        default=30,
                        help='number of iterations')
    parser.add_argument('--decay_epoch',
                        type=int,
                        default=20,
                        help='number of iterations')
    parser.add_argument('--test',
                        type=bool,
                        default=False,
                        help='enable testing')
    parser.add_argument('--train_test',
                        type=bool,
                        default=True,
                        help='enable testing')
    parser.add_argument('--show',
                        type=bool,
                        default=True,
                        help='print progress')
    parser.add_argument('--init_std',
                        type=float,
                        default=0.1,
                        help='weight initialization std')
    parser.add_argument('--init_lr',
                        type=float,
                        default=0.01,
                        help='initial learning rate')
    parser.add_argument('--lr_decay',
                        type=float,
                        default=0.75,
                        help='learning rate decay')
    parser.add_argument(
        '--final_lr',
        type=float,
        default=1E-5,
        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.9,
                        help='momentum rate')
    parser.add_argument('--maxgradnorm',
                        type=float,
                        default=50.0,
                        help='maximum gradient norm')
    parser.add_argument('--final_fc_dim',
                        type=float,
                        default=50,
                        help='hidden state dim for final fc layer')

    dataset = 'assist2009_updated'

    if dataset == 'assist2009_updated':
        parser.add_argument('--q_embed_dim',
                            type=int,
                            default=50,
                            help='question embedding dimensions')
        parser.add_argument('--batch_size',
                            type=int,
                            default=32,
                            help='the batch size')
        parser.add_argument('--qa_embed_dim',
                            type=int,
                            default=200,
                            help='answer and question embedding dimensions')
        parser.add_argument('--memory_size',
                            type=int,
                            default=20,
                            help='memory size')
        parser.add_argument(
            '--n_question',
            type=int,
            default=110,
            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen',
                            type=int,
                            default=200,
                            help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir',
                            type=str,
                            default='./data/assist2009_updated',
                            help='data directory')
        parser.add_argument('--data_name',
                            type=str,
                            default='assist2009_updated',
                            help='data set name')
        parser.add_argument('--load',
                            type=str,
                            default='data/assist2009_updated',
                            help='model file to load')
        parser.add_argument('--save',
                            type=str,
                            default='data/assist2009_updated/model',
                            help='path to save model')

    elif dataset == 'STATICS':
        parser.add_argument('--batch_size',
                            type=int,
                            default=10,
                            help='the batch size')
        parser.add_argument('--q_embed_dim',
                            type=int,
                            default=50,
                            help='question embedding dimensions')
        parser.add_argument('--qa_embed_dim',
                            type=int,
                            default=100,
                            help='answer and question embedding dimensions')
        parser.add_argument('--memory_size',
                            type=int,
                            default=50,
                            help='memory size')
        parser.add_argument(
            '--n_question',
            type=int,
            default=1223,
            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen',
                            type=int,
                            default=6,
                            help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir',
                            type=str,
                            default='./data/STATICS',
                            help='data directory')
        parser.add_argument('--data_name',
                            type=str,
                            default='STATICS',
                            help='data set name')
        parser.add_argument('--load',
                            type=str,
                            default='STATICS',
                            help='model file to load')
        parser.add_argument('--save',
                            type=str,
                            default='STATICS',
                            help='path to save model')

    params = parser.parse_args()
    model = torch.load(params.save + "/best.pt")
    print(params)
    ## 读取test数据 作为推荐数据集合
    dat = DATA(n_question=params.n_question,
               seqlen=params.seqlen,
               separate_char=',')
    test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    test_q_data, test_qa_data, test_id = dat.load_data(test_data_path)
    # 制作 user-q-qa字典 用于推荐以及SR计算
    id_q_qa = id_q_qa_dict(test_id, test_q_data, test_qa_data)

    ## 读取每个用户的知识矩阵,协同过滤后得到相似用户
    km = knowledge_matrix(model, params, test_id, test_q_data, test_qa_data)
    user_distance = user_distance_matrix(km, params)
    user_top3 = user_topk(user_distance, 3)

    ## 使用相似用户,对于该用户推荐,得到推荐习题
    rec_id = test_id[100]
    recom_q_id = user_recom_q(rec_id, id_q_qa, user_top3)
    print(recom_q_id)
Beispiel #3
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu', type=int, default=0)
    parser.add_argument('--max_iter', type=int, default=30, help='number of iterations')
    parser.add_argument('--decay_epoch', type=int, default=20, help='number of iterations')
    parser.add_argument('--test', type=bool, default=False, help='enable testing')
    parser.add_argument('--train_test', type=bool, default=True, help='enable testing')
    parser.add_argument('--show', type=bool, default=True, help='print progress')
    parser.add_argument('--init_std', type=float, default=0.1, help='weight initialization std')
    parser.add_argument('--init_lr', type=float, default=0.01, help='initial learning rate')
    parser.add_argument('--lr_decay', type=float, default=0.75, help='learning rate decay')
    parser.add_argument('--final_lr', type=float, default=1E-5,
                        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum', type=float, default=0.9, help='momentum rate')
    parser.add_argument('--max_grad_norm', type=float, default=3.0, help='maximum gradient norm')
    parser.add_argument('--hidden_dim', type=int, default=64, help='hidden layer dimension')
    parser.add_argument('--n_hidden', type=int, default=2, help='hidden numbers')
    parser.add_argument('--dataset', type=str, default='assist2009_updated')
    parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
    parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
    parser.add_argument('--dropout_rate', type=float, default=0.6)


    if parser.parse_args().dataset == 'assist2009_updated':
        # parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        # parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=110, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2009_updated', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2009_updated', help='data set name')
        parser.add_argument('--load', type=str, default='assist2009_updated', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2009_updated', help='path to save model')

    elif parser.parse_args().dataset == 'assist2015':
        # parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        # parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=100, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2015', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2015', help='data set name')
        parser.add_argument('--load', type=str, default='assist2015', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2015', help='path to save model')

    elif parser.parse_args().dataset == 'STATICS':
        # parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        # parser.add_argument('--qa_embed_dim', type=int, default=100, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=1223,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/STATICS', help='data directory')
        parser.add_argument('--data_name', type=str, default='STATICS', help='data set name')
        parser.add_argument('--load', type=str, default='STATICS', help='model file to load')
        parser.add_argument('--save', type=str, default='STATICS', help='path to save model')

    elif parser.parse_args().dataset == 'synthetic':
        # parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        # parser.add_argument('--qa_embed_dim', type=int, default=100, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=50,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/synthetic', help='data directory')
        parser.add_argument('--data_name', type=str, default='synthetic', help='data set name')
        parser.add_argument('--load', type=str, default='synthetic', help='model file to load')
        parser.add_argument('--save', type=str, default='synthetic', help='path to save model')

    elif parser.parse_args().dataset == 'assist2017':
        # parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        # parser.add_argument('--qa_embed_dim', type=int, default=100, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=102,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='../dataset/assist2017/train_valid_test', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2017', help='data set name')
        parser.add_argument('--load', type=str, default='assist2017', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2017', help='path to save model')

    params = parser.parse_args()
    params.lr = params.init_lr

    print(params)

    dat = DATA(n_question=params.n_question, seqlen=params.seqlen, separate_char=',')
    if params.dataset != 'synthetic':
        train_data_path = params.data_dir + "/" + params.data_name + "_train1.csv"
        valid_data_path = params.data_dir + "/" + params.data_name + "_valid1.csv"
        test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    else:
        train_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_train1.csv"
        valid_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_valid1.csv"
        test_data_path = params.data_dir + "/" + "naive_c5_q50_s4000_v0_test.csv"

    train_q_data, train_q_t_data, train_answer_data, train_repeated_time_gap, train_past_trail_counts,\
    train_seq_time_gap = dat.load_data(train_data_path)
    valid_q_data, valid_q_t_data, valid_answer_data, valid_repeated_time_gap, valid_past_trail_counts,\
    valid_seq_time_gap  = dat.load_data(valid_data_path)
    test_q_data, test_q_t_data, test_answer_data, test_repeated_time_gap, test_past_trail_counts,\
    test_seq_time_gap = dat.load_data(test_data_path)

    model = MODEL(batch_size=params.batch_size,
                  seqlen=params.seqlen,
                  n_question=params.n_question,
                  hidden_dim=params.hidden_dim,
                  x_embed_dim=params.qa_embed_dim,
                  hidden_layers=params.n_hidden,
                  dropout_rate=params.dropout_rate,
                  gpu=params.gpu)

    model.init_embeddings()
    model.init_params()
    optimizer = optim.Adam(params=model.parameters(), lr=params.lr, betas=(0.9, 0.9))

    if params.gpu >= 0:
        print('device: ' + str(params.gpu))
        torch.cuda.set_device(params.gpu)
        model.cuda()

    # all_train_loss = {}
    # all_train_accuracy = {}
    # all_train_auc = {}
    # all_valid_loss = {}
    # all_valid_accuracy = {}
    # all_valid_auc = {}
    # all_test_loss = {}
    # all_test_accuracy = {}
    # all_test_auc = {}
    best_valid_auc = 0
    cur_test_auc = 0
    cur_train_auc = 0

    for idx in range(params.max_iter):
        train_loss, train_accuracy, train_auc = train(model, params, optimizer, train_q_data, train_q_t_data,
                                                      train_answer_data, train_repeated_time_gap,\
                                                      train_past_trail_counts, train_seq_time_gap)
        print('Epoch %d/%d, loss : %3.5f, auc : %3.5f, accuracy : %3.5f' % (
            idx + 1, params.max_iter, train_loss, train_auc, train_accuracy))
        valid_loss, valid_accuracy, valid_auc = test(model, params, optimizer, valid_q_data, valid_q_t_data,
                                                     valid_answer_data, valid_repeated_time_gap,\
                                                     valid_past_trail_counts, valid_seq_time_gap)
        print('Epoch %d/%d, valid auc : %3.5f, valid accuracy : %3.5f' % (
            idx + 1, params.max_iter, valid_auc, valid_accuracy))
        test_loss, test_accuracy, test_auc = test(model, params, optimizer, test_q_data, test_q_t_data,
                                                  test_answer_data, test_repeated_time_gap,
                                                  test_past_trail_counts, test_seq_time_gap)
        print('Epoch %d/%d, test auc : %3.5f, test accuracy : %3.5f' % (
            idx + 1, params.max_iter, test_auc, test_accuracy))

        # all_train_auc[idx + 1] = train_auc
        # all_train_accuracy[idx + 1] = train_accuracy
        # all_train_loss[idx + 1] = train_loss
        # all_valid_loss[idx + 1] = valid_loss
        # all_valid_accuracy[idx + 1] = valid_accuracy
        # all_valid_auc[idx + 1] = valid_auc
        # all_test_loss[idx + 1] = test_loss
        # all_test_accuracy[idx + 1] = test_accuracy
        # all_test_auc[idx + 1] = test_auc

        if valid_auc > best_valid_auc:
            print('%3.4f to %3.4f' % (best_valid_auc, valid_auc))
            best_valid_auc = valid_auc
            cur_test_auc = test_auc
            cur_train_auc = train_auc

    print('DATASET: {}, TRAIN AUC: {}, BEST VALID AUC: {}, TEST AUC: {}'.format(params.data_name, cur_train_auc, \
                                                                                best_valid_auc, cur_test_auc))
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu',
                        type=int,
                        default=0,
                        help='the gpu will be used, e.g "0,1,2,3"')
    parser.add_argument('--max_iter',
                        type=int,
                        default=30,
                        help='number of iterations')
    parser.add_argument('--decay_epoch',
                        type=int,
                        default=20,
                        help='number of iterations')
    parser.add_argument('--test',
                        type=bool,
                        default=False,
                        help='enable testing')
    parser.add_argument('--train_test',
                        type=bool,
                        default=True,
                        help='enable testing')
    parser.add_argument('--show',
                        type=bool,
                        default=True,
                        help='print progress')
    parser.add_argument('--init_std',
                        type=float,
                        default=0.1,
                        help='weight initialization std')
    parser.add_argument('--init_lr',
                        type=float,
                        default=0.01,
                        help='initial learning rate')
    parser.add_argument('--lr_decay',
                        type=float,
                        default=0.75,
                        help='learning rate decay')
    parser.add_argument(
        '--final_lr',
        type=float,
        default=1E-5,
        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.9,
                        help='momentum rate')
    parser.add_argument('--maxgradnorm',
                        type=float,
                        default=50.0,
                        help='maximum gradient norm')
    parser.add_argument('--final_fc_dim',
                        type=float,
                        default=50,
                        help='hidden state dim for final fc layer')

    dataset = 'assist2009_updated'

    if dataset == 'assist2009_updated':
        parser.add_argument('--q_embed_dim',
                            type=int,
                            default=50,
                            help='question embedding dimensions')
        parser.add_argument('--batch_size',
                            type=int,
                            default=32,
                            help='the batch size')
        parser.add_argument('--qa_embed_dim',
                            type=int,
                            default=200,
                            help='answer and question embedding dimensions')
        parser.add_argument('--memory_size',
                            type=int,
                            default=20,
                            help='memory size')
        parser.add_argument(
            '--n_question',
            type=int,
            default=110,
            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen',
                            type=int,
                            default=200,
                            help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir',
                            type=str,
                            default='./data/assist2009_updated',
                            help='data directory')
        parser.add_argument('--data_name',
                            type=str,
                            default='assist2009_updated',
                            help='data set name')
        parser.add_argument('--load',
                            type=str,
                            default='data/assist2009_updated',
                            help='model file to load')
        parser.add_argument('--save',
                            type=str,
                            default='data/assist2009_updated/model',
                            help='path to save model')

    elif dataset == 'STATICS':
        parser.add_argument('--batch_size',
                            type=int,
                            default=10,
                            help='the batch size')
        parser.add_argument('--q_embed_dim',
                            type=int,
                            default=50,
                            help='question embedding dimensions')
        parser.add_argument('--qa_embed_dim',
                            type=int,
                            default=100,
                            help='answer and question embedding dimensions')
        parser.add_argument('--memory_size',
                            type=int,
                            default=50,
                            help='memory size')
        parser.add_argument(
            '--n_question',
            type=int,
            default=1223,
            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen',
                            type=int,
                            default=6,
                            help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir',
                            type=str,
                            default='./data/STATICS',
                            help='data directory')
        parser.add_argument('--data_name',
                            type=str,
                            default='STATICS',
                            help='data set name')
        parser.add_argument('--load',
                            type=str,
                            default='STATICS',
                            help='model file to load')
        parser.add_argument('--save',
                            type=str,
                            default='STATICS',
                            help='path to save model')

    params = parser.parse_args()
    params.lr = params.init_lr
    params.memory_key_state_dim = params.q_embed_dim  # 50
    params.memory_value_state_dim = params.qa_embed_dim  # 200

    print(params)

    dat = DATA(n_question=params.n_question,
               seqlen=params.seqlen,
               separate_char=',')
    # train_data_path = params.data_dir + "/" + "test5.1.txt"
    train_data_path = params.data_dir + "/" + params.data_name + "_train2.csv"
    valid_data_path = params.data_dir + "/" + params.data_name + "_valid2.csv"
    test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    train_q_data, train_qa_data, _ = dat.load_data(train_data_path)
    valid_q_data, valid_qa_data, _ = dat.load_data(valid_data_path)
    test_q_data, test_qa_data, _ = dat.load_data(test_data_path)

    params.memory_key_state_dim = params.q_embed_dim  # 记忆key = 问题embedding的维度
    params.memory_value_state_dim = params.qa_embed_dim  # 记忆val = 回答embedding的维度

    model = MODEL(n_question=params.n_question,
                  batch_size=params.batch_size,
                  q_embed_dim=params.q_embed_dim,
                  qa_embed_dim=params.qa_embed_dim,
                  memory_size=params.memory_size,
                  memory_key_state_dim=params.memory_key_state_dim,
                  memory_value_state_dim=params.memory_value_state_dim,
                  final_fc_dim=params.final_fc_dim)

    model.init_embeddings()
    model.init_params()
    # optimizer = optim.SGD(params=model.parameters(), lr=params.lr, momentum=params.momentum)
    optimizer = optim.Adam(params=model.parameters(),
                           lr=params.lr,
                           betas=(0.9, 0.9))

    if params.gpu >= 0:
        print('device: ' + str(params.gpu))
        torch.cuda.set_device(params.gpu)
        model.cuda()

    all_train_loss = {}
    all_train_accuracy = {}
    all_train_auc = {}
    all_valid_loss = {}
    all_valid_accuracy = {}
    all_valid_auc = {}
    best_valid_auc = 0

    train_shuffle_index = np.random.permutation(train_q_data.shape[0])
    valid_shuffie_index = np.random.permutation(valid_q_data.shape[0])
    train_q_data_shuffled = train_q_data[train_shuffle_index]
    train_qa_data_shuffled = train_qa_data[train_shuffle_index]
    valid_q_data_shuffled = valid_q_data[valid_shuffie_index]
    valid_qa_data_shuffled = valid_qa_data[valid_shuffie_index]

    train_loss_list, train_acc_list, train_auc_list, train_f1_list = [], [], [], []
    valid_loss_list, valid_acc_list, valid_auc_list, valid_f1_list = [], [], [], []

    for idx in range(params.max_iter):

        # train_loss, train_accuracy, train_auc = train(idx, model, params, optimizer, train_q_data, train_qa_data)
        train_loss, train_accuracy, train_auc, train_f1 = train(
            idx, model, params, optimizer, train_q_data_shuffled,
            train_qa_data_shuffled)
        train_loss_list.append(train_loss)
        train_acc_list.append(train_accuracy)
        train_auc_list.append(train_auc)
        train_f1_list.append(train_f1)
        print(
            'Epoch %d/%d, loss : %3.5f, auc : %3.5f, accuracy : %3.5f, f1 : %.4f'
            % (idx + 1, params.max_iter, train_loss, train_auc, train_accuracy,
               train_f1))
        # valid_loss, valid_accuracy, valid_auc = test(model, params, optimizer, valid_q_data, valid_qa_data)
        valid_loss, valid_accuracy, valid_auc, valid_f1 = test(
            model, params, optimizer, valid_q_data_shuffled,
            valid_qa_data_shuffled)
        valid_loss_list.append(valid_loss)
        valid_acc_list.append(valid_accuracy)
        valid_auc_list.append(valid_auc)
        valid_f1_list.append(valid_f1)
        print(
            'Epoch %d/%d, valid auc : %3.5f, valid accuracy : %3.5f, f1 : %.4f'
            % (idx + 1, params.max_iter, valid_auc, valid_accuracy, valid_f1))

        all_train_auc[idx + 1] = train_auc
        all_train_accuracy[idx + 1] = train_accuracy
        all_train_loss[idx + 1] = train_loss
        all_valid_loss[idx + 1] = valid_loss
        all_valid_accuracy[idx + 1] = valid_accuracy
        all_valid_auc[idx + 1] = valid_auc
        #
        # output the epoch with the best validation auc
        generate_dir(params.save)
        if valid_auc > best_valid_auc:
            print('%3.4f to %3.4f' % (best_valid_auc, valid_auc))
            best_valid_auc = valid_auc
            best_epoch = idx + 1
            best_valid_acc = valid_accuracy
            best_valid_loss = valid_loss
            test_loss, test_accuracy, test_auc, test_f1 = test(
                model, params, optimizer, test_q_data, test_qa_data)
            print(
                "test_auc: %.4f\ttest_accuracy: %.4f\ttest_loss: %.4f\ttest_f1: %.4f"
                % (test_auc, test_accuracy, test_loss, test_f1))
            # save_checkpoint(model, memory, params.save + "/Epoch%d-test_auc%.2f-val_auc%.2f-loss%.2f.pt"%(best_epoch, test_auc, valid_auc, test_loss))
            save_path = params.save + "/Epoch%d-test_auc%.2f-val_auc%.2f-loss%.2f.pt" % (
                best_epoch, test_auc, valid_auc, test_loss)
            torch.save(model, save_path)
            print(save_path + " save to " + params.save)

    print("best outcome: best epoch: %.4f" % (best_epoch))
    os.system(f"mv {save_path} {params.save}/best.pt")
    print("valid_auc: %.4f\tvalid_accuracy: %.4f\tvalid_loss: %.4f\t" %
          (best_valid_auc, best_valid_acc, best_valid_loss))
    print("test_auc: %.4f\ttest_accuracy: %.4f\ttest_loss: %.4f\t" %
          (test_auc, test_accuracy, test_loss))

    print(train_loss_list, train_acc_list, train_auc_list, train_f1_list,
          valid_loss_list, valid_acc_list, valid_auc_list, valid_f1_list)
    train_log = 'log.txt'
    with open(train_log, "w") as f:
        f.write("train_loss_list================")
        f.write(str(train_loss_list))
        f.write("train_acc_list================")
        f.write(str(train_acc_list))
        f.write("train_auc_list================")
        f.write(str(train_auc_list))
        f.write("train_f1_lis================")
        f.write(str(train_f1_list))
        f.write("valid_loss_list================")
        f.write(str(valid_loss_list))
        f.write("valid_acc_list================")
        f.write(str(valid_acc_list))
        f.write("================")
        f.write(str(valid_auc_list))
        f.write("================")
        f.write(str(valid_f1_list))
    np.save("train_loss_list.npy", np.array(train_loss_list))
    np.save("train_acc_list.npy", np.array(train_acc_list))
    np.save("train_auc_list.npy", np.array(train_auc_list))
    np.save("train_f1_list.npy", np.array(train_f1_list))
    np.save("valid_loss_list.npy", np.array(valid_loss_list))
    np.save("valid_acc_list.npy", np.array(valid_acc_list))
    np.save("valid_auc_list.npy", np.array(valid_auc_list))
    np.save("valid_f1_list.npy", np.array(valid_f1_list))
Beispiel #5
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu', type=int, default=0, help='the gpu will be used, e.g "0,1,2,3"')
    parser.add_argument('--max_iter', type=int, default=300, help='number of iterations')
    parser.add_argument('--decay_epoch', type=int, default=20, help='number of iterations')
    parser.add_argument('--test', type=bool, default=False, help='enable testing')
    parser.add_argument('--train_test', type=bool, default=True, help='enable testing')
    parser.add_argument('--show', type=bool, default=True, help='print progress')
    parser.add_argument('--init_std', type=float, default=0.1, help='weight initialization std')
    parser.add_argument('--init_lr', type=float, default=0.01, help='initial learning rate')
    parser.add_argument('--lr_decay', type=float, default=0.75, help='learning rate decay')
    parser.add_argument('--final_lr', type=float, default=1E-5,
                        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum', type=float, default=0.9, help='momentum rate')
    parser.add_argument('--maxgradnorm', type=float, default=50.0, help='maximum gradient norm')
    parser.add_argument('--final_fc_dim', type=float, default=50, help='hidden state dim for final fc layer')

    dataset = 'assist2009_updated'

    if dataset == 'assist2009_updated':
        parser.add_argument('--q_embed_dim', type=int, default=50, help='question embedding dimensions')
        parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
        parser.add_argument('--memory_size', type=int, default=20, help='memory size')
        parser.add_argument('--n_question', type=int, default=110, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='./data/assist2009_updated', help='data directory')
        parser.add_argument('--data_name', type=str, default='assist2009_updated', help='data set name')
        parser.add_argument('--load', type=str, default='assist2009_updated', help='model file to load')
        parser.add_argument('--save', type=str, default='assist2009_updated', help='path to save model')

    elif dataset == 'STATICS':
        parser.add_argument('--batch_size', type=int, default=10, help='the batch size')
        parser.add_argument('--q_embed_dim', type=int, default=50, help='question embedding dimensions')
        parser.add_argument('--qa_embed_dim', type=int, default=100, help='answer and question embedding dimensions')
        parser.add_argument('--memory_size', type=int, default=50, help='memory size')
        parser.add_argument('--n_question', type=int, default=1223, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=6, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='./data/STATICS', help='data directory')
        parser.add_argument('--data_name', type=str, default='STATICS', help='data set name')
        parser.add_argument('--load', type=str, default='STATICS', help='model file to load')
        parser.add_argument('--save', type=str, default='STATICS', help='path to save model')



    params = parser.parse_args()
    params.lr = params.init_lr
    params.memory_key_state_dim = params.q_embed_dim
    params.memory_value_state_dim = params.qa_embed_dim

    print(params)

    dat = DATA(n_question=params.n_question, seqlen=params.seqlen, separate_char=',')
    # train_data_path = params.data_dir + "/" + "test5.1.txt"
    train_data_path = params.data_dir + "/" + params.data_name + "_train1.csv"
    valid_data_path = params.data_dir + "/" + params.data_name + "_valid1.csv"
    test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    train_q_data, train_qa_data = dat.load_data(train_data_path)
    valid_q_data, valid_qa_data = dat.load_data(valid_data_path)
    test_q_data, test_qa_data = dat.load_data(test_data_path)

    params.memory_key_state_dim = params.q_embed_dim
    params.memory_value_state_dim = params.qa_embed_dim

    model = MODEL(n_question=params.n_question,
                  batch_size=params.batch_size,
                  q_embed_dim=params.q_embed_dim,
                  qa_embed_dim=params.qa_embed_dim,
                  memory_size=params.memory_size,
                  memory_key_state_dim=params.memory_key_state_dim,
                  memory_value_state_dim=params.memory_value_state_dim,
                  final_fc_dim=params.final_fc_dim)


    model.init_embeddings()
    model.init_params()
    # optimizer = optim.SGD(params=model.parameters(), lr=params.lr, momentum=params.momentum)
    optimizer = optim.Adam(params=model.parameters(), lr=params.lr, betas=(0.9, 0.9))

    if params.gpu >= 0:
        print('device: ' + str(params.gpu))
        torch.cuda.set_device(params.gpu)
        model.cuda()

    all_train_loss = {}
    all_train_accuracy = {}
    all_train_auc = {}
    all_valid_loss = {}
    all_valid_accuracy = {}
    all_valid_auc = {}
    best_valid_auc = 0

    # shuffle_index = np.random.permutation(train_q_data.shape[0])
    # q_data_shuffled = train_q_data[shuffle_index]
    # qa_data_shuffled = train_qa_data[shuffle_index]

    for idx in range(params.max_iter):
        train_loss, train_accuracy, train_auc = train(idx, model, params, optimizer, train_q_data, train_qa_data)
        print('Epoch %d/%d, loss : %3.5f, auc : %3.5f, accuracy : %3.5f' % (idx + 1, params.max_iter, train_loss, train_auc, train_accuracy))
        valid_loss, valid_accuracy, valid_auc = test(model, params, optimizer, valid_q_data, valid_qa_data)
        print('Epoch %d/%d, valid auc : %3.5f, valid accuracy : %3.5f' % (idx + 1, params.max_iter, valid_auc, valid_accuracy))


        all_train_auc[idx + 1] = train_auc
        all_train_accuracy[idx + 1] = train_accuracy
        all_train_loss[idx + 1] = train_loss
        all_valid_loss[idx + 1] = valid_loss
        all_valid_accuracy[idx + 1] = valid_accuracy
        all_valid_auc[idx + 1] = valid_auc
        #
        # output the epoch with the best validation auc
        if valid_auc > best_valid_auc:
            print('%3.4f to %3.4f' % (best_valid_auc, valid_auc))
            best_valid_auc = valid_auc
Beispiel #6
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--gpu', type=int, default=-1, help='the gpu will be used, e.g "0,1,2,3"')
    parser.add_argument('--max_iter', type=int, default=10, help='number of iterations')
    parser.add_argument('--decay_epoch', type=int, default=20, help='number of iterations')
    parser.add_argument('--test', type=bool, default=False, help='enable testing')
    parser.add_argument('--train_test', type=bool, default=True, help='enable testing')
    parser.add_argument('--show', type=bool, default=True, help='print progress')
    parser.add_argument('--init_std', type=float, default=0.1, help='weight initialization std')
    parser.add_argument('--init_lr', type=float, default=0.01, help='initial learning rate')
    parser.add_argument('--lr_decay', type=float, default=0.75, help='learning rate decay')
    parser.add_argument('--final_lr', type=float, default=1E-5,
                        help='learning rate will not decrease after hitting this threshold')
    parser.add_argument('--momentum', type=float, default=0.9, help='momentum rate')
    parser.add_argument('--max_grad_norm', type=float, default=3.0, help='maximum gradient norm')
    parser.add_argument('--hidden_dim', type=int, default=128, help='hidden layer dimension')
    parser.add_argument('--n_hidden', type=int, default=2, help='hidden numbers')

    dataset = 'oj'

    if dataset == 'oj':
        parser.add_argument('--batch_size', type=int, default=5, help='the batch size')
        parser.add_argument('--qa_embed_dim', type=int, default=50, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=68, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='./data/oj', help='data directory')
        parser.add_argument('--data_name', type=str, default='oj', help='data set name')
        parser.add_argument('--load', type=str, default='oj', help='model file to load')
        parser.add_argument('--save', type=str, default='oj', help='path to save model')

    elif dataset == 'assistments':
        parser.add_argument('--batch_size', type=int, default=32, help='the batch size')
        parser.add_argument('--qa_embed_dim', type=int, default=200, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=124, help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=200, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='./data/assistments', help='data directory')
        parser.add_argument('--data_name', type=str, default='assistments', help='data set name')
        parser.add_argument('--load', type=str, default='assistments', help='model file to load')
        parser.add_argument('--save', type=str, default='assistments', help='path to save model')

    elif dataset == 'STATICS':
        parser.add_argument('--batch_size', type=int, default=10, help='the batch size')
        parser.add_argument('--qa_embed_dim', type=int, default=100, help='answer and question embedding dimensions')
        parser.add_argument('--n_question', type=int, default=1223,
                            help='the number of unique questions in the dataset')
        parser.add_argument('--seqlen', type=int, default=800, help='the allowed maximum length of a sequence')
        parser.add_argument('--data_dir', type=str, default='./data/STATICS', help='data directory')
        parser.add_argument('--data_name', type=str, default='STATICS', help='data set name')
        parser.add_argument('--load', type=str, default='STATICS', help='model file to load')
        parser.add_argument('--save', type=str, default='STATICS', help='path to save model')

    params = parser.parse_args()
    params.lr = params.init_lr

    print(params)

    dat = DATA(n_question=params.n_question, seqlen=params.seqlen, separate_char=',')
    # train_data_path = params.data_dir + "/" + "builder_train.csv"
    # valid_data_path = params.data_dir + "/" + "builder_test.csv"

    train_data_path = params.data_dir + "/" + params.data_name + "_train.csv"
    valid_data_path = params.data_dir + "/" + params.data_name + "_valid.csv"
    # test_data_path = params.data_dir + "/" + params.data_name + "_test.csv"
    train_q_data, train_q_t_data, train_answer_data = dat.load_data(train_data_path)
    valid_q_data, valid_q_t_data, valid_answer_data = dat.load_data(valid_data_path)
    # test_q_data, test_q_t_data, test_answer_data = dat.load_data(test_data_path)

    model = MODEL(n_question=params.n_question,
                  hidden_dim=params.hidden_dim,
                  x_embed_dim=params.qa_embed_dim,
                  hidden_layers=params.n_hidden,
                  gpu=params.gpu)

    model.init_embeddings()
    model.init_params()
    # model = torch.load(params.data_dir + "/save/"+params.save)
    # optimizer = optim.SGD(params=model.parameters(), lr=params.lr, momentum=params.momentum)
    optimizer = optim.Adam(params=model.parameters(), lr=params.lr, betas=(0.9, 0.9))

    if params.gpu >= 0:
        print('device: ' + str(params.gpu))
        torch.cuda.set_device(params.gpu)
        model.cuda()

    all_train_loss = {}
    all_train_accuracy = {}
    all_train_auc = {}
    all_valid_loss = {}
    all_valid_accuracy = {}
    all_valid_auc = {}
    best_valid_auc = 0

    for idx in range(params.max_iter):
        train_loss, train_accuracy, train_auc = train(model, idx, params, optimizer, train_q_data, train_q_t_data,
                                                      train_answer_data)
        print('Epoch %d/%d, loss : %3.5f, auc : %3.5f, accuracy : %3.5f' % (
            idx + 1, params.max_iter, train_loss, train_auc, train_accuracy))
        valid_loss, valid_accuracy, valid_auc = test(model, params, optimizer, valid_q_data, valid_q_t_data,
                                                     valid_answer_data)
        print('Epoch %d/%d, valid auc : %3.5f, valid accuracy : %3.5f' % (
            idx + 1, params.max_iter, valid_auc, valid_accuracy))
        # test_loss, test_accuracy, test_auc = test(model, params, optimizer, test_q_data, test_q_t_data,
        #                                           test_answer_data)
        # print('Epoch %d/%d, test auc : %3.5f, test accuracy : %3.5f' % (
        #     idx + 1, params.max_iter, test_auc, test_accuracy))
        all_train_auc[idx + 1] = train_auc
        all_train_accuracy[idx + 1] = train_accuracy
        all_train_loss[idx + 1] = train_loss
        all_valid_loss[idx + 1] = valid_loss
        all_valid_accuracy[idx + 1] = valid_accuracy
        all_valid_auc[idx + 1] = valid_auc
        #
        # output the epoch with the best validation auc
        if valid_auc > best_valid_auc:
            print('%3.4f to %3.4f' % (best_valid_auc, valid_auc))
            best_valid_auc = valid_auc