Exemplo n.º 1
0
    def train_next(self,
                   train_dataset,
                   test_dataset,
                   batch_size,
                   out_path,
                   params={},
                   **kargs):
        # copy existing materials to new path
        if out_path != self.save_path:
            train.copy(self.save_path, out_path)

        save_model_path = os.path.join(out_path, 'model.ckpt')

        # setting some parameters
        n_epoch = params.get('n_epoch', 10)
        freq_eval = params.get('freq_eval', 20)
        metric = params.get('metric', 'f1')

        #
        # build batches
        #
        train_batch, test_batch = create_batch(train_dataset,
                                               batch_size), create_batch(
                                                   test_dataset, batch_size)

        print('-- start training')
        train_count = 0
        eval_count = 0
        best_test = -np.inf
        decay_lr_every = 500
        lr_decay = 0.9
        init_lr = self.model.lr

        #
        # training
        #
        for epoch in range(n_epoch):
            print("\n[E]poch %i, lr %.4f" % (epoch + 1, init_lr))
            bar = Bar('training', max=len(train_batch), suffix='')
            tabl = PrettyTable([
                'status', 'train_epoch', 'train_batch', 'test_avg_score',
                'test_avg_loss'
            ])

            loss_total, acc_total = [], []

            for i, batch_id in enumerate(
                    np.random.permutation(len(train_batch))):
                train_count += 1
                batch = train_batch[i]

                loss, acc = self.model.batch_run(batch=batch,
                                                 i=train_count,
                                                 mode='train',
                                                 metric=metric)

                loss_total.append(loss)
                acc_total.append(acc)

                bar.bar_prefix = " | batch %i |" % (batch_id + 1)
                bar.bar_suffix = " | cur_loss: %.3f | cur_acc: %.3f | best_test_acc: %.3f" % (
                    loss, acc, best_test)

                bar.next()

                if train_count % decay_lr_every == 0:
                    init_lr = init_lr * lr_decay

                if train_count % freq_eval == 0:
                    test_loss_lst, test_acc_lst = [], []

                    for t_i, t_batch_id in enumerate(range(len(test_batch))):
                        t_batch = test_batch[t_batch_id]
                        eval_count += 1

                        loss, acc = self.model.batch_run(batch=t_batch,
                                                         i=eval_count,
                                                         mode='eval',
                                                         metric=metric,
                                                         lr=init_lr)

                        test_loss_lst.append(loss)
                        test_acc_lst.append(acc)

                    test_loss = np.array(test_loss_lst).mean()
                    test_acc = np.array(test_acc_lst).mean()

                    status = '++++'
                    if test_acc > best_test:
                        best_test = test_acc
                        status = 'best'

                        self.model.save(save_model_path)

                    tabl.add_row([
                        status, epoch + 1, batch_id + 1,
                        '%.3f' % test_acc,
                        '%.3f' % test_loss
                    ])

            print "\nmean_train_loss: %.3f, mean_train_acc: %.3f" % (
                np.mean(loss_total), np.mean(acc_total))
            print(tabl.get_string(title="Local All Test Accuracies"))
