Exemplo n.º 1
0
    def get_session_adj(self, d, alpha):
        print('----------------------------------')
        print('Use sessoin adj cpu sparse tensor, row 1:')
        assert isinstance(alpha, float)
        row = np.array([sidx for sidx in d.keys() for iidx in d[sidx]['items'][::-1]], dtype=np.int32)
        col = np.array([iidx for sidx in d.keys() for iidx in d[sidx]['items'][::-1]], dtype=np.int32)
        data = np.array([np.power(alpha, i) for sidx in d.keys() for i, iidx in enumerate(d[sidx]['items'][::-1])],
                        dtype=np.float32)
        mx = sp.csr_matrix((data, (row, col)), shape=(len(d), self.item_size))
        mx = spmx_1_normalize(mx)
        print('----------------------------------')

        return spmx2torch_sparse_tensor(mx)
Exemplo n.º 2
0
    def get_feature(self, d):
        row = np.array(
            [sidx for sidx in d.keys() for iidx in d[sidx]['items']],
            dtype=np.int32)
        col = np.array(
            [iidx for sidx in d.keys() for iidx in d[sidx]['items']],
            dtype=np.int32)
        data = np.ones_like(row)
        mx = sp.csr_matrix((data, (row, col)), shape=(len(d), self.item_size))
        A = sp.bmat([[None, mx], [mx.transpose(), None]]).tocsr()
        A_hat = A + sp.eye(A.shape[0], dtype=np.float32)
        feature = spmx_1_normalize(A_hat)

        return spmx2torch_sparse_tensor(feature)
Exemplo n.º 3
0
    def get_adj(self, d, tail):
        if tail is not None:
            tail_seq = {k: d[k]['items'][-tail:] for k in d.keys()}
        else:
            tail_seq = {k: d[k]['items'] for k in d.keys()}

        row = np.array(
            [sidx for sidx in tail_seq.keys() for iidx in set(tail_seq[sidx])],
            dtype=np.int32)
        col = np.array(
            [iidx for sidx in tail_seq.keys() for iidx in set(tail_seq[sidx])],
            dtype=np.int32)
        data = np.ones_like(row, dtype=np.float32)
        mx = sp.csr_matrix((data, (row, col)), shape=(len(d), self.item_size))

        adj = sp.bmat([[None, mx], [mx.transpose(), None]]).tocsr()
        adj = spmx_1_normalize(adj)

        return spmx2torch_sparse_tensor(adj)