Exemplo n.º 2
0
def train(config, params, train_dataset, test_dataset, add_training_log):

    #
    # build batches
    #
    train_batch, test_batch = create_batch(train_dataset,
                                           params['batch_size']), create_batch(
                                               test_dataset,
                                               params['batch_size'])

    #
    # save params
    #
    cPickle.dump(params, open(config['save_params_path'], 'w'))

    #
    # build tensorflow model
    #
    @timeit
    def build_tf_model():
        print('-- build model')
        model = config['model'](**params)
        model.build_model()

        # build custom tensorboard
        print('-- build tensorboard')
        # tensorboard = CustomTensorboard(dir_summary=config['save_summary_path'], model_graph=model.sess.graph,
        #                                 metric=config['metric'])
        tensorboard = None

        return model, tensorboard

    model, tensorboard = build_tf_model()

    #
    # training parameters
    #
    print('-- start training')
    train_count = 0
    eval_count = 0
    best_test = 0.0
    decay_lr_every = 500
    lr_decay = 0.9
    init_lr = model.lr

    #
    # training
    #
    for epoch in range(params['nepochs']):
        print("\n[E]poch %i, lr %.4f" % (epoch + 1, init_lr))
        bar = Bar('training', max=len(train_batch), suffix='')
        tabl = PrettyTable([
            'status', 'train_epoch', 'train_batch', 'test_avg_score',
            'test_avg_loss'
        ])

        loss_total, acc_total = [], []

        for i, batch_id in enumerate(np.random.permutation(len(train_batch))):
            train_count += 1
            batch = train_batch[i]

            loss, acc = model.batch_run(batch=batch,
                                        i=train_count,
                                        mode='train',
                                        metric=config['metric'])

            loss_total.append(loss)
            acc_total.append(acc)

            bar.bar_prefix = " | batch %i |" % (batch_id + 1)
            bar.bar_suffix = " | cur_loss: %.3f | cur_acc: %.3f | best_test_acc: %.3f" % (
                loss, acc, best_test)

            bar.next()

            if train_count % decay_lr_every == 0: init_lr = init_lr * lr_decay

            if train_count % params['freq_eval'] == 0:
                test_loss_lst, test_acc_lst = [], []

                for t_i, t_batch_id in enumerate(range(len(test_batch))):
                    t_batch = test_batch[t_batch_id]
                    eval_count += 1

                    loss, acc = model.batch_run(batch=t_batch,
                                                i=eval_count,
                                                mode='eval',
                                                metric=config['metric'],
                                                lr=init_lr)

                    test_loss_lst.append(loss)
                    test_acc_lst.append(acc)

                test_loss = np.array(test_loss_lst).mean()
                test_acc = np.array(test_acc_lst).mean()

                status = '++++'
                if test_acc > best_test:
                    best_test = test_acc
                    status = 'best'

                    model.save(config['save_model_path'])

                tabl.add_row([
                    status, epoch + 1, batch_id + 1,
                    '%.3f' % test_acc,
                    '%.3f' % test_loss
                ])

        print "\nmean_train_loss: %.3f, mean_train_acc: %.3f" % (
            np.mean(loss_total), np.mean(acc_total))
        print(tabl.get_string(title="Local All Test Accuracies"))

    return best_test, config['saved_path']