Exemplo n.º 4
0
def train(dataset, alpha, A_type, normalize_type, session_type,
          pretrained_item_emb, model_type, batch_size, shuffle, item_emb_dim,
          hid_dim1, hid_dim2, hid_dim3, lr_emb, lr_gcn, l2_emb, l2_gcn,
          epochs):
    # init
    if dataset == 'LastFM':
        # use LastFM dataset
        data_obj = LastfmData()
    elif dataset == 'Diginetica':
        # use Diginetica dataset
        data_obj = DigineticaData()
    else:
        # use yoochoose1_64 dataset
        data_obj = YoochooseData(dataset=dataset)

    # gpu device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # init A
    # A: type=scipy.sparse
    A = data_obj.get_decay_adj(
        data_obj.d, tail=None,
        alpha=alpha) if A_type == 'decay' else data_obj.get_gcn_adj(data_obj.d)
    # normalize the adj, type = 'ramdom_walk'(row 1) or type = 'symmetric'
    if normalize_type == 'random_walk':
        print('----------------------------------')
        print('Normalize_type is random_walk:')
        A = spmx_1_normalize(A)
        print('----------------------------------')
    else:
        print('----------------------------------')
        print('Normalize_type is symmetric:')
        A = spmx_sym_normalize(A)
        print('----------------------------------')
    # transform the adj to a sparse cpu tensor
    A = spmx2torch_sparse_tensor(A)

    # get cpu tensor: labels
    labels = data_obj.get_labels(data_obj.d)

    # get cpu tensor: item_idxes
    _, _, item_idxes = data_obj.get_indexes()

    if session_type == 'session_hot_items':
        # get cpu sparse tensor: session adj
        session_adj = data_obj.get_session_adj(data_obj.d, alpha=alpha)
    else:
        # if not use session adj, then session_adj = None
        session_adj = None

    if session_type == 'session_last_item':
        # get cpu LongTensor: session_last_item
        session_last_item = data_obj.get_session_last_item(data_obj.d).long()
    else:
        # if not use session_last_item, then session_last_item = None
        session_last_item = None

    # get pretrained_item_emb
    if pretrained_item_emb == 'True' and alpha != 0.0:
        print('----------------------------------')
        if dataset == 'yoochoose1_64':
            print('Use yoochoose1_64 pretrained item embedding: ' +
                  'pretrained_emb' + str(alpha) + '.pkl')
            pretrained_item_emb = torch.load(
                './yoo1_64_pretrained_item_emb/pretrained_emb' + str(alpha) +
                '.pkl')['item_emb.weight']
        elif dataset == 'yoochoose1_8':
            print('Use yoochoose1_8 pretrained item embedding: ' +
                  'pretrained_emb' + str(alpha) + '.pkl')
            pretrained_item_emb = torch.load(
                './yoo1_8_pretrained_item_emb/pretrained_emb' + str(alpha) +
                '.pkl')['item_emb.weight']
        elif dataset == 'LastFM':
            print('Use LastFM pretrained item embedding: ' + 'pretrained_emb' +
                  str(alpha) + '.pkl')
            pretrained_item_emb = torch.load(
                './lastfm_pretrained_item_emb/pretrained_emb' + str(alpha) +
                '.pkl')['item_emb.weight']
        else:
            print('Use Diginetica pretrained item embedding: ' +
                  'pretrained_emb' + str(alpha) + '.pkl')
            pretrained_item_emb = torch.load(
                './dig_pretrained_item_emb/pretrained_emb' + str(alpha) +
                '.pkl')['item_emb.weight']
        print('----------------------------------')
    else:
        print('----------------------------------')
        print('Not use pretrained item embedding:')
        pretrained_item_emb = None
        print('----------------------------------')

    # get cpu LongTensor: item_emb_idxes
    item_emb_idxes = torch.arange(data_obj.item_size).long()

    # transform all tensor to cuda
    A = A.to(device)
    labels = labels.to(device)
    item_idxes = item_idxes.to(device)
    item_emb_idxes = item_emb_idxes.to(device)
    if session_last_item is not None:
        session_last_item = session_last_item.to(device)
    if session_adj is not None:
        session_adj = session_adj.to(device)

    # define the evalution object
    evalution5 = Evaluation(k=5)
    evalution10 = Evaluation(k=10)
    evalution15 = Evaluation(k=15)
    evalution20 = Evaluation(k=20)

    # define yoochoose data object
    trainset = SessionDataset(train_size=data_obj.train_size,
                              test_size=data_obj.test_size,
                              train=True,
                              labels=labels)
    trainloader = DataLoader(dataset=trainset,
                             batch_size=batch_size,
                             shuffle=shuffle)
    testset = SessionDataset(train_size=data_obj.train_size,
                             test_size=data_obj.test_size,
                             train=False,
                             labels=labels)
    testloader = DataLoader(dataset=testset,
                            batch_size=batch_size,
                            shuffle=False)

    # define model, then transform to cuda
    if model_type == 'ngcf1_session_hot_items':
        # use ngcf1_session_hot_items model:
        model = ngcf1_session_hot_items(
            item_nums=data_obj.item_size,
            item_emb_dim=item_emb_dim,
            hid_dim1=hid_dim1,
            pretrained_item_emb=pretrained_item_emb)
    elif model_type == 'ngcf2_session_hot_items':
        # use ngcf2_session_hot_items model:
        model = ngcf2_session_hot_items(
            item_nums=data_obj.item_size,
            item_emb_dim=item_emb_dim,
            hid_dim1=hid_dim1,
            hid_dim2=hid_dim2,
            pretrained_item_emb=pretrained_item_emb)
    elif model_type == 'ngcf3_session_hot_items':
        # use ngcf3_session_hot_items model:
        model = ngcf3_session_hot_items(
            item_nums=data_obj.item_size,
            item_emb_dim=item_emb_dim,
            hid_dim1=hid_dim1,
            hid_dim2=hid_dim2,
            hid_dim3=hid_dim3,
            pretrained_item_emb=pretrained_item_emb)
    else:
        # use ngcf2_session_last_item model:
        model = ngcf2_session_last_item(
            item_nums=data_obj.item_size,
            item_emb_dim=item_emb_dim,
            hid_dim1=hid_dim1,
            hid_dim2=hid_dim2,
            pretrained_item_emb=pretrained_item_emb)
    model.to(device)

    # define loss and optim
    criterion = nn.CrossEntropyLoss()
    if model_type == 'ngcf1_session_hot_items':
        # use ngcf1_session_hot_items model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)

    elif model_type == 'ngcf2_session_hot_items':
        # use ngcf2_session_hot_items model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }, {
            'params': model.gconv2.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)

    elif model_type == 'ngcf3_session_hot_items':
        # use ngcf3_session_hot_items model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }, {
            'params': model.gconv2.parameters()
        }, {
            'params': model.gconv3.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)

    else:
        # use ngcf2_session_last_item model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }, {
            'params': model.gconv2.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)

    # figure recall mrr norm
    fig_recalls = []
    fig_mrrs = []
    fig_emb_norms = []
    fig_gcn_norms = []
    fig_epochs = []

    # train epochs
    for epoch in range(epochs):
        # model training
        start = time.time()

        # train evalution dict
        recall = {'5': [], '10': [], '15': [], '20': []}
        mrr = {'5': [], '10': [], '15': [], '20': []}

        # test evalution dict
        r = {'5': [], '10': [], '15': [], '20': []}
        m = {'5': [], '10': [], '15': [], '20': []}

        # loss list
        losses = []

        model.train()
        for i, data in enumerate(trainloader):
            # zero optim
            optim_emb.zero_grad()
            optim_gcn.zero_grad()

            # batch inputs
            batch_idxes, batch_labels = data[0].long().to(
                device), data[1].long().to(device)

            # predicting
            if model_type == 'ngcf1_session_hot_items':
                # use ngcf1_session_hot_items model to predict
                outs = model(batch_idxes, A, item_idxes, session_adj,
                             item_emb_idxes)
            elif model_type == 'ngcf2_session_hot_items':
                # use ngcf2_session_hot_items model to predict
                outs = model(batch_idxes, A, item_idxes, session_adj,
                             item_emb_idxes)
            elif model_type == 'ngcf3_session_hot_items':
                # use ngcf3_session_hot_items model to predict
                outs = model(batch_idxes, A, item_idxes, session_adj,
                             item_emb_idxes)
            else:
                # use ngcf2_session_last_item model to predict
                outs = model(batch_idxes, A, item_idxes, session_last_item,
                             item_emb_idxes)

            # loss
            loss = criterion(outs, batch_labels)

            # backward
            loss.backward()

            # optim step
            optim_emb.step()
            optim_gcn.step()

            # evalution, k=5, 10, 15, 20
            recall['5'].append(evalution5.evaluate(outs, batch_labels)[0])
            recall['10'].append(evalution10.evaluate(outs, batch_labels)[0])
            recall['15'].append(evalution15.evaluate(outs, batch_labels)[0])
            recall['20'].append(evalution20.evaluate(outs, batch_labels)[0])
            mrr['5'].append(evalution5.evaluate(outs, batch_labels)[1])
            mrr['10'].append(evalution10.evaluate(outs, batch_labels)[1])
            mrr['15'].append(evalution15.evaluate(outs, batch_labels)[1])
            mrr['20'].append(evalution20.evaluate(outs, batch_labels)[1])

            # losses
            losses.append(loss.item())

            # print loss, recall, mrr
            if i % 50 == 49:
                print('[{0: 2d}, {1:5d}]  loss:{2:.4f}'.format(
                    epoch + 1, i + 1, np.mean(losses)))
                print('[recall@5 ]:{0:.4f}  [mrr@5 ]:{1:.4f}'.format(
                    np.mean(recall['5']), np.mean(mrr['5'])))
                print('[recall@10]:{0:.4f}  [mrr@10]:{1:.4f}'.format(
                    np.mean(recall['10']), np.mean(mrr['10'])))
                print('[recall@15]:{0:.4f}  [mrr@15]:{1:.4f}'.format(
                    np.mean(recall['15']), np.mean(mrr['15'])))
                print('[recall@20]:{0:.4f}  [mrr@20]:{1:.4f}'.format(
                    np.mean(recall['20']), np.mean(mrr['20'])))

        # print gcn_norm, emb_norm
        emb_norm = get_norm(model, 'emb')
        gcn_norm = get_norm(model, 'gcn')
        fig_emb_norms.append(emb_norm)
        fig_gcn_norms.append(gcn_norm)
        print('[gcn_norm]:{0:.4f}  [emb_norm]:{1:.4f}'.format(
            gcn_norm, emb_norm))

        # epoch time
        print('[epoch time]:{0:.4f}'.format(time.time() - start))

        # save model
        if epoch % 10 == 9:
            torch.save(
                model.state_dict(),
                'params' + model_type + '-Alpha' + str(alpha) + '_' +
                '_lr_emb' + str(lr_emb) + '_l2_emb' + str(l2_emb) + '_lr_gcn' +
                str(lr_gcn) + '_l2_gcn' + str(l2_gcn) + '.pkl')

        # model eval
        model.eval()
        with torch.no_grad():
            for j, d in enumerate(testloader):
                # test batch inputs
                b_idxes, b_labels = d[0].long().to(device), d[1].long().to(
                    device)

                # predicting
                if model_type == 'ngcf1_session_hot_items':
                    # use ngcf1_session_hot_items model to predict
                    o = model(b_idxes, A, item_idxes, session_adj,
                              item_emb_idxes)
                elif model_type == 'ngcf2_session_hot_items':
                    # use ngcf2_session_hot_items model to predict
                    o = model(b_idxes, A, item_idxes, session_adj,
                              item_emb_idxes)
                elif model_type == 'ngcf3_session_hot_items':
                    # use ngcf3_session_hot_items model to predict
                    o = model(b_idxes, A, item_idxes, session_adj,
                              item_emb_idxes)
                else:
                    # use ngcf2_session_last_item model to predict
                    o = model(b_idxes, A, item_idxes, session_last_item,
                              item_emb_idxes)

                # evalution, k=5, 10, 15, 20
                r['5'].append(evalution5.evaluate(o, b_labels)[0])
                r['10'].append(evalution10.evaluate(o, b_labels)[0])
                r['15'].append(evalution15.evaluate(o, b_labels)[0])
                r['20'].append(evalution20.evaluate(o, b_labels)[0])
                m['5'].append(evalution5.evaluate(o, b_labels)[1])
                m['10'].append(evalution10.evaluate(o, b_labels)[1])
                m['15'].append(evalution15.evaluate(o, b_labels)[1])
                m['20'].append(evalution20.evaluate(o, b_labels)[1])

            # print test recall mrr
            print('[{0: 2d}]'.format(epoch + 1))
            print('[recall@5 ]:{0:.4f}  [mrr@5 ]:{1:.4f}'.format(
                np.mean(r['5']), np.mean(m['5'])))
            print('[recall@10]:{0:.4f}  [mrr@10]:{1:.4f}'.format(
                np.mean(r['10']), np.mean(m['10'])))
            print('[recall@15]:{0:.4f}  [mrr@15]:{1:.4f}'.format(
                np.mean(r['15']), np.mean(m['15'])))
            print('[recall@20]:{0:.4f}  [mrr@20]:{1:.4f}'.format(
                np.mean(r['20']), np.mean(m['20'])))

            # plt recall and mrr and norm
            fig_epochs.append(epoch)
            fig_recalls.append(np.mean(r['20']))
            fig_mrrs.append(np.mean(m['20']))
            plt_evalution(fig_epochs,
                          fig_recalls,
                          fig_mrrs,
                          k=20,
                          alpha=alpha,
                          lr_emb=lr_emb,
                          l2_emb=l2_emb,
                          lr_gcn=lr_gcn,
                          l2_gcn=l2_gcn,
                          model_type=model_type)
            plt_norm(fig_epochs,
                     fig_emb_norms,
                     fig_gcn_norms,
                     alpha=alpha,
                     lr_emb=lr_emb,
                     l2_emb=l2_emb,
                     lr_gcn=lr_gcn,
                     l2_gcn=l2_gcn,
                     model_type=model_type)
Exemplo n.º 5
0
def train(dataset, alpha, A_type, normalize_type, model_pretrained_params,
          model_type, batch_size, test_batch_size, negative_nums, item_emb_dim,
          hid_dim1, hid_dim2, hid_dim3, lr_emb, l2_emb, lr_gcn, l2_gcn, lr_cnn,
          l2_cnn, epochs, params_file_name):
    # init
    if dataset == 'LastFM':
        # use LastFM dataset
        data_obj = LastfmData()
    elif dataset == 'Diginetica':
        # use Diginetica dataset
        data_obj = DigineticaData()
    else:
        # use yoochoose1_64 dataset
        data_obj = YoochooseData(dataset=dataset)

    # gpu device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # init A
    # A: type=scipy.sparse
    A = data_obj.get_decay_adj(
        data_obj.d, tail=None,
        alpha=alpha) if A_type == 'decay' else data_obj.get_gcn_adj(data_obj.d)
    # normalize the adj, type = 'ramdom_walk'(row 1) or type = 'symmetric'
    if normalize_type == 'random_walk':
        print('----------------------------------')
        print('Normalize_type is random_walk:')
        A = spmx_1_normalize(A)
        print('----------------------------------')
    else:
        print('----------------------------------')
        print('Normalize_type is symmetric:')
        A = spmx_sym_normalize(A)
        print('----------------------------------')
    # transform the adj to a sparse cpu tensor
    A = spmx2torch_sparse_tensor(A)

    # get cpu tensor: labels
    labels = data_obj.get_labels(data_obj.d)

    # get cpu sparse tensor: session adj
    SI = data_obj.get_session_adj(data_obj.d, alpha=alpha)

    # load model pretrained params
    if model_pretrained_params == 'True':
        print('----------------------------------')
        if dataset == 'LastFM':
            # use LastFM params
            print('Use LastFM model pretraned params: ' + params_file_name +
                  '.pkl')
            pretrained_state_dict = torch.load('./lastfm_pretrained_params/' +
                                               params_file_name + '.pkl')
        elif dataset == 'Diginetica':
            # use Diginetica params
            print('Use Diginetica model pretraned params: ' +
                  params_file_name + '.pkl')
            pretrained_state_dict = torch.load('./dig_pretrained_params/' +
                                               params_file_name + '.pkl')
        else:
            # use yoochoose1_64 params
            print('Use yoochoose1_64 model pretraned params: ' +
                  params_file_name + '.pkl')
            pretrained_state_dict = torch.load('./yoo1_64_pretrained_params/' +
                                               params_file_name + '.pkl')
        print('----------------------------------')
    else:
        pretrained_state_dict = None

    # transform all tensor to cuda
    A = A.to(device)
    labels = labels.to(device)
    SI = SI.to(device)

    # define the evalution object
    evalution5 = Evaluation(k=5)
    evalution10 = Evaluation(k=10)
    evalution15 = Evaluation(k=15)
    evalution20 = Evaluation(k=20)

    # define yoochoose data object
    trainloader = SessionDataloader(train_size=data_obj.train_size,
                                    test_size=data_obj.test_size,
                                    item_size=data_obj.item_size,
                                    labels=labels,
                                    batch_size=batch_size,
                                    train=True,
                                    negative_nums=negative_nums,
                                    shuffle=True)
    testloader = SessionDataloader(train_size=data_obj.train_size,
                                   test_size=data_obj.test_size,
                                   item_size=data_obj.item_size,
                                   labels=labels,
                                   batch_size=test_batch_size *
                                   data_obj.item_size,
                                   train=False,
                                   negative_nums=negative_nums,
                                   shuffle=False)

    # define model, then transform to cuda
    if model_type == 'sgncf1_cnn':
        # use sgncf1_cnn model:
        model = sgncf1_cnn(dataset_nums=data_obj.train_size +
                           data_obj.test_size,
                           item_nums=data_obj.item_size,
                           item_emb_dim=item_emb_dim,
                           hid_dim1=hid_dim1)
    else:
        # use sgncf2_cnn model:
        model = sgncf2_cnn(dataset_nums=data_obj.train_size +
                           data_obj.test_size,
                           item_nums=data_obj.item_size,
                           item_emb_dim=item_emb_dim,
                           hid_dim1=hid_dim1,
                           hid_dim2=hid_dim2)
    model.to(device)

    # update model_state_dict
    if pretrained_state_dict is not None:
        model_state_dict = model.state_dict()
        pretrained_state_dict = {
            k: v
            for k, v in pretrained_state_dict.items() if k in model_state_dict
        }
        model_state_dict.update(pretrained_state_dict)
        model.load_state_dict(model_state_dict)

    # define loss and optim
    criterion = nn.BCEWithLogitsLoss()
    if model_type == 'sgncf1_cnn':
        # use sgncf1 model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)
        optim_cnn = optim.Adam([{
            'params': model.cnn_1d.parameters()
        }, {
            'params': model.fc.parameters()
        }],
                               lr=lr_cnn,
                               weight_decay=l2_cnn)
    else:
        # use sgncf2 model parameters:
        optim_emb = optim.Adagrad([{
            'params': model.item_emb.parameters()
        }],
                                  lr=lr_emb,
                                  weight_decay=l2_emb)
        optim_gcn = optim.Adam([{
            'params': model.gconv1.parameters()
        }, {
            'params': model.gconv2.parameters()
        }],
                               lr=lr_gcn,
                               weight_decay=l2_gcn)
        optim_cnn = optim.Adam([{
            'params': model.cnn_1d.parameters()
        }, {
            'params': model.fc.parameters()
        }],
                               lr=lr_cnn,
                               weight_decay=l2_cnn)

    # figure recall mrr norm
    fig_recalls = []
    fig_mrrs = []
    fig_emb_norms = []
    fig_gcn_norms = []
    fig_cnn_norms = []
    fig_epochs = []

    # train epochs
    for epoch in range(epochs):
        # model training
        start = time.time()

        # test evalution dict
        r = {'5': [], '10': [], '15': [], '20': []}
        m = {'5': [], '10': [], '15': [], '20': []}

        # loss list
        losses = []

        model.train()
        for i, data in enumerate(trainloader):
            # zero optim
            optim_emb.zero_grad()
            optim_gcn.zero_grad()
            optim_cnn.zero_grad()

            # batch inputs
            batch_sidxes, batch_iidxes, batch_labels = data[:, 0].long().to(
                device), data[:,
                              1].long().to(device), data[:,
                                                         2].float().to(device)

            # predicting
            outs = model(batch_sidxes, batch_iidxes, A, SI)

            # loss
            loss = criterion(outs, batch_labels)

            # backward
            loss.backward()

            # optim step
            optim_emb.step()
            optim_gcn.step()
            optim_cnn.step()

            # losses
            losses.append(loss.item())

            # print loss, recall, mrr
            if i % 20 == 19:
                print('[{0: 2d}, {1:5d}, {2: 7d}], loss:{3:.4f}'.format(
                    epoch + 1, int(i * (batch_size / (negative_nums + 1))),
                    data_obj.train_size, np.mean(losses)))

        # print gcn_norm, emb_norm
        emb_norm = get_norm(model, 'emb')
        gcn_norm = get_norm(model, 'gcn')
        cnn_norm = get_norm(model, 'cnn')
        fig_emb_norms.append(emb_norm)
        fig_gcn_norms.append(gcn_norm)
        fig_cnn_norms.append(gcn_norm)
        print('[gcn_norm]:{0:.4f}  [emb_norm]:{1:.4f}  [cnn_norm]:{2:.4f}'.
              format(gcn_norm, emb_norm, cnn_norm))

        # epoch time
        print('[epoch time]:{0:.4f}'.format(time.time() - start))

        # model eval
        model.eval()
        with torch.no_grad():
            for j, d in enumerate(testloader):
                # test batch inputs
                b_sidxes, b_iidxes, b_labels = d[0][:, 0].long().to(
                    device), d[0][:, 1].long().to(device), d[1].to(device)

                # predicting
                o = model(b_sidxes, b_iidxes, A, SI)
                o = o.view(-1, data_obj.item_size)

                # evalution, k=5, 10, 15, 20
                r['5'].append(evalution5.evaluate(o, b_labels)[0])
                r['10'].append(evalution10.evaluate(o, b_labels)[0])
                r['15'].append(evalution15.evaluate(o, b_labels)[0])
                r['20'].append(evalution20.evaluate(o, b_labels)[0])
                m['5'].append(evalution5.evaluate(o, b_labels)[1])
                m['10'].append(evalution10.evaluate(o, b_labels)[1])
                m['15'].append(evalution15.evaluate(o, b_labels)[1])
                m['20'].append(evalution20.evaluate(o, b_labels)[1])

                # print test inf
                # print('[{0: 2d}, {1: 5d}, {2: 7d}]'.format(epoch+1,
                #                                            j * test_batch_size,
                #                                            data_obj.test_size))

            # print test recall mrr
            print('[{0: 2d}]'.format(epoch + 1))
            print('[recall@5 ]:{0:.4f}  [mrr@5 ]:{1:.4f}'.format(
                np.sum(r['5']) / data_obj.test_size,
                np.sum(m['5']) / data_obj.test_size))
            print('[recall@10]:{0:.4f}  [mrr@10]:{1:.4f}'.format(
                np.sum(r['10']) / data_obj.test_size,
                np.sum(m['10']) / data_obj.test_size))
            print('[recall@15]:{0:.4f}  [mrr@15]:{1:.4f}'.format(
                np.sum(r['15']) / data_obj.test_size,
                np.sum(m['15']) / data_obj.test_size))
            print('[recall@20]:{0:.4f}  [mrr@20]:{1:.4f}'.format(
                np.sum(r['20']) / data_obj.test_size,
                np.sum(m['20']) / data_obj.test_size))

            # plt recall and mrr and norm
            fig_epochs.append(epoch)
            fig_recalls.append(np.sum(r['20']) / data_obj.test_size)
            fig_mrrs.append(np.sum(m['20']) / data_obj.test_size)
            plt_evalution(fig_epochs,
                          fig_recalls,
                          fig_mrrs,
                          k=20,
                          alpha=alpha,
                          lr_emb=lr_emb,
                          l2_emb=l2_emb,
                          lr_gcn=lr_gcn,
                          l2_gcn=l2_gcn,
                          model_type=model_type,
                          lr_cnn=lr_cnn,
                          l2_cnn=l2_cnn)
            plt_norm(fig_epochs,
                     fig_emb_norms,
                     fig_gcn_norms,
                     fig_cnn_norms,
                     alpha=alpha,
                     lr_emb=lr_emb,
                     l2_emb=l2_emb,
                     lr_gcn=lr_gcn,
                     l2_gcn=l2_gcn,
                     model_type=model_type,
                     lr_cnn=lr_cnn,
                     l2_cnn=l2_cnn)