Exemplo n.º 3
0
def main(test_cold_user_path, test_warm_path, train_path, u_content_path,
         v_content_path, saved_model, batch_size, n_epoch, learning_rate,
         n_items_per_user, dropout, topk, latent_dim, content_dim,
         lightfm_path, **kargs):

    test_cold_user_matrix = pd.read_csv(test_cold_user_path,
                                        sep=',',
                                        names=['profile', 'item', 'rating'])
    test_warm_matrix = pd.read_csv(test_warm_path,
                                   sep=',',
                                   names=['profile', 'item', 'rating'])
    train_matrix = pd.read_csv(train_path,
                               sep=',',
                               names=['profile', 'item', 'rating'])

    lightfm = cPickle.load(open(lightfm_path, 'r'))

    u_pref_matrix = lightfm.user_embeddings.astype('float32')
    v_pref_matrix = lightfm.item_embeddings.astype('float32')
    u_bias_matrix = lightfm.user_biases.reshape((-1, 1)).astype('float32')
    v_bias_matrix = lightfm.item_biases.reshape((-1, 1)).astype('float32')

    u_content_matrix = np.fromfile(file=u_content_path,
                                   dtype=np.float32).reshape(
                                       n_users, content_dim)
    v_content_matrix = np.fromfile(file=v_content_path,
                                   dtype=np.float32).reshape(
                                       n_items, content_dim)

    # adding zero for dropout purpose
    u_pref_zero_matrix = np.vstack(
        [u_pref_matrix, np.zeros_like(u_pref_matrix[0, :])])
    v_pref_zero_matrix = np.vstack(
        [v_pref_matrix, np.zeros_like(v_pref_matrix[0, :])])
    u_bias_zero_matrix = np.vstack(
        [u_bias_matrix, np.zeros_like(u_bias_matrix[0, :])])
    v_bias_zero_matrix = np.vstack(
        [v_bias_matrix, np.zeros_like(v_bias_matrix[0, :])])

    zero_user_id = u_pref_zero_matrix.shape[0] - 1
    zero_item_id = v_pref_zero_matrix.shape[0] - 1

    # create model for storing necessary materials
    if not os.path.isdir(saved_model): os.makedirs(saved_model)
    save_paths = {
        'model_class': os.path.join(saved_model, 'model.pkl'),
        'model_deep': os.path.join(saved_model, 'model.ckpt')
    }

    # augment training datas
    train_matrix = data_augment(R=train_matrix,
                                n_items_per_user=n_items_per_user,
                                batch_size=batch_size,
                                u_pref=u_pref_matrix,
                                v_pref=v_pref_matrix,
                                u_bias=u_bias_matrix,
                                v_bias=v_bias_matrix)

    # create train and eval batchs
    train_batchs = create_train_batchs(R=train_matrix, batch_size=batch_size)
    test_cold_user_batchs = create_eval_batchs(R=test_cold_user_matrix,
                                               batch_size=batch_size,
                                               is_cold_user=True)
    test_warm_batchs = create_eval_batchs(R=test_warm_matrix,
                                          batch_size=batch_size)

    # model
    model = NN(latent_dim=latent_dim,
               user_feature_dim=content_dim,
               item_feature_dim=content_dim,
               out_dim=200,
               default_lr=learning_rate,
               k=topk,
               do_batch_norm=True)

    cPickle.dump(model, open(save_paths['model_class'], 'w'))
    model.set_np_matrix(np_u_pref_zero=u_pref_zero_matrix,
                        np_v_pref_zero=v_pref_zero_matrix,
                        np_u_cont=u_content_matrix,
                        np_v_cont=v_content_matrix,
                        np_u_bias_zero=u_bias_zero_matrix,
                        np_v_bias_zero=v_bias_zero_matrix)
    model.build()

    # train
    batch_len = len(train_batchs)
    n_step = 0
    freq_eval = 40
    best_cu_score, best_ci_score, best_w_score = -np.inf, -np.inf, -np.inf
    decay_lr_every = 100
    lr_decay = 0.95

    for epoch_i in range(n_epoch):
        print("\n[E]poch %i, lr %.4f, dropout %.2f" %
              (epoch_i + 1, learning_rate, dropout))
        bar = Bar('training', max=batch_len, suffix='')
        tabl = PrettyTable([
            'status', 'train_epoch', 'train_batch', 'cold_user_acc',
            'cold_item_acc', 'warm_acc', 'total'
        ])

        batch_ids = np.random.permutation(batch_len)
        train_loss_total = []

        for batch_i, batch_id in enumerate(batch_ids):
            n_step += 1
            batch = train_batchs[batch_id]

            # dropout or not
            if dropout != 0:
                batch.dropout_user(dropout_prob=dropout, zero_id=zero_user_id)
                #batch.dropout_item(dropout_prob = dropout, zero_id = zero_item_id)

            train_loss, _ = model.run(datas=batch,
                                      mode=model.train_signal,
                                      lr=learning_rate)
            train_loss_total.append(train_loss)

            bar.bar_prefix = " | batch %i |" % (batch_i + 1)
            bar.bar_suffix = " | cur_loss: %.4f | " % train_loss

            bar.next()

            if n_step % decay_lr_every == 0:
                learning_rate = lr_decay * learning_rate

            if n_step % freq_eval == 0:
                cu_acc_mean = score_eval_batch(datas=test_cold_user_batchs,
                                               model=model)
                ci_acc_mean = 1.0  #score_eval_batch_map(datas=test_cold_item_batchs, model=model, topks=topks)
                w_acc_mean = score_eval_batch(datas=test_warm_batchs,
                                              model=model)

                status = '++++'

                if (cu_acc_mean + ci_acc_mean + w_acc_mean) >= (
                        best_cu_score + best_ci_score + best_w_score):
                    best_w_score = w_acc_mean
                    best_ci_score = ci_acc_mean
                    best_cu_score = cu_acc_mean

                    status = 'best'

                    # save model
                    model.save(save_paths['model_deep'])

                tabl.add_row([
                    status, epoch_i + 1, batch_i + 1,
                    "%.3f" % cu_acc_mean,
                    "%.3f" % ci_acc_mean,
                    "%.3f" % w_acc_mean,
                    "%.4f" % (cu_acc_mean + w_acc_mean + ci_acc_mean)
                ])

        print "\nmean_loss: %.3f" % np.mean(train_loss_total)
        print(tabl.get_string(title="Local All Test Accuracies"))