Exemplo n.º 6
0
def check(dataset, A_type, normalize_type, model_type, F_normalize, batch_size,
          shuffle, alpha, pretrained_item_emb, item_emb_dim, hid_dim1,
          hid_dim2, hid_dim3, lr_emb, lr_gcn, l2_emb, l2_gcn, epoch):
    # init
    yooch = YoochooseData(dataset=dataset)
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # init A
    # A: type=scipy.sparse
    A = yooch.get_decay_adj(
        yooch.d, tail=None,
        alpha=alpha) if A_type == 'decay' else yooch.get_gcn_adj(yooch.d)
    # normalize the adj, type = 'ramdom_walk'(row 1) or type = 'symmetric'
    A = spmx_1_normalize(
        A) if normalize_type == 'ramdom_walk' else spmx_sym_normalize(A)
    # transform the adj to a sparse cpu tensor
    A = spmx2torch_sparse_tensor(A)

    # get cpu tensor: lables
    lables = yooch.get_lables(yooch.d)

    # get cpu sparse tensor: session_adj
    session_adj = yooch.get_session_adj(yooch.d, alpha=alpha)

    # get cpu tensor: item_idxes
    _, _, item_idxes = yooch.get_indexes()

    # if session_emb use the local then use the code below
    session_local_idxes = yooch.get_local(yooch.d)

    # get pretrained_item_emb
    pretrained_item_emb = torch.load(
        'pretrained_emb' + str(int(alpha * 10)) +
        '.pkl')['item_emb.weight'] if pretrained_item_emb == 'True' else None

    # transform all tensor to cuda
    A = A.to(device)
    lables = lables.to(device)
    session_adj = session_adj.to(device)
    item_idxes = item_idxes.to(device)

    # if session_emb use the local then use the code below
    session_local_idxes = session_local_idxes.to(device)

    # define the evalution object
    evalution5 = Evaluation(k=5)
    evalution10 = Evaluation(k=10)
    evalution15 = Evaluation(k=15)
    evalution20 = Evaluation(k=20)
    max_epoch = {'5': -1, '10': -1, '15': -1, '20': -1}
    max_recall = {'5': -1, '10': -1, '15': -1, '20': -1}
    max_mrr = {'5': -1, '10': -1, '15': -1, '20': -1}

    # define yoochoose data object
    trainset = YoochooseDataset(train_size=yooch.train_size,
                                test_size=yooch.test_size,
                                train=True,
                                lables=lables)
    trainloader = DataLoader(dataset=trainset,
                             batch_size=batch_size,
                             shuffle=shuffle)
    testset = YoochooseDataset(train_size=yooch.train_size,
                               test_size=yooch.test_size,
                               train=False,
                               lables=lables)
    testloader = DataLoader(dataset=testset,
                            batch_size=batch_size,
                            shuffle=False)

    model = ngcf2(item_nums=yooch.item_size,
                  item_emb_dim=item_emb_dim,
                  hid_dim1=hid_dim1,
                  hid_dim2=hid_dim2,
                  pretrained_item_emb=pretrained_item_emb,
                  F_normalize=F_normalize)
    model.to(device)
    model.load_state_dict(torch.load('/home/wuwu/下载/ngcf2alpha0.3params.pkl'))

    model.eval()
    outs = model(yooch.train_size + 1, A, session_adj, item_idxes)

    a = 1
Exemplo n.º 7
0
def model_test(dataset, alpha, A_type, normalize_type, model_type,
               negative_nums, item_emb_dim, hid_dim1, hid_dim2,
               model_pretrained_params, params_file_name):
    # init
    if dataset == 'LastFM':
        # use LastFM dataset
        data_obj = LastfmData()
    elif dataset == 'Diginetica':
        # use Diginetica dataset
        data_obj = DigineticaData()
    else:
        # use yoochoose1_64 dataset
        data_obj = YoochooseData(dataset=dataset)

    # gpu device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # init A
    # A: type=scipy.sparse
    A = data_obj.get_decay_adj(
        data_obj.d, tail=None,
        alpha=alpha) if A_type == 'decay' else data_obj.get_gcn_adj(data_obj.d)
    # normalize the adj, type = 'ramdom_walk'(row 1) or type = 'symmetric'
    if normalize_type == 'random_walk':
        print('----------------------------------')
        print('Normalize_type is random_walk:')
        A = spmx_1_normalize(A)
        print('----------------------------------')
    else:
        print('----------------------------------')
        print('Normalize_type is symmetric:')
        A = spmx_sym_normalize(A)
        print('----------------------------------')
    # transform the adj to a sparse cpu tensor
    A = spmx2torch_sparse_tensor(A)

    # get cpu tensor: labels
    labels = data_obj.get_labels(data_obj.d)

    # get cpu sparse tensor: session adj
    SI = data_obj.get_session_adj(data_obj.d, alpha=alpha)

    # load model pretrained params
    if model_pretrained_params == 'True':
        print('----------------------------------')
        if dataset == 'LastFM':
            # use LastFM params
            print('Use LastFM model pretraned params: ' + params_file_name +
                  '.pkl')
            pretrained_state_dict = torch.load('./lastfm_pretrained_params/' +
                                               params_file_name + '.pkl')
        elif dataset == 'Diginetica':
            # use Diginetica params
            print('Use Diginetica model pretraned params: ' +
                  params_file_name + '.pkl')
            pretrained_state_dict = torch.load('./dig_pretrained_params/' +
                                               params_file_name + '.pkl')
        else:
            # use yoochoose1_64 params
            print('Use yoochoose1_64 model pretraned params: ' +
                  params_file_name + '.pkl')
            pretrained_state_dict = torch.load('./yoo1_64_pretrained_params/' +
                                               params_file_name + '.pkl')
        print('----------------------------------')
    else:
        pretrained_state_dict = None

    # transform all tensor to cuda
    A = A.to(device)
    labels = labels.to(device)
    SI = SI.to(device)

    # define the evalution object
    evalution5 = Evaluation(k=5)
    evalution10 = Evaluation(k=10)
    evalution15 = Evaluation(k=15)
    evalution20 = Evaluation(k=20)

    # define yoochoose data object
    testloader = SessionDataloader(train_size=data_obj.train_size,
                                   test_size=data_obj.test_size,
                                   item_size=data_obj.item_size,
                                   labels=labels,
                                   batch_size=50 * data_obj.item_size,
                                   train=False,
                                   negative_nums=negative_nums,
                                   shuffle=False)

    # define model, then transform to cuda
    if model_type == 'sgncf1':
        # use sgncf1_cnn model:
        model = sgncf1(dataset_nums=data_obj.train_size + data_obj.test_size,
                       item_nums=data_obj.item_size,
                       item_emb_dim=item_emb_dim,
                       hid_dim1=hid_dim1,
                       pretrained_item_emb=None)
    else:
        # use sgncf2_cnn model:
        model = sgncf2(dataset_nums=data_obj.train_size + data_obj.test_size,
                       item_nums=data_obj.item_size,
                       item_emb_dim=item_emb_dim,
                       hid_dim1=hid_dim1,
                       hid_dim2=hid_dim2,
                       pretrained_item_emb=None)
    model.to(device)

    # update model_state_dict
    if pretrained_state_dict is not None:
        model_state_dict = model.state_dict()
        pretrained_state_dict = {
            k: v
            for k, v in pretrained_state_dict.items() if k in model_state_dict
        }
        model_state_dict.update(pretrained_state_dict)
        model.load_state_dict(model_state_dict)

    # test evalution dict
    r = {'5': [], '10': [], '15': [], '20': []}
    m = {'5': [], '10': [], '15': [], '20': []}

    # model eval
    model.eval()
    with torch.no_grad():
        for j, d in enumerate(testloader):
            # test batch inputs
            b_sidxes, b_iidxes, b_labels = d[0][:, 0].long().to(
                device), d[0][:, 1].long().to(device), d[1].to(device)

            # predicting
            o = model(b_sidxes, b_iidxes, A, SI)
            o = o.view(-1, data_obj.item_size)

            # evalution, k=5, 10, 15, 20
            r['5'].append(evalution5.evaluate(o, b_labels)[0])
            r['10'].append(evalution10.evaluate(o, b_labels)[0])
            r['15'].append(evalution15.evaluate(o, b_labels)[0])
            r['20'].append(evalution20.evaluate(o, b_labels)[0])
            m['5'].append(evalution5.evaluate(o, b_labels)[1])
            m['10'].append(evalution10.evaluate(o, b_labels)[1])
            m['15'].append(evalution15.evaluate(o, b_labels)[1])
            m['20'].append(evalution20.evaluate(o, b_labels)[1])
            print('[{0: 2d}, {1: 4d}]'.format(j * 50, data_obj.test_size))

        # print test recall mrr
        print('[recall@5 ]:{0:.4f}  [mrr@5 ]:{1:.4f}'.format(
            np.sum(r['5']) / data_obj.test_size,
            np.sum(m['5']) / data_obj.test_size))
        print('[recall@10]:{0:.4f}  [mrr@10]:{1:.4f}'.format(
            np.sum(r['10']) / data_obj.test_size,
            np.sum(m['10']) / data_obj.test_size))
        print('[recall@15]:{0:.4f}  [mrr@15]:{1:.4f}'.format(
            np.sum(r['15']) / data_obj.test_size,
            np.sum(m['15']) / data_obj.test_size))
        print('[recall@20]:{0:.4f}  [mrr@20]:{1:.4f}'.format(
            np.sum(r['20']) / data_obj.test_size,
            np.sum(m['20']) / data_obj.test_size